diff options
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-ieee1588.patch')
-rw-r--r-- | meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-ieee1588.patch | 7945 |
1 files changed, 7945 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-ieee1588.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-ieee1588.patch new file mode 100644 index 0000000000..ac1bea9050 --- /dev/null +++ b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-ieee1588.patch @@ -0,0 +1,7945 @@ + + +From: Masayuki Ohtake <masa-korg@dsn.okisemi.com> +Subject: OKI Semiconductor PCH IEEE1588 driver + +This driver implements IEEE1588 controls for PCH. + +Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com> +Acked-by: Wang Qi <qi.wang@intel.com> + +--- + drivers/char/Kconfig | 7 ++ + drivers/char/Makefile | 2 + drivers/char/pch_ieee1588/Makefile | 10 + drivers/char/pch_ieee1588/pch_1588_hal.c | 4040 + drivers/char/pch_ieee1588/pch_1588_hal.h | 885 + drivers/char/pch_ieee1588/pch_1588_main.c | 1192 + drivers/char/pch_ieee1588/pch_1588_main.h | 702 + drivers/char/pch_ieee1588/pch_1588_pci.c | 700 + drivers/char/pch_ieee1588/pch_1588_pci.h | 122 + drivers/char/pch_ieee1588/pch_common.h | 146 + drivers/char/pch_ieee1588/pch_debug.h | 60 ++++++++++++++++++++++++++++++++ 11 files changed, zz insertions(+) +diff -urN linux-2.6.33-rc3/drivers/char/Kconfig topcliff-2.6.33-rc3/drivers/char/Kconfig +--- linux-2.6.33-rc3/drivers/char/Kconfig 2010-01-06 09:02:46.000000000 +0900 ++++ topcliff-2.6.33-rc3/drivers/char/Kconfig 2010-03-09 10:14:52.000000000 +0900 +@@ -4,6 +4,13 @@ + + menu "Character devices" + ++config PCH_IEEE1588 ++ tristate "PCH IEEE1588" ++ depends on PCI ++ help ++ If you say yes to this option, support will be included for the ++ PCH IEEE1588 Host controller. ++ + config VT + bool "Virtual terminal" if EMBEDDED + depends on !S390 +diff -urN linux-2.6.33-rc3/drivers/char/Makefile topcliff-2.6.33-rc3/drivers/char/Makefile +--- linux-2.6.33-rc3/drivers/char/Makefile 2010-01-06 09:02:46.000000000 +0900 ++++ topcliff-2.6.33-rc3/drivers/char/Makefile 2010-03-05 22:57:39.000000000 +0900 +@@ -111,6 +111,8 @@ + obj-$(CONFIG_JS_RTC) += js-rtc.o + js-rtc-y = rtc.o + ++obj-$(CONFIG_PCH_IEEE1588) += pch_ieee1588/ ++ + # Files generated that shall be removed upon make clean + clean-files := consolemap_deftbl.c defkeymap.c + +diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/Makefile topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/Makefile +--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/Makefile 1970-01-01 09:00:00.000000000 +0900 ++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/Makefile 2010-03-10 04:52:54.000000000 +0900 +@@ -0,0 +1,10 @@ ++ifeq ($(CONFIG_IEEE1588_DEBUG_CORE),y) ++EXTRA_CFLAGS += -DDEBUG ++endif ++ ++obj-$(CONFIG_PCH_IEEE1588) += pch_ieee1588.o ++ ++#for A0_A1_SAMPLE LSI board ++EXTRA_CFLAGS+=-DIOH_IEEE1588_A0_A1_SAMPLE_BUG ++ ++pch_ieee1588-objs := pch_1588_main.o pch_1588_pci.o pch_1588_hal.o +diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.c topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.c +--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.c 1970-01-01 09:00:00.000000000 +0900 ++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.c 2010-03-09 10:34:22.000000000 +0900 +@@ -0,0 +1,4040 @@ ++ /*! ++ * @file ioh_1588_hal.c ++ * @brief ++ * This file has the definitions for HALLAyer APIs. ++ * @version 0.92 ++ * @section ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * History: ++ * modified to support Intel IOH GE IEEE 1588 hardware ++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. ++ * All rights reserved. ++ * derived from ++ * IEEE 1588 Time Synchronization Driver for Intel EP80579 ++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ */ ++ ++#include <linux/io.h> ++#include "pch_common.h" ++#include "pch_debug.h" ++#include <linux/module.h> ++#include "pch_1588_hal.h" ++ ++/* ++ * HAL API definitions for the IEEE 1588 module ++ */ ++ ++/*! @ingroup IEEE1588 ++ * @def INLINE ++ * @brief The macro used instead of the keyword __inline. ++*/ ++#define INLINE inline ++ ++/*Register read/write macros*/ ++#define IOH_REG_32_READ(regAddr, varRef) (*(varRef) = IOH_READ32(regAddr)) ++#define IOH_REG_32_WRITE(regAddr, varValue) IOH_WRITE32(varValue, regAddr) ++#define IOH_BIT_SET_CHECK(regAddr, bitMask) \ ++ ((IOH_READ32(regAddr) & (bitMask)) == (bitMask)) ++ ++#ifdef IOH_IEEE1588_A1_SAMPLE_BUG ++/*global variable to store tick rate*/ ++static unsigned long gTickRateApp; ++#endif ++ ++/* function prototypes */ ++/* TS_Control register access routines */ ++static INLINE void ioh_1588_pps_imask_set(void); ++static INLINE void ioh_1588_amms_imask_set(void); ++static INLINE void ioh_1588_asms_imask_set(void); ++static INLINE void ioh_1588_ttm_imask_set(void); ++static INLINE void ioh_1588_pps_imask_clear(void); ++static INLINE void ioh_1588_amms_imask_clear(void); ++static INLINE void ioh_1588_asms_imask_clear(void); ++static INLINE void ioh_1588_ttm_imask_clear(void); ++static INLINE unsigned long ioh_1588_pps_imask_get(void); ++static INLINE unsigned long ioh_1588_amms_imask_get(void); ++static INLINE unsigned long ioh_1588_asms_imask_get(void); ++static INLINE unsigned long ioh_1588_ttm_imask_get(void); ++static INLINE void ioh_1588_block_reset(void); ++ ++/* TS_Event register access routines */ ++static INLINE unsigned long ioh_1588_pps_evt_get(void); ++static INLINE unsigned long ioh_1588_amms_evt_get(void); ++static INLINE unsigned long ioh_1588_asms_evt_get(void); ++static INLINE unsigned long ioh_1588_ttm_evt_get(void); ++static INLINE void ioh_1588_pps_evt_clear(void); ++static INLINE void ioh_1588_amms_evt_clear(void); ++static INLINE void ioh_1588_asms_evt_clear(void); ++static INLINE void ioh_1588_ttm_evt_clear(void); ++ ++/* TS_Addend register access routines - Frequency Scaling Value */ ++static INLINE void ioh_1588_addend_set(unsigned long fsv); ++static INLINE void ioh_1588_addend_get(unsigned long *fsv); ++ ++/* TS_PPS_Compare register access routines */ ++static INLINE void ioh_1588_pps_set(unsigned long fsv); ++static INLINE void ioh_1588_pps_get(unsigned long *fsv); ++/* TS_SYSTimeLo, Hi registers access routines */ ++static INLINE void ioh_1588_sys_snap_set(unsigned long sys_time_low, ++ unsigned long sys_time_high); ++static INLINE void ioh_1588_sys_snap_get(unsigned long *sys_time_low, ++ unsigned long *sys_time_high); ++/* TS_TrgtTimeLo, Hi registers access routines */ ++static INLINE void ioh_1588_tgt_snap_set(unsigned long tgt_time_low, ++ unsigned long tgt_time_high); ++static INLINE void ioh_1588_tgt_snap_get(unsigned long *tgt_time_low, ++ unsigned long *tgt_time_high); ++/* TS_ASMSLo, Hi registers access routines */ ++static INLINE void ioh_1588_aux_slave_snap_get(unsigned long *asms_low, ++ unsigned long *asms_high); ++/* TS_AMMSLo, Hi registers access routines */ ++static INLINE void ioh_1588_aux_master_snap_get(unsigned long *amms_low, ++ unsigned long *amms_high); ++ ++/* TS_Ch_Control register access routines */ ++static INLINE void ioh_1588_master_mode_set(unsigned long master_mode); ++static INLINE unsigned long ioh_1588_master_mode_get(void); ++static INLINE void ioh_1588_timestamp_all_set(unsigned long allMsg); ++static INLINE unsigned long ioh_1588_timestamp_all_get(void); ++static INLINE void ioh_1588_op_mode_set(unsigned long mode); ++static INLINE unsigned long ioh_1588_op_mode_get(void); ++static INLINE void ioh_1588_version_set(unsigned long versionVal); ++static INLINE unsigned long ioh_1588_version_get(void); ++ ++/* TS_Ch_Event register access routines */ ++static INLINE unsigned long ioh_1588_rx_snap_evt(void); ++static INLINE unsigned long ioh_1588_tx_snap_evt(void); ++static INLINE void ioh_1588_rx_snap_evt_clear(void); ++static INLINE void ioh_1588_tx_snap_evt_clear(void); ++/* TS_TxSnapLo, Hi registers access routines */ ++static INLINE void ioh_1588_tx_snap_get(unsigned long *txs_low, ++ unsigned long *txs_high); ++/* TS_RxSnapLo, Hi registers access routines */ ++static INLINE void ioh_1588_rx_snap_get(unsigned long *rxs_low, ++ unsigned long *rxs_high); ++/* TS_srcUUIDLo, Hi registers access routines */ ++static INLINE void ioh_1588_uuid_seqid_get(unsigned long *uuid_low, ++ unsigned long *uuid_high, ++ unsigned int *seq_id); ++ ++static INLINE unsigned long ioh_1588_can_snap_valid(void); ++static INLINE unsigned long ioh_1588_can_snap_ovr(void); ++static INLINE void ioh_1588_can_snap_valid_clear(void); ++static INLINE void ioh_1588_can_snap_ovr_clear(void); ++static INLINE void ioh_1588_can_snap_get(unsigned long *rxs_low, ++ unsigned long *rxs_high); ++ ++static INLINE void ioh_1588_eth_enable_set(void); ++static INLINE void ioh_1588_eth_enable_clear(void); ++static INLINE unsigned long ioh_1588_eth_enable_get(void); ++static INLINE void ioh_1588_can_enable_set(void); ++static INLINE void ioh_1588_can_enable_clear(void); ++static INLINE unsigned long ioh_1588_can_enable_get(void); ++static INLINE void ioh_1588_station_set(unsigned long station, ++ unsigned long value); ++static INLINE void ioh_1588_station_get(unsigned long station, ++ unsigned long *value); ++ ++/* Masks to extract High and Low SHORTs from unsigned long values */ ++#define IOH_1588_MSB_SHORT_MASK (0xFFFF0000) ++#define IOH_1588_LSB_SHORT_MASK (0x0000FFFF) ++ ++/* Location of SeqID in the register */ ++#define IOH_1588_SID_LOC (16) ++ ++/* Variable declarations */ ++ ++/** ++ * Client registered callback routines for ++ * a) the target time reached or exceeded interrupt notification ++ * b) the auxiliary time stamps availability interrupt notification ++ * c) the pulse per second match interrupt notification ++ */ ++static ioh1588TargetTimeCallback ioh_tt_cbptr = ++ (ioh1588TargetTimeCallback) NULL; ++static ioh1588AuxTimeCallback ioh_am_cbptr = (ioh1588AuxTimeCallback) NULL; ++static ioh1588AuxTimeCallback ioh_as_cbptr = (ioh1588AuxTimeCallback) NULL; ++static ioh1588PulsePerSecondCallback ioh_pps_cbptr = ++ (ioh1588PulsePerSecondCallback) NULL; ++ ++/* The transmit and receive timestamp statistics */ ++static struct ioh1588Stats ioh_1588_stats = { 0, 0 }; ++ ++/* To save the state of all registers of the module */ ++static struct ioh_1588_regs_set ioh_1588_regs; ++ ++/* IO mapped virtual address for the 1588 registers */ ++static unsigned long ioh_1588_base; ++ ++/* local functions definitions. */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_pps_imask_set(void) ++ * @brief Enable PPS Interrupt ++ * @param None ++ * @retval None ++*/ ++ ++static INLINE void ioh_1588_pps_imask_set(void) ++{ ++ /* SET the ppsm bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_PPSM_MASK); ++} ++ ++/** @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_amms_imask_set(void) ++ * @brief Enable Auxiliary Master Mode Snapshot Interrupt ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_amms_imask_set(void) ++{ ++ /* SET the amms bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_AMMS_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_asms_imask_set(void) ++ * @brief Enable Auxiliary Slave Mode Snapshot Interrupt ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_asms_imask_set(void) ++{ ++ /* SET the asms bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_ASMS_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_ttm_imask_set(void) ++ * @brief Enable Target Time Interrupt ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_ttm_imask_set(void) ++{ ++ /* SET the ttm bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_TTM_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_pps_imask_get(void) ++ * @brief Get PPS Interrupt Mask value ++ * @param None ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_pps_imask_get(void) ++{ ++ /* Is the ppsm bit SET? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_PPSM_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_amms_imask_get(void) ++ * @brief Get Auxiliary Master Mode Snapshot Interrupt Mask value ++ * @param None ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_amms_imask_get(void) ++{ ++ /* Is the amms bit SET? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_AMMS_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ @fn static INLINE unsigned long ioh_1588_asms_imask_get(void) ++ @brief Get Auxiliary Slave Mode Snapshot Interrupt Mask value ++ @param None ++ @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_asms_imask_get(void) ++{ ++ /* Is the asms bit SET? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_ASMS_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_ttm_imask_get(void) ++ * @brief Get Target Time Interrupt Mask value ++ * @param None. ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_ttm_imask_get(void) ++{ ++ /* Is the ttm bit SET? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_TTM_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ @fn static INLINE void ioh_1588_pps_imask_clear(void) ++ @brief Disable PPS Interrupt ++ @param None ++ @retval None ++*/ ++static INLINE void ioh_1588_pps_imask_clear(void) ++{ ++ /* CLEAR the ppsm bit */ ++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_PPSM_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_amms_imask_clear(void) ++ * @brief Disable Auxiliary Master Mode Snapshot Interrupt. ++ * @param None. ++ * @retval None ++*/ ++static INLINE void ioh_1588_amms_imask_clear(void) ++{ ++ /* CLEAR the amms bit */ ++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_AMMS_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_asms_imask_clear(void) ++ * @brief Disable Auxiliary Slave Mode Snapshot Interrupt ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_asms_imask_clear(void) ++{ ++ /* CLEAR the asms bit */ ++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_ASMS_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_ttm_imask_clear(void) ++ * @brief Disable Target Time Interrupt ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_ttm_imask_clear(void) ++{ ++ /* CLEAR the ttm bit */ ++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_TTM_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_block_reset(void) ++ * @brief Reset Hardware Assist block ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_block_reset(void) ++{ ++ /* SET the rst bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_RESET); ++ /* CLEAR the rst bit */ ++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_TSC_OFFSET, ++ IOH_1588_TSC_RESET); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_pps_evt_get(void) ++ * @brief Poll for PPS event ++ * @param None ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_pps_evt_get(void) ++{ ++ /* Check for PPS event */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSE_OFFSET, ++ IOH_1588_TSE_PPS); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_amms_evt_get(void) ++ * @brief Poll for Auxiliary Master Mode Snapshot Captured event ++ * @param None ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_amms_evt_get(void) ++{ ++ /* Check for AMMS event */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSE_OFFSET, ++ IOH_1588_TSE_SNM); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_asms_evt_get(void) ++ * @brief Poll for Auxiliary Slave Mode Snapshot Captured event ++ * @param None ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_asms_evt_get(void) ++{ ++ /* Check ASMS event */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSE_OFFSET, ++ IOH_1588_TSE_SNS); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_ttm_evt_get(void) ++ * @brief Poll for Target Time Reached event ++ * @param None ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_ttm_evt_get(void) ++{ ++ /* Check target time pending event */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_TSE_OFFSET, ++ IOH_1588_TSE_TTIPEND); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_pps_evt_clear(void) ++ * @brief Clear PPS event ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_pps_evt_clear(void) ++{ ++ /* clear the pps bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSE_OFFSET, IOH_1588_TSE_PPS); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_amms_evt_clear(void) ++ * @brief Clear Auxiliary Master Mode Snapshot Captured event ++ * @param None. ++ * @retval None. ++*/ ++static INLINE void ioh_1588_amms_evt_clear(void) ++{ ++ /* clear the snm bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSE_OFFSET, IOH_1588_TSE_SNM); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_asms_evt_clear(void) ++ * @brief Clear Auxiliary Slave Mode Snapshot Captured event ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_asms_evt_clear(void) ++{ ++ /* clear the sns bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSE_OFFSET, IOH_1588_TSE_SNS); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_ttm_evt_clear(void) ++ * @brief Clear Target Time Reached event ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_ttm_evt_clear(void) ++{ ++ /* CLEAR the ttipend bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_TSE_OFFSET, ++ IOH_1588_TSE_TTIPEND); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_sys_snap_set( ++ * unsigned long sys_time_low, unsigned long sys_time_high) ++ * @brief Set System Time value ++ * @param sys_time_low [IN] The system time low. ++ * @param sys_time_high {In} The system time high. ++ * @retval None ++*/ ++static INLINE void ++ioh_1588_sys_snap_set(unsigned long sys_time_low, unsigned long sys_time_high) ++{ ++ /* Update the System Time Low Register contents */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_STL_OFFSET, sys_time_low); ++ ++ /* Update the System Time High Register contents */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_STH_OFFSET, sys_time_high); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE voidioh_1588_sys_snap_get( ++ * unsigned long *sys_time_low, unsigned long *sys_time_high) ++ * @brief Get System Time Low value ++ * @param sys_time_low [OUT] The system time low. ++ * @param sys_time_high [OUT] The system time high. ++ * @retval None ++*/ ++static INLINE void ++ioh_1588_sys_snap_get(unsigned long *sys_time_low, unsigned long *sys_time_high) ++{ ++ /* Get the System Time Low Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_STL_OFFSET, sys_time_low); ++ ++ /* Get the System Time High Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_STH_OFFSET, sys_time_high); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_tgt_snap_set ( ++ * unsigned long tgt_time_low, unsigned long tgt_time_high) ++ * @brief Set Target Time value ++ * @param tgt_time_low [IN] The target time low. ++ * @param tgt_time_high [IN] The target time high. ++ * @retval None. ++*/ ++static INLINE void ++ioh_1588_tgt_snap_set(unsigned long tgt_time_low, unsigned long tgt_time_high) ++{ ++ /* Update the Target Time Low Register contents */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_TTL_OFFSET, tgt_time_low); ++ ++ /* Update the Target Time High Register contents */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_TTH_OFFSET, tgt_time_high); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_tgt_snap_get( ++ * unsigned long *tgt_time_low, unsigned long *tgt_time_high) ++ * @brief Get Target Time value ++ * @param tgt_time_low [OUT] The target time low. ++ * @param tgt_time_high [IN] The target time high. ++ * @retval None ++*/ ++static INLINE void ++ioh_1588_tgt_snap_get(unsigned long *tgt_time_low, unsigned long *tgt_time_high) ++{ ++ /* Get the Target Time Low Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_TTL_OFFSET, tgt_time_low); ++ ++ /* Get the Target Time High Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_TTH_OFFSET, tgt_time_high); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_addend_set(unsigned long fsv) ++ * @brief Set Frequency Scaling Value ++ * @param fsv [IN] Frequency ++ * @retval None ++*/ ++static INLINE void ioh_1588_addend_set(unsigned long fsv) ++{ ++ /* Update the Addend Register contents */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_ADD_OFFSET, fsv); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_addend_get(unsigned long *fsv) ++ * @brief Get Frequency Scaling Value ++ * @param fsv [OUT] The frequency. ++ * @retval None ++*/ ++static INLINE void ioh_1588_addend_get(unsigned long *fsv) ++{ ++ /* Get the Addend Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_ADD_OFFSET, fsv); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_pps_set(unsigned long pps) ++ * @brief Set Pulse Per Second Value ++ * @param pps [IN] The pulse per second value. ++ * @retval None. ++*/ ++static INLINE void ioh_1588_pps_set(unsigned long pps) ++{ ++ /* Update the PPS Compare Register contents */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_PPS_OFFSET, pps); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_pps_get(unsigned long *pps) ++ * @brief Get Pulse Per Second Value ++ * @param pps [OUT] The pulse per second value. ++ * @retval None. ++*/ ++static INLINE void ioh_1588_pps_get(unsigned long *pps) ++{ ++ /* Get the PPS Compare Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_PPS_OFFSET, pps); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_aux_master_snap_get( ++ * unsigned long *amms_low, unsigned long *amms_high) ++ * @brief Get AMMS value ++ * @param amms_low [OUT] AMMS low value. ++ * @param amms_high [OUT] AMMS high value. ++ * @retval None. ++*/ ++static INLINE void ++ioh_1588_aux_master_snap_get(unsigned long *amms_low, unsigned long *amms_high) ++{ ++ /* Get the Auxiliary Master Mode Snapshot Low Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_AMSL_OFFSET, amms_low); ++ ++ /* Get the Auxiliary Master Mode Snapshot High Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_AMSH_OFFSET, amms_high); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_aux_slave_snap_get( ++ * unsigned long *asms_low, unsigned long *asms_high) ++ * @brief Get ASMS value ++ * @param asms_low [OUT] The ASMS low value. ++ * @param asms_high [OUT] The ASMS high value. ++ * @retval None ++*/ ++static INLINE void ++ioh_1588_aux_slave_snap_get(unsigned long *asms_low, unsigned long *asms_high) ++{ ++ /* Get the Auxiliary Slave Mode Snapshot Low Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_ASSL_OFFSET, asms_low); ++ ++ /* Get the Auxiliary Slave Mode Snapshot High Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_ASSH_OFFSET, asms_high); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_master_mode_set( ++ * unsigned long master_mode) ++ * @brief Set the channel mode to 1588 Master/Slave ++ * @param master_mode [IN] The channel mode. ++ * @retval None ++*/ ++static INLINE void ioh_1588_master_mode_set(unsigned long master_mode) ++{ ++ /* SET or CLEAR the Master Mode */ ++ if (TRUE == master_mode) { ++ IOH_DEBUG("ioh_1588_master_mode_set: setting master mode\n"); ++ /* SET the mm bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET, ++ IOH_1588_CC_MM); ++ } else { ++ IOH_DEBUG("ioh_1588_master_mode_set: clearing master mode\n"); ++ /* CLEAR the mm bit */ ++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET, ++ IOH_1588_CC_MM); ++ } ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_master_mode_get (void) ++ * @brief Check for 1588 master mode of channel ++ * @param None. ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_master_mode_get(void) ++{ ++ /* Is the mm bit SET? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CC_OFFSET, ++ IOH_1588_CC_MM); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_timestamp_all_set( ++ * unsigned long allMsg) ++ * @brief Set Timestamp all or only PTP messages flag ++ * @param allMsg [IN] All/PTP messages. ++ * @retval None ++*/ ++static INLINE void ioh_1588_timestamp_all_set(unsigned long allMsg) ++{ ++ /* SET or CLEAR the All Message Timestamping */ ++ if (TRUE == allMsg) { ++ IOH_DEBUG ++ ("ioh_1588_timestamp_all_set: time stamp all messages\n"); ++ /* SET the ta bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET, ++ IOH_1588_CC_TA); ++ } else { /* else of if (TRUE == allMsg) */ ++ ++ IOH_DEBUG ++ ("ioh_1588_timestamp_all_set: time stamp PTP messages \ ++ only\n"); ++ /* CLEAR the ta bit */ ++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET, ++ IOH_1588_CC_TA); ++ } ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_timestamp_all_get(void) ++ * @brief Check for Timestamp all OR only PTP messages flag ++ * @param None. ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_timestamp_all_get(void) ++{ ++ /* Is the ta bit SET? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CC_OFFSET, ++ IOH_1588_CC_TA); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_version_set( ++ * unsigned long versionVal) ++ * @brief Set the 1588 version number ++ * @param versionVal [IN] The version value. ++ * @retval None. ++*/ ++static INLINE void ioh_1588_version_set(unsigned long versionVal) ++{ ++ if (TRUE == versionVal) { ++ IOH_DEBUG ++ ("ioh_1588_version_set supports IEEE1588 v1 and \ ++ IEEE1588-2008\n"); ++ /* SET the version bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET, ++ IOH_1588_CC_VERSION); ++ } else { ++ IOH_DEBUG("ioh_1588_version_set supports IEEE1588 v1 only\n"); ++ /* CLEAR the version bit */ ++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_CC_OFFSET, ++ IOH_1588_CC_VERSION); ++ } ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_version_get (void) ++ * @brief Get the 1588 version number ++ * @param None. ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_version_get(void) ++{ ++ /* Is the version bit SET? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CC_OFFSET, ++ IOH_1588_CC_VERSION); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_can_snap_valid (void) ++ * @brief CAN Timestamp available ++ * @param None ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_can_snap_valid(void) ++{ ++ /* Is the valid bit SET? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CCE_OFFSET, ++ IOH_1588_CE_VAL); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_can_snap_ovr(void) ++ * @brief CAN Timestamp overrun ++ * @param None ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_can_snap_ovr(void) ++{ ++ /* Is the ovr bit SET? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CCE_OFFSET, ++ IOH_1588_CE_OVR); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_can_snap_valid_clear(void) ++ * @brief Clear CAN Timestamp valid flag ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_can_snap_valid_clear(void) ++{ ++ /* CLEAR the valid bit by writing '1' onto it */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_CCE_OFFSET, IOH_1588_CE_VAL); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_can_snap_ovr_clear(void) ++ * @brief Clear CAN Timestamp overrun flag ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_can_snap_ovr_clear(void) ++{ ++ /* CLEAR the overrun bit */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_CCE_OFFSET, IOH_1588_CE_OVR); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_rx_snap_evt(void) ++ * @brief Receive Timestamp available ++ * @param None ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_rx_snap_evt(void) ++{ ++ /* Is the rxs bit SET? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CE_OFFSET, ++ IOH_1588_CE_RXS); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn ++ * @brief Transmit Timestamp available ++ * @param None ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_tx_snap_evt(void) ++{ ++ /* Is the txs bit SET? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_CE_OFFSET, ++ IOH_1588_CE_TXS); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_rx_snap_evt_clear(void) ++ * @brief Clear Receive Timestamp available event ++ * @param None. ++ * @retval None.*/ ++static INLINE void ioh_1588_rx_snap_evt_clear(void) ++{ ++ /* CLEAR the rxs bit */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_CE_OFFSET, IOH_1588_CE_RXS); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_tx_snap_evt_clear(void) ++ * @brief Clear Transmit Timestamp available event ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_tx_snap_evt_clear(void) ++{ ++ unsigned long ev_reg; ++ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CE_OFFSET, &ev_reg); ++ IOH_DEBUG ++ ("ioh_1588_tx_snap_evt_clear event reg content before clearing= %lx\n", ++ ev_reg); ++ ++ /* CLEAR the txs bit */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_CE_OFFSET, IOH_1588_CE_TXS); ++ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CE_OFFSET, &ev_reg); ++ IOH_DEBUG ++ ("ioh_1588_tx_snap_evt_clear event reg content after clearing= %lx\n", ++ ev_reg); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_can_snap_get( ++ * unsigned long *rxs_low,unsigned long *rxs_high) ++ * @brief Get PTP CAN Port Timestamp value ++ * @param rxs_low [OUT] The CAN Rx low value. ++ * @param rxs_high [OUT] The CAN Rx high value. ++ * @retval None. ++*/ ++static INLINE void ++ioh_1588_can_snap_get(unsigned long *rxs_low, unsigned long *rxs_high) ++{ ++ /* Get the Receive Timestamp/Snapshot Low Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CXSL_OFFSET, rxs_low); ++ ++ /* Get the Receive Timestamp/Snapshot High Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CXSH_OFFSET, rxs_high); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_rx_snap_get( ++ * unsigned long *rxs_low, unsigned long *rxs_high) ++ * @brief Get PTP Port Rx Timestamp value ++ * @param rxs_low [OUT] The Snap Rx value. ++ * @param rxs_high [OUT] The Snap Rx Value. ++ * @reatval None ++*/ ++static INLINE void ++ioh_1588_rx_snap_get(unsigned long *rxs_low, unsigned long *rxs_high) ++{ ++ /* Get the Receive Timestamp/Snapshot Low Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_RSL_OFFSET, rxs_low); ++ ++ /* Get the Receive Timestamp/Snapshot High Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_RSH_OFFSET, rxs_high); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_tx_snap_get( ++ * unsigned long *txs_low, unsigned long *txs_high) ++ * @brief Get PTP Port Tx Timestamp value ++ * @param txs_low [OUT] The Port Tx value low. ++ * @param txs_high [OUT] The Port Tx value high. ++ * @retval None ++*/ ++static INLINE void ++ioh_1588_tx_snap_get(unsigned long *txs_low, unsigned long *txs_high) ++{ ++ /* Get the Transmit Timestamp/Snapshot Low Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_XSL_OFFSET, txs_low); ++ ++ /* Get the Transmit Timestamp/Snapshot High Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_XSH_OFFSET, txs_high); ++ ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_uuid_seqid_get( ++ * unsigned long *uuid_low,unsigned long *uuid_high, unsigned int *seq_id) ++ * @brief Get UUID High (16-bit value) & Sequence ID (16-bit value) of ++ * PTP message ++ * @param uuid_low [OUT] The UUID low value. ++ * @param seq_id [OUT] The sequence ID. ++ * @retval None. ++*/ ++static INLINE void ++ioh_1588_uuid_seqid_get(unsigned long *uuid_low, ++ unsigned long *uuid_high, unsigned int *seq_id) ++{ ++ unsigned long regval = 0; ++ ++ /* Get the UUID Low Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_UID_OFFSET, uuid_low); ++ ++ /* Get the Sequence ID and Source UUID High Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_SID_OFFSET, ®val); ++ ++ *seq_id = (regval >> IOH_1588_SID_LOC); ++ *uuid_high = (regval & IOH_1588_LSB_SHORT_MASK); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_op_mode_set(unsigned long mode) ++ * @brief Sets the operation mode. ++ * @param mode [IN] The mode value. ++ * @retval None. ++*/ ++static INLINE void ioh_1588_op_mode_set(unsigned long mode) ++{ ++ unsigned long regval; ++ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CC_OFFSET, ®val); ++ regval = ++ (regval & ~IOH_1588_CC_MODE_MASK) | (mode << ++ IOH_1588_CC_MODE_SHIFT); ++ /* set the operaion mode bits */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_CC_OFFSET, regval); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_op_mode_get(void) ++ * @brief Gets the operation mode. ++ * @param None. ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_op_mode_get(void) ++{ ++ unsigned long regval; ++ unsigned long mode; ++ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_CC_OFFSET, ®val); ++ /* get the operaion mode bits */ ++ mode = (regval & IOH_1588_CC_MODE_MASK) >> IOH_1588_CC_MODE_SHIFT; ++ ++ return mode; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_eth_enable_set(void) ++ * @brief Enbales the eth. ++ * @param None. ++ * @retval None. ++*/ ++static INLINE void ioh_1588_eth_enable_set(void) ++{ ++ /* SET the eth_enable bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_ECS_OFFSET, IOH_1588_ECS_ETH); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_eth_enable_clear(void) ++ * @brief Clears the eth enable. ++ * @param None. ++ * @retval None. ++*/ ++static INLINE void ioh_1588_eth_enable_clear(void) ++{ ++ /* Clear the eth_enable bit */ ++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_ECS_OFFSET, IOH_1588_ECS_ETH); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_eth_enable_get(void) ++ * @brief Gets the eth enable. ++ * @param None. ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_eth_enable_get(void) ++{ ++ /* Is eth_enable bit set? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_ECS_OFFSET, ++ IOH_1588_ECS_ETH); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_can_enable_set(void) ++ * @brief Sets the CAN enable. ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_can_enable_set(void) ++{ ++ /* SET the can_enable bit */ ++ IOH_SET_ADDR_BIT(ioh_1588_base + IOH_1588_ECS_OFFSET, IOH_1588_ECS_CAN); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_can_enable_clear(void) ++ * @brief Sets the CAN enable clear ++ * @param None ++ * @retval None ++*/ ++static INLINE void ioh_1588_can_enable_clear(void) ++{ ++ /* Clear the can_enable bit */ ++ IOH_CLR_ADDR_BIT(ioh_1588_base + IOH_1588_ECS_OFFSET, IOH_1588_ECS_CAN); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE unsigned long ioh_1588_can_enable_get(void) ++ * @brief Gets the CAN enable status. ++ * @param None. ++ * @retval unsigned long ++*/ ++static INLINE unsigned long ioh_1588_can_enable_get(void) ++{ ++ /* Is can_enable bit set? */ ++ return IOH_BIT_SET_CHECK(ioh_1588_base + IOH_1588_ECS_OFFSET, ++ IOH_1588_ECS_CAN); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_station_set(unsigned long station, ++ * unsigned long value) ++ * @brief Set the station[1-6] address to be used in PTP message ++ * @param station [IN] The Station. ++ * @param value [IN] The Value. ++ * @retval None. ++*/ ++static INLINE void ++ioh_1588_station_set(unsigned long station, unsigned long value) ++{ ++ IOH_DEBUG("ioh_1588_station_set;setting station address=%lx\n", value); ++ /* Set the Station Address Register contents */ ++ IOH_REG_32_WRITE(ioh_1588_base + IOH_1588_STA_OFFSET + ++ station * sizeof(int), value); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn static INLINE void ioh_1588_station_get (unsigned long station, ++ * unsigned long *value) ++ * @brief Get the station[1-6] address used in PTP message ++ * @param station [IN] The station. ++ * @param value [OUT] The value. ++ * @retval None. ++*/ ++static INLINE void ++ioh_1588_station_get(unsigned long station, unsigned long *value) ++{ ++ /* Get the Station Address Register contents */ ++ IOH_REG_32_READ(ioh_1588_base + IOH_1588_STA_OFFSET + ++ station * sizeof(int), value); ++ *value &= 0xFF; /* only one byte */ ++} ++ ++/** ++ * Support functions definitions ++ */ ++ ++/** ++ * @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_disable_interrupts(void) ++ * @brief Disables all interrupts on the 1588 device. ++ * @param None ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++ ++enum ioh_status ioh_1588_disable_interrupts(void) ++{ ++ if (ioh_1588_base != 0) { ++ IOH_DEBUG ++ ("ioh_1588_disable_interrupts:invoking \ ++ ioh_1588_ttm_imask_clear\n"); ++ ioh_1588_ttm_imask_clear(); ++ IOH_DEBUG ++ ("ioh_1588_disable_interrupts:invoking \ ++ ioh_1588_asms_imask_clear\n"); ++ ioh_1588_asms_imask_clear(); ++ IOH_DEBUG ++ ("ioh_1588_disable_interrupts:invoking \ ++ ioh_1588_amms_imask_clear\n"); ++ ioh_1588_amms_imask_clear(); ++ IOH_DEBUG ++ ("ioh_1588_disable_interrupts:invoking \ ++ ioh_1588_pps_imask_clear\n"); ++ ioh_1588_pps_imask_clear(); ++ } ++ return IOH_1588_SUCCESS; ++} ++ ++/** ++ * @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_interrupt_pending( ++ * unsigned long *pending) ++ * @brief Check whether there is any pending interrupts from the 1588 ++ * device. ++ * @param pending [IN] Pending flag which set to TRUE if there is any ++ * pending interrupt ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_interrupt_pending(unsigned long *pending) ++{ ++ *pending = FALSE; ++ if (ioh_1588_pps_evt_get() || ioh_1588_amms_evt_get() || ++ ioh_1588_asms_evt_get() || ioh_1588_ttm_evt_get()) { ++ IOH_DEBUG("ioh_1588_interrupt_pending:interrupt pending\n"); ++ *pending = TRUE; ++ } else { ++ IOH_DEBUG("ioh_1588_interrupt_pending:NO interrupt pending\n"); ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/** ++ * @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh1588PTPPortMode ioh_1588_port_mode_get( ++ * enum ioh1588PTPPort ptpPort) ++ * @brief Function to determine the port mode ++ * @param ptpPort [IN] Interested port (GBE_0) ++ * @retval enum ioh1588PTPPortMode ++ * - IOH_1588PTP_PORT_MASTER ++ * - IOH_1588PTP_PORT_SLAVE ++ * - IOH_1588PTP_PORT_ANYMODE ++ */ ++enum ioh1588PTPPortMode ioh_1588_port_mode_get(enum ioh1588PTPPort ptpPort) ++{ ++ /* Local variables */ ++ unsigned long master_mode = FALSE; ++ unsigned long any_mode = FALSE; ++ enum ioh1588PTPPortMode port_mode = IOH_1588PTP_PORT_SLAVE; ++ ++ /* Get the Mode of the PTP Port */ ++ master_mode = ioh_1588_master_mode_get(); ++ any_mode = ioh_1588_timestamp_all_get(); ++ ++ /* Is ANY mode (all message timestamp mode) on? */ ++ if (TRUE == any_mode) { ++ IOH_DEBUG ++ ("ioh_1588_port_mode_get:all messages being timestamped\n"); ++ /* ++ * When Any mode is set, all messages are time stamped, ++ * irrespective of the Master/Slave mode bit ++ */ ++ port_mode = IOH_1588PTP_PORT_ANYMODE; ++ IOH_DEBUG ++ ("ioh_1588_port_mode_get:port_mode = \ ++ IOH_1588PTP_PORT_ANYMODE\n"); ++ } else { ++ /* Is Master mode on? */ ++ if (TRUE == master_mode) { ++ port_mode = IOH_1588PTP_PORT_MASTER; ++ IOH_DEBUG ++ ("ioh_1588_port_mode_get:port_mode = \ ++ IOH_1588PTP_PORT_MASTER\n"); ++ } else { ++ port_mode = IOH_1588PTP_PORT_SLAVE; ++ IOH_DEBUG ++ ("ioh_1588_port_mode_get:port_mode = \ ++ IOH_1588PTP_PORT_SLAVE\n"); ++ } ++ } ++ ++ return port_mode; ++} ++ ++/* ++ * Public API definitions ++ */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_blpl_base_address_set(unsigned long base_addr) ++ * ++ * @brief Function sets the virtual address of registers ++ * @remarks This API will set the starting virtual addresses for the ++ * 1588 hardware registers. The main tasks performed by this ++ * function are: ++ * - If the aargument passed is NULL, return status ++ * IOH_1588_INVALIDPARAM ++ * - Set base address of IEEE 1588 registers to specified value ++ * ++ * ++ * @param base_addr [IN] - Virtual address of IEEE 1588 module registers ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Invalid parameter passed ++ */ ++enum ioh_status ioh_1588_blpl_base_address_set(unsigned long base_addr) ++{ ++ if (!base_addr) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_blpl_base_address_set:invalid base address\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ ioh_1588_base = base_addr; ++ IOH_DEBUG("ioh_1588_blpl_base_address_set:base address=%lx\n", ++ ioh_1588_base); ++ ++ /* Initialize the callback pointers */ ++ ioh_tt_cbptr = (ioh1588TargetTimeCallback) NULL; ++ ioh_am_cbptr = (ioh1588AuxTimeCallback) NULL; ++ ioh_as_cbptr = (ioh1588AuxTimeCallback) NULL; ++ ioh_pps_cbptr = (ioh1588PulsePerSecondCallback) NULL; ++ IOH_DEBUG("ioh_1588_blpl_base_address_set:initialized callback ptrs\n"); ++ ++ /* Reset the statistics counters */ ++ ioh_1588_stats.rxMsgs = ioh_1588_stats.txMsgs = 0; ++ IOH_DEBUG("ioh_1588_blpl_base_address_set:reset statistics counters\n"); ++ ++ /* Clear availability of various events */ ++ IOH_DEBUG ++ ("ioh_1588_blpl_base_address_set:invoking \ ++ ioh_1588_pps_evt_clear\n"); ++ ioh_1588_pps_evt_clear(); ++ IOH_DEBUG ++ ("ioh_1588_blpl_base_address_set:invoking \ ++ ioh_1588_ttm_evt_clear\n"); ++ ioh_1588_ttm_evt_clear(); ++ IOH_DEBUG ++ ("ioh_1588_blpl_base_address_set:invoking \ ++ ioh_1588_amms_evt_clear\n"); ++ ioh_1588_amms_evt_clear(); ++ IOH_DEBUG ++ ("ioh_1588_blpl_base_address_set:invoking \ ++ ioh_1588_asms_evt_clear\n"); ++ ioh_1588_asms_evt_clear(); ++ ++ IOH_DEBUG("ioh_1588_blpl_base_address_set:returning success\n"); ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_port_config_set( ++ * enum ioh1588PTPPort ptpPort, enum ioh1588PTPPortMode ptpPortMode) ++ * ++ * @brief Configure IEEE 1588 Hardware Assist message detection on a given PTP ++ * port ++ * ++ * @remarks This API enables the time stamping on a particular PTP port. ++ * The main tasks performed by this function are: ++ * - Validate the parameters and return ++ * IOH_1588_INVALIDPARAM, if found invalid ++ * - Modify the TS_Channel_Control register to set the ++ * requested mode ++ * ++ * ++ * @param ptpPort [IN] - port on which PTP message detection to be enabled ++ * @param ptpPortMode [IN]- Master/Slave/All messages ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed ++ */ ++enum ioh_status ++ioh_1588_ptp_port_config_set(enum ioh1588PTPPort ptpPort, ++ enum ioh1588PTPPortMode ptpPortMode) ++{ ++ /* Verify the parameters for proper values */ ++ if (ptpPort != IOH_1588_GBE_0_1588PTP_PORT) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ptp_port_config_set:invalid ptp port\ ++ returning IOH_1588_GBE_0_1588PTP_PORT\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Set the Mode of the PTP Port */ ++ switch (ptpPortMode) { ++ case IOH_1588PTP_PORT_MASTER: ++ { ++ IOH_DEBUG ++ ("ioh_1588_ptp_port_config_set:port_mode=\ ++ IOH_1588PTP_PORT_MASTER\n"); ++ IOH_DEBUG ++ ("ioh_1588_ptp_port_config_set:invoking \ ++ ioh_1588_master_mode_set \ ++ with param TRUE\n"); ++ ioh_1588_master_mode_set(TRUE); ++ IOH_DEBUG ++ ("ioh_1588_ptp_port_config_set:invoking \ ++ ioh_1588_timestamp_all_set \ ++ with param FALSE\n"); ++ ioh_1588_timestamp_all_set(FALSE); ++ break; ++ } ++ case IOH_1588PTP_PORT_SLAVE: ++ { ++ IOH_DEBUG ++ ("ioh_1588_ptp_port_config_set:port_mode=\ ++ IOH_1588PTP_PORT_SLAVE\n"); ++ IOH_DEBUG ++ ("ioh_1588_ptp_port_config_set:invoking \ ++ ioh_1588_master_mode_set \ ++ with param FALSE\n"); ++ ioh_1588_master_mode_set(FALSE); ++ IOH_DEBUG ++ ("ioh_1588_ptp_port_config_set:invoking \ ++ ioh_1588_timestamp_all_set \ ++ with param FALSE\n"); ++ ioh_1588_timestamp_all_set(FALSE); ++ break; ++ } ++ case IOH_1588PTP_PORT_ANYMODE: ++ { ++ IOH_DEBUG ++ ("ioh_1588_ptp_port_config_set:port_mode=\ ++ IOH_1588PTP_PORT_ANYMODE\n"); ++ IOH_DEBUG ++ ("ioh_1588_ptp_port_config_set:invoking \ ++ ioh_1588_master_mode_set \ ++ with param FALSE\n"); ++ ioh_1588_master_mode_set(FALSE); ++ IOH_DEBUG ++ ("ioh_1588_ptp_port_config_set:invoking \ ++ ioh_1588_timestamp_all_set \ ++ with param TRUE\n"); ++ ioh_1588_timestamp_all_set(TRUE); ++ break; ++ } ++ default: ++ { ++ IOH_LOG(KERN_ERR, "ioh_1588_ptp_port_config_set: \ ++ Invalid Port Mode (%d) \ ++ returning IOH_1588_INVALIDPARAM\n", ++ ptpPortMode); ++ return IOH_1588_INVALIDPARAM; ++ } ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_port_config_get( ++ * enum ioh1588PTPPort ptpPort, ++ * enum ioh1588PTPPortMode *ptpPortMode) ++ * ++ * @brief Get the configuration of IEEE 1588 Hardware Assist message ++ * detection ++ * for given PTP port ++ * ++ * @remarks This API retrieves the time stamping configuration of the given ++ * PTP port. ++ * The main tasks performed by this function are: ++ * - Validate the parameters and return ++ * IOH_1588_INVALIDPARAM, if found invalid ++ * - Return the current master/slave mode from ++ * TS_Channel_Control register ++ * ++ * ++ * @param ptpPort [IN] port for which PTP message configuration ++ * to be obtained ++ * @param ptpPortMode [OUT] Master/Slave/All messages ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed ++ */ ++enum ioh_status ++ioh_1588_ptp_port_config_get(enum ioh1588PTPPort ptpPort, ++ enum ioh1588PTPPortMode *ptpPortMode) ++{ ++ /* Verify the parameters for proper values */ ++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) || ++ ((enum ioh1588PTPPortMode *) NULL == ptpPortMode)) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ptp_port_config_get:\ ++ invalid port_mode or port \ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Get the Mode of the PTP Port */ ++ IOH_DEBUG ++ ("ioh_1588_ptp_port_config_get:invoking ioh_1588_port_mode_get\n"); ++ *ptpPortMode = ioh_1588_port_mode_get(ptpPort); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_rx_poll( ++ * enum ioh1588PTPPort ptpPort, ++ * struct ioh1588PtpMsgData *ptpMsgData) ++ * ++ * @brief Poll the IEEE 1588 Hardware Assist receive side message/time ++ * stamp ++ * detection status for given PTP Port ++ * ++ * @remarks This API will poll for the availability of a time stamp on the ++ * received Sync (in slave mode) or Delay_Req (in master mode) ++ * messages. ++ * The buffer is provided by the caller. ++ * The steps performed in this function are: ++ * - If ptpPort not valid or ptpMsgData is NULL return ++ * IOH_1588_INVALID_PARAM ++ * - Find out whether locked /unlocked mode. ++ * - If locked mode ,check the TS_Channel_Event register for Rx ++ * event ++ * - If locked mode, return NO TIMESTAMP if no Rx event flag is ++ * set. ++ * - Read the time stamp from RECV_Snapshot low, high and ++ * - SourceUUID0 low, high registers ++ * - Clear SourceUUId if the mode is not master/slave and PTP v1 ++ * only. ++ * - Increment RX messages captured statistics counter ++ * - If locked mode ,clear the RX event is TS_Channel_Event ++ * register ++ * ++ * ++ * @param ptpPort [IN] port on which time stamp availability ++ * to be checked ++ * @param ptpMsgData [out] Captured time stamp and other message ++ * information ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed ++ * @li IOH_1588_NOTIMESTAMP - Time stamp not available ++ * @li IOH_1588_FAILED - Internal error occurred ++ */ ++enum ioh_status ++ioh_1588_ptp_rx_poll(enum ioh1588PTPPort ptpPort, \ ++ struct ioh1588PtpMsgData *ptpMsgData) ++{ ++ unsigned long locked_mode = FALSE; ++ ++ enum ioh1588PTPPortMode port_mode = IOH_1588PTP_PORT_MODE_INVALID; ++ enum ioh1588PTPVersion ptpVersion = IOH_1588PTP_VERSION_INVALID; ++ enum ioh1588PTPOperationMode opMode = IOH_1588PTP_OP_MODE_INVALID; ++ ++ /* Verify the parameters for proper values */ ++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) || ++ ((struct ioh1588PtpMsgData *) NULL == ptpMsgData)) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ptp_rx_poll:invalid port or ptp message \ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /*Get the PTP version */ ++ ptpVersion = ioh_1588_version_get(); ++ ++ /*check if locked/unlocked mode */ ++ if (ptpVersion == IOH_1588PTP_VERSION_0) { /*PTP v1 only */ ++ /* Get the Mode of the PTP Port if only PTPv1 is supported */ ++ port_mode = ioh_1588_port_mode_get(ptpPort); ++ if (port_mode != IOH_1588PTP_PORT_ANYMODE) ++ locked_mode = TRUE; ++ } else { /*PTP v1 & v2 */ ++ ++ /*get operation mode */ ++ opMode = ioh_1588_op_mode_get(); ++ if ((opMode != IOH_1588PTP_OP_MODE_V1_ALL_MSGS) && ++ (opMode != IOH_1588PTP_OP_MODE_V1_V2_ALL_MSGS)) { ++ locked_mode = TRUE; ++ } ++ } ++ ++ /*if locked mode,check event flag */ ++ if ((TRUE == locked_mode) && (TRUE != ioh_1588_rx_snap_evt())) { ++ IOH_DEBUG ++ ("ioh_1588_ptp_rx_poll:locked mode-event flag not set\n"); ++ IOH_DEBUG("ioh_1588_ptp_rx_poll:NO TIMESTAMP \ ++ returning IOH_1588_NOTIMESTAMP\n"); ++ return IOH_1588_NOTIMESTAMP; ++ } ++ ++ /* Fetch the receive timestamp */ ++ IOH_DEBUG("ioh_1588_ptp_rx_poll:invoking ioh_1588_rx_snap_get\n"); ++ ioh_1588_rx_snap_get(&ptpMsgData->ptpTimeStamp.timeValueLowWord, ++ &ptpMsgData->ptpTimeStamp.timeValueHighWord); ++ ++ IOH_DEBUG ++ ("ioh_1588_ptp_rx_poll:ioh_1588_ptp_rx_poll Snapshot (Hi:Low): \ ++ %lx : %lx\n", ++ ptpMsgData->ptpTimeStamp.timeValueHighWord, ++ ptpMsgData->ptpTimeStamp.timeValueLowWord); ++ ++ /* Fetch the UUID & Seq# of PTP messages in 'Master/Slave Mode' only */ ++ if ((TRUE == locked_mode) && (IOH_1588PTP_VERSION_0 == ptpVersion)) { ++ IOH_DEBUG ++ ("ioh_1588_ptp_rx_poll:invoking ioh_1588_uuid_seqid_get\n"); ++ ioh_1588_uuid_seqid_get(&ptpMsgData->ptpUuid.uuidValueLowWord, ++ &ptpMsgData->ptpUuid. ++ uuidValueHighHalfword, ++ &ptpMsgData->ptpSequenceNumber); ++ } ++ /* Clear-off the UUID & Seq# of all the messages in 'Any Mode' */ ++ else { ++ IOH_DEBUG ++ ("ioh_1588_ptp_rx_poll:port mode is ANYMODE,clearing off \ ++ UUID & SeqNumber\n"); ++ ptpMsgData->ptpUuid.uuidValueLowWord = 0; ++ ptpMsgData->ptpUuid.uuidValueHighHalfword = 0; ++ ptpMsgData->ptpSequenceNumber = 0; ++ } ++ ++ /* Increment receive timestamp counter ++ * Note:In unlocked modes,this will get incremented ++ * for every rx time stamp poll. ++ */ ++ ioh_1588_stats.rxMsgs++; ++ IOH_DEBUG("ioh_1588_ptp_rx_poll:incremented rcv timestamp \ ++ counter=%ld\n", ioh_1588_stats.rxMsgs); ++ ++ /* ++ * Fill-in the PTP message type.This can be done ++ * only when PTP v1 alone is supported and mode ++ * is master/slave.Set the message type as unknown ++ * for all other cases. ++ */ ++ if (ptpVersion == IOH_1588PTP_VERSION_0) { /*PTP v1 only */ ++ switch (port_mode) { ++ case IOH_1588PTP_PORT_MASTER: ++ { ++ IOH_DEBUG ++ ("ioh_1588_ptp_rx_poll:PTP message type=\ ++ IOH_1588PTP_MSGTYPE_DELAYREQ\n"); ++ ptpMsgData->ptpMsgType = ++ IOH_1588PTP_MSGTYPE_DELAYREQ; ++ break; ++ } ++ case IOH_1588PTP_PORT_SLAVE: ++ { ++ IOH_DEBUG ++ ("ioh_1588_ptp_rx_poll:PTP message type=\ ++ IOH_1588PTP_MSGTYPE_SYNC\n"); ++ ptpMsgData->ptpMsgType = ++ IOH_1588PTP_MSGTYPE_SYNC; ++ break; ++ } ++ case IOH_1588PTP_PORT_ANYMODE: ++ { ++ IOH_DEBUG ++ ("ioh_1588_ptp_rx_poll:PTP message type=\ ++ IOH_1588PTP_MSGTYPE_UNKNOWN\n"); ++ ptpMsgData->ptpMsgType = ++ IOH_1588PTP_MSGTYPE_UNKNOWN; ++ break; ++ } ++ default: ++ { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ptp_rx_poll(): Invalid Port \ ++ Mode \ ++ returning IOH_1588_FAILED\n"); ++ return IOH_1588_FAILED; ++ } ++ } ++ } else { /*PTP v1 & v2 */ ++ ++ IOH_DEBUG ++ ("ioh_1588_ptp_rx_poll:PTP message type=\ ++ IOH_1588PTP_MSGTYPE_UNKNOWN\n"); ++ ptpMsgData->ptpMsgType = IOH_1588PTP_MSGTYPE_UNKNOWN; ++ } ++ ++ /* If locked mode allow next timestamp to be captured */ ++ if (TRUE == locked_mode) { ++ IOH_DEBUG ++ ("ioh_1588_ptp_rx_poll:invoking \ ++ ioh_1588_rx_snap_evt_clear\n"); ++ ioh_1588_rx_snap_evt_clear(); ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_tx_poll( ++ * enum ioh1588PTPPort ptpPort, ++ * struct ioh1588PtpMsgData *ptpMsgData) ++ * ++ * @brief Poll the IEEE 1588 Hardware Assist transmit side message/time ++ * stamp ++ * detection status for given PTP Port ++ * ++ * @remarks This API will poll for the availability of a time stamp on the ++ * transmit side Sync (in master mode) or Delay_Req (in slave mode) ++ * messages. ++ * The buffer is provided by the caller. ++ * The main tasks performed by this function are: ++ * - If ptpPort not valid or ptpMsgData is NULL ++ * return IOH_1588_INVALID_PARAM ++ * - Find out whether locked /unlocked mode. ++ * - If locked mode ,check the TS_Channel_Event register for Tx ++ * event ++ * - If locked mode, return NO TIMESTAMP if no Tx event flag is ++ * set. ++ * - Read the time stamp from XMIT_Snapshot low, high registers ++ * - Increment TX messages captured statistics counter ++ * - If locked mode, clear the TX event is TS_Channel_Event ++ * register ++ * ++ * ++ * @param ptpPort [IN] port on which time stamp availability to be ++ * checked ++ * @param ptpMsgData [OUT] Captured time stamp and other message ++ * information ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed ++ * @li IOH_1588_NOTIMESTAMP - Time stamp not available ++ * @li IOH_1588_FAILED - Internal error occurred ++ */ ++enum ioh_status ++ioh_1588_ptp_tx_poll(enum ioh1588PTPPort ptpPort, \ ++ struct ioh1588PtpMsgData *ptpMsgData) ++{ ++ unsigned long locked_mode = FALSE; ++ ++ enum ioh1588PTPPortMode port_mode = IOH_1588PTP_PORT_MODE_INVALID; ++ enum ioh1588PTPVersion ptpVersion = IOH_1588PTP_VERSION_INVALID; ++ enum ioh1588PTPOperationMode opMode = IOH_1588PTP_OP_MODE_INVALID; ++ ++ /* Verify the parameters for proper values */ ++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) || ++ ((struct ioh1588PtpMsgData *) NULL == ptpMsgData)) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ptp_tx_poll:invalid port or ptp message \ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /*Get the PTP version */ ++ ptpVersion = ioh_1588_version_get(); ++ ++ /*check if locked/unlocked mode */ ++ if (ptpVersion == IOH_1588PTP_VERSION_0) { /*PTP v1 only */ ++ /* Get the Mode of the PTP Port if only PTPv1 is supported */ ++ port_mode = ioh_1588_port_mode_get(ptpPort); ++ if (port_mode != IOH_1588PTP_PORT_ANYMODE) ++ locked_mode = TRUE; ++ } else { /*PTP v1 & v2 */ ++ ++ /*get operation mode */ ++ opMode = ioh_1588_op_mode_get(); ++ if ((opMode != IOH_1588PTP_OP_MODE_V1_ALL_MSGS) && ++ (opMode != IOH_1588PTP_OP_MODE_V1_V2_ALL_MSGS)) { ++ locked_mode = TRUE; ++ } ++ } ++ ++ /*if locked mode,check event flag */ ++ if ((TRUE == locked_mode) && (TRUE != ioh_1588_tx_snap_evt())) { ++ IOH_DEBUG ++ ("ioh_1588_ptp_tx_poll:locked mode-event flag not set\n"); ++ IOH_DEBUG ++ ("ioh_1588_ptp_tx_poll:ioh_1588_ptp_tx_poll NO TIMESTAMP \ ++ returning IOH_1588_NOTIMESTAMP\n"); ++ return IOH_1588_NOTIMESTAMP; ++ } ++ ++ /* read time stamp registers */ ++ ioh_1588_tx_snap_get(&ptpMsgData->ptpTimeStamp.timeValueLowWord, ++ &ptpMsgData->ptpTimeStamp.timeValueHighWord); ++ ++ IOH_DEBUG ++ ("ioh_1588_ptp_tx_poll:ioh_1588_ptp_tx_poll Snapshot (Hi:Low): \ ++ %lx : %lx\n", ++ ptpMsgData->ptpTimeStamp.timeValueHighWord, ++ ptpMsgData->ptpTimeStamp.timeValueLowWord); ++ /* ++ * Fill the UUID and Seq# with invalid values (zeros) ++ * since they are not relevant for transmit timestamp ++ */ ++ ptpMsgData->ptpUuid.uuidValueLowWord = 0; ++ ptpMsgData->ptpUuid.uuidValueHighHalfword = 0; ++ ptpMsgData->ptpSequenceNumber = 0; ++ ++ /* ++ * Increment transmit timestamp counter ++ * Note:In unlocked modes,this will get incremented ++ * for every tx time stamp poll ++ */ ++ ioh_1588_stats.txMsgs++; ++ IOH_DEBUG("ioh_1588_ptp_tx_poll:incremented tx timestamp counter=%ld\n", ++ ioh_1588_stats.txMsgs); ++ ++ /* ++ * Fill-in the PTP message type.This can be done ++ * only when PTP v1 alone is supported and mode ++ * is master/slave.Set the message type as unknown ++ * for all other cases. ++ */ ++ if (ptpVersion == IOH_1588PTP_VERSION_0) { /*PTP v1 only */ ++ switch (port_mode) { ++ case IOH_1588PTP_PORT_MASTER: ++ { ++ IOH_DEBUG ++ ("ioh_1588_ptp_tx_poll:PTP message type=\ ++ IOH_1588PTP_MSGTYPE_SYNC\n"); ++ ptpMsgData->ptpMsgType = ++ IOH_1588PTP_MSGTYPE_SYNC; ++ break; ++ } ++ case IOH_1588PTP_PORT_SLAVE: ++ { ++ IOH_DEBUG ++ ("ioh_1588_ptp_tx_poll:PTP message type=\ ++ IOH_1588PTP_MSGTYPE_DELAYREQ\n"); ++ ptpMsgData->ptpMsgType = ++ IOH_1588PTP_MSGTYPE_DELAYREQ; ++ break; ++ } ++ case IOH_1588PTP_PORT_ANYMODE: ++ { ++ IOH_DEBUG ++ ("ioh_1588_ptp_tx_poll:PTP message type=\ ++ IOH_1588PTP_MSGTYPE_UNKNOWN\n"); ++ ptpMsgData->ptpMsgType = ++ IOH_1588PTP_MSGTYPE_UNKNOWN; ++ break; ++ } ++ default: ++ { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ptp_tx_poll(): \ ++ Invalid Port Mode \ ++ returning IOH_1588_FAILED\n"); ++ return IOH_1588_FAILED; ++ } ++ } ++ } else { /*PTP v1 & v2 */ ++ ++ IOH_DEBUG ++ ("ioh_1588_ptp_tx_poll:PTP message type=\ ++ IOH_1588PTP_MSGTYPE_UNKNOWN\n"); ++ ptpMsgData->ptpMsgType = IOH_1588PTP_MSGTYPE_UNKNOWN; ++ } ++ ++ /* If locked mode allow next timestamp to be captured */ ++ if (locked_mode) { ++ IOH_DEBUG ++ ("ioh_1588_ptp_tx_poll:invoking ioh_1588_tx_snap_evt_clear\n"); ++ ioh_1588_tx_snap_evt_clear(); ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_system_time_set( ++ * struct ioh1588TimeValue systemTime) ++ * ++ * @brief This API sets the system time to given value ++ * @remarks Sets the System Time in the IEEE 1588 hardware assist block. ++ * ++ * @param systemTime [IN] value to set the system time to ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_system_time_set(struct ioh1588TimeValue systemTime) ++{ ++ unsigned long old_fsv = 0; ++ ++ /* Retrieve old Frequency Scaling Value */ ++ IOH_DEBUG("ioh_1588_system_time_set:invoking ioh_1588_addend_get\n"); ++ ioh_1588_addend_get(&old_fsv); ++ IOH_DEBUG("ioh_1588_system_time_set:existing freq scaling value=%lx\n", ++ old_fsv); ++ ++ /* ++ * Set the Frequency Scaling Value to zero (0) so that ++ * System Time doesn't get incremented while it is being written to ++ */ ++ IOH_DEBUG("ioh_1588_system_time_set:invoking ioh_1588_addend_set \ ++ to set frequncy scaling value to 0\n"); ++ ioh_1588_addend_set(0); ++ ++ /* Update System Time with user specified values */ ++ IOH_DEBUG("ioh_1588_system_time_set:invoking \ ++ ioh_1588_ioh_1588_sys_snap_set \ ++ with values low=%lx,high=%lx\n", ++ systemTime.timeValueLowWord, systemTime.timeValueHighWord); ++ ioh_1588_sys_snap_set(systemTime.timeValueLowWord, ++ systemTime.timeValueHighWord); ++ ++ /* ++ * Let the hardware assist re-evaluate the target time reached ++ * condition based on the new system time ++ */ ++ IOH_DEBUG("ioh_1588_system_time_set:invoking ioh_1588_ttm_evt_clear\n"); ++ ioh_1588_ttm_evt_clear(); ++ ++ /* ++ * Restore old Frequency Scaling Value so that System Time ++ * can be incremented ++ */ ++ IOH_DEBUG("ioh_1588_system_time_set:invoking ioh_1588_addend_set \ ++ to restore freq scaling value\n"); ++ ioh_1588_addend_set(old_fsv); ++ ++ IOH_DEBUG("ioh_1588_system_time_set:returning IOH_1588_SUCCESS\n"); ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_system_time_get( ++ * struct ioh1588TimeValue *systemTime) ++ * ++ * @brief Gets the System Time from the IEEE 1588 hardware assist block ++ * @remarks This API gets the System time. ++ * The main steps followed in this function are: ++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL ++ * - Return the current system time by reading the SystemTime low, ++ * high registers ++ * ++ * ++ * @param systemTime [OUT] - Address to which system time is to be ++ * returned ++ * ++ * @return enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Invalid address passed ++ */ ++enum ioh_status ioh_1588_system_time_get(struct ioh1588TimeValue *systemTime) ++{ ++ /* Verify the parameter */ ++ if ((struct ioh1588TimeValue *) NULL == systemTime) { ++ IOH_LOG(KERN_ERR, "ioh_1588_system_time_get:invalid parameter \ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Fetch System Time */ ++ ioh_1588_sys_snap_get(&systemTime->timeValueLowWord, ++ &systemTime->timeValueHighWord); ++ ++ IOH_DEBUG("ioh_1588_system_time_get:invoked \ ++ ioh_1588_ioh_1588_sys_snap_get \ ++ system time:low=%lx,high=%lx\n", ++ systemTime->timeValueLowWord, systemTime->timeValueHighWord); ++ IOH_DEBUG("ioh_1588_system_time_get returning IOH_1588_SUCCESS\n"); ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_tick_rate_set(unsigned long tickRate) ++ * ++ * @brief Sets the Frequency Scaling Value in the IEEE 1588 hardware ++ * assist block ++ * ++ * @remarks This API sets the Tick Rate (Frequency Scaling Value) in the ++ * IEEE 1588 block. This value determines the progress at which ++ * the System time advances. ++ * Note: For the A1 hardware sample, the addend register value ++ * configured in the hardware ++ * is calculated as follows: ++ * Addend register value = Logical right shift tickRate by 1 and ++ * set MSB to 1 ++ * ++ * @param tickRate [IN] Frequency scaling value ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_tick_rate_set(unsigned long tickRate) ++{ ++ /* Update the Frequency Scaling Value */ ++#ifdef IOH_IEEE1588_A1_SAMPLE_BUG ++ /*back up tick rate provided by app */ ++ gTickRateApp = tickRate; ++ /*calculate actual tick rate for device */ ++ IOH_DEBUG("ioh_1588_tick_rate_set:tick rate [app]=%lx\n", tickRate); ++ tickRate = ((tickRate >> 1) | 0x80000000); ++ IOH_DEBUG("ioh_1588_tick_rate_set:tick rate [dev]=%lx\n", tickRate); ++#endif ++ IOH_DEBUG("ioh_1588_tick_rate_set:invoking ioh_1588_addend_set \ ++ with tick rate=%lx\n", tickRate); ++ ioh_1588_addend_set(tickRate); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_tick_rate_get(unsigned long *tickRate) ++ * ++ * @brief Gets the Frequency Scaling Value from the IEEE 1588 hardware ++ * assist block ++ * ++ * @remarks This API gets the Tick Rate (Frequency Scaling Value) used in ++ * the IEEE 1588 block. ++ * This value determines the progress at which the System time ++ * advances. ++ * The main steps followed in this function are: ++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL ++ * - Return the content of Addend register ++ * ++ * ++ * @param tickRate [IN] - Address where current Frequency scaling value is ++ * returned ++ * ++ * @return enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARM - Invalid address passed ++ */ ++enum ioh_status ioh_1588_tick_rate_get(unsigned long *tickRate) ++{ ++ /* Verify the parameter */ ++ if ((unsigned long *)NULL == tickRate) { ++ IOH_LOG(KERN_ERR, "ioh_1588_tick_rate_get:invalid tick rate\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++#ifdef IOH_IEEE1588_A1_SAMPLE_BUG ++ /* Retrieve Frequency Scaling Value stored in software buffer */ ++ *tickRate = gTickRateApp; ++#else ++ /* Retrieve Current Frequency Scaling Value */ ++ ioh_1588_addend_get(tickRate); ++#endif ++ IOH_DEBUG("ioh_1588_tick_rate_get:invoked ioh_1588_addend_get\ ++ the tick rate=%lx\n", *tickRate); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_target_time_interrupt_enable( ++ * ioh1588TargetTimeCallback callBack) ++ * ++ * @brief Enable the target time reached/exceeded system time interrupt ++ * ++ * @remarks This API enables the interrupt that occurs when the System time ++ * reaches the Target time set in the IEEE 1588 hardware assist ++ * block. ++ * The main steps followed in this function are: ++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL ++ * - Modify Time Sync Control Register to enable target time ++ * interrupt ++ * - Set the handler to callback function provided ++ * ++ * ++ * @param callBack [IN] - Routine to be invoked when target time reached ++ * interrupt occurs ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Null parameter passed for callback ++ */ ++enum ioh_status ++ioh_1588_target_time_interrupt_enable(ioh1588TargetTimeCallback callBack) ++{ ++ /* Verify the parameter */ ++ if ((ioh1588TargetTimeCallback) NULL == callBack) { ++ IOH_LOG(KERN_ERR, "ioh_1588_target_time_interrupt_enable\ ++ invalid callback;returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Register the Callback */ ++ ioh_tt_cbptr = callBack; ++ ++ /* Set target time interrupt mask */ ++ IOH_DEBUG("ioh_1588_target_time_interrupt_enable:invoking\ ++ ioh_1588_ttm_imask_set\n"); ++ ioh_1588_ttm_imask_set(); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_target_time_interrupt_disable(void) ++ * ++ * @brief Disable the target time reached/exceeded system time interrupt ++ * ++ * @remarks This API disables the interrupt that occurs when the System time ++ * reaches the Target time set in the IEEE 1588 hardware assist ++ * block. ++ * The main steps followed in this function are: ++ * - Modify Time Sync Control Register to disable target time ++ * interrupt ++ * - Clear the callback handler ++ * ++ * @param None ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_target_time_interrupt_disable(void) ++{ ++ /* Clear target time interrupt mask */ ++ IOH_DEBUG("ioh_1588_target_time_interrupt_disable:invoking \ ++ ioh_1588_ttm_imask_clear\n"); ++ ioh_1588_ttm_imask_clear(); ++ ++ /* Unregister the Callback */ ++ ioh_tt_cbptr = (ioh1588TargetTimeCallback) NULL; ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_target_time_poll( ++ * unsigned long *ttmPollFlag, struct ioh1588TimeValue *targetTime) ++ * ++ * @brief Poll to verify whether the System time is greater or equal ++ * to the Target time in the IEEE 1588 hardware assist block. ++ * ++ * @remarks The main steps followed in this function are: ++ * - Validate the parameters and return IOH_1588_INVALIDPARAM, if ++ * not valid ++ * - If callback function registered, return status ++ * IOH_1588_INTERRUPTMODEINUSE ++ * - Read the TS_Event register to check for the presence of valid ++ * snapshot ++ * - Read the TargetTimeSnap low, high registers ++ * - Clear the event from TS_Event register ++ * ++ * ++ * @param ttmPollFlag [OUT] TRUE if target time has reached system ++ * time ++ * FALSE if target time has not reached ++ * system time ++ * @param targetTime [OUT] Snap shot of target time captured ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Null parameter passed ++ * @li IOH_1588_INTERRUPTMODEINUSE - Interrupt mode is in use ++ */ ++enum ioh_status ++ioh_1588_target_time_poll(unsigned long *ttmPollFlag, ++ struct ioh1588TimeValue *targetTime) ++{ ++ /* Verify the parameters */ ++ if (((unsigned long *)NULL == ttmPollFlag) || ++ ((struct ioh1588TimeValue *) NULL == targetTime)) { ++ IOH_LOG(KERN_ERR, "ioh_1588_target_time_poll: invalid param\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Is interrupt mode of processing is enabled? */ ++ if ((ioh1588TargetTimeCallback) NULL != ioh_tt_cbptr) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_target_time_poll:returning \ ++ IOH_1588_INTERRUPTMODEINUSE\n"); ++ return IOH_1588_INTERRUPTMODEINUSE; ++ } ++ ++ /* Is the System Time reached or exceeded Target Time? */ ++ *ttmPollFlag = ioh_1588_ttm_evt_get(); ++ if (FALSE == *ttmPollFlag) { ++ IOH_DEBUG ++ ("ioh_1588_target_time_poll:target time not reached\n"); ++ /* Target Time not to be returned yet */ ++ targetTime->timeValueLowWord = 0; ++ targetTime->timeValueHighWord = 0; ++ ++ return IOH_1588_SUCCESS; ++ } ++ ++ IOH_DEBUG("ioh_1588_target_time_poll:target time reached\n"); ++ /* Get the Target Time */ ++ ioh_1588_tgt_snap_get(&targetTime->timeValueLowWord, ++ &targetTime->timeValueHighWord); ++ ++ IOH_DEBUG("ioh_1588_target_time_poll:target time:low=%lx high=%lx\n", ++ targetTime->timeValueLowWord, targetTime->timeValueHighWord); ++ ++ IOH_DEBUG ++ ("ioh_1588_target_time_poll:invoking ioh_1588_ttm_evt_clear\n"); ++ /* Clear the target time reached condition (ttipend bit) */ ++ ioh_1588_ttm_evt_clear(); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_target_time_set( ++ * struct ioh1588TimeValue targetTime) ++ * ++ * @brief Sets the Target Time in the IEEE 1588 hardware assist block ++ * ++ * @remarks This API will set the Target Time to a given value. ++ * ++ * @param targetTime [IN] - Target time to set ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_target_time_set(struct ioh1588TimeValue targetTime) ++{ ++ unsigned long old_mask = FALSE; ++ ++ /* Retrieve existing target time interrupt mask value */ ++ old_mask = ioh_1588_ttm_imask_get(); ++ IOH_DEBUG("ioh_1588_target_time_set:target time interrupt mask=%lx\n", ++ old_mask); ++ ++ /* ++ * Clear the target time interrupt mask so that the interrupt will not ++ * come ++ * during the time we manipulate the registers. ++ */ ++ IOH_DEBUG("ioh_1588_target_time_set:invoking ioh_1588_ttm_imask_clear\ ++ to clear the target time interrupt mask\n"); ++ ioh_1588_ttm_imask_clear(); ++ ++ IOH_DEBUG("ioh_1588_target_time_set:invoking ioh_1588_tgt_snap_set \ ++ with values:low=%lx,high=%lx\n", \ ++ targetTime.timeValueLowWord, targetTime.timeValueHighWord); ++ /* Update Target Time with user specified values */ ++ ioh_1588_tgt_snap_set(targetTime.timeValueLowWord, ++ targetTime.timeValueHighWord); ++ ++ /* ++ * Let the hardware assist re-evaluate the target time reached ++ * condition based on the new target time ++ */ ++ IOH_DEBUG("ioh_1588_target_time_set:invoking ioh_1588_ttm_evt_clear\n"); ++ ioh_1588_ttm_evt_clear(); ++ ++ /* Restore the preserved target time interrupt mask value */ ++ if (TRUE == old_mask) { ++ IOH_DEBUG ++ ("ioh_1588_target_time_set:invoking \ ++ ioh_1588_ttm_imask_set\n"); ++ ioh_1588_ttm_imask_set(); ++ } ++ ++ IOH_DEBUG("ioh_1588_target_time_set:returning IOH_1588_SUCCESS\n"); ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_target_time_get( ++ * struct ioh1588TimeValue *targetTime) ++ * ++ * @brief Gets the Target Time in the IEEE 1588 hardware assist block ++ * ++ * @remarks This API will get the Target Time from IEEE 1588 block ++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL ++ * - Read and return the content of TargetTime low, high registers ++ * ++ * ++ * @param targetTime [IN] - Address to which target time is to be returned ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Null parameter passed ++ */ ++enum ioh_status ioh_1588_target_time_get(struct ioh1588TimeValue *targetTime) ++{ ++ /* Verify the parameter */ ++ if ((struct ioh1588TimeValue *) NULL == targetTime) { ++ IOH_DEBUG("ioh_1588_target_time_get:invalid param \ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Get Target Time */ ++ ioh_1588_tgt_snap_get(&targetTime->timeValueLowWord, ++ &targetTime->timeValueHighWord); ++ IOH_DEBUG("ioh_1588_target_time_get:invoked ioh_1588_tgt_snap_get \ ++ target time:low=%lx,high:%lx\n", \ ++ targetTime->timeValueLowWord, targetTime->timeValueHighWord); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_time_interrupt_enable( ++ * enum ioh1588AuxMode auxMode,ioh1588AuxTimeCallback callBack) ++ * ++ * @brief Enables the interrupt for the Auxiliary Master/Slave mode for ++ * Time ++ * Stamp in the IEEE 1588 hardware assist block ++ * ++ * @remarks This API will enable the Auxiliary Master/Slave ++ * Time stamp Interrupt. The main steps followed in ++ * this function are: ++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL ++ * - Modify the Time Sync Controller register to enable the ++ * interrupt ++ * - Set the callback routine ++ * ++ * ++ * @param auxMode [IN] - Auxiliary slave or master mode ++ * @param callBack [IN] - Callback to be invoked when interrupt ++ * fires ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Null parameter passed ++ */ ++enum ioh_status ++ioh_1588_aux_time_interrupt_enable(enum ioh1588AuxMode auxMode, ++ ioh1588AuxTimeCallback callBack) ++{ ++ /* Verify the parameters */ ++ if ((IOH_1588_AUXMODE_INVALID <= auxMode) || ++ ((ioh1588AuxTimeCallback) NULL == callBack)) { ++ IOH_DEBUG("ioh_1588_aux_time_interrupt_enable:invalid param \ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Register the Callback and SET the amm/asm bits on */ ++ if (IOH_1588_AUXMODE_MASTER == auxMode) { ++ IOH_DEBUG ++ ("ioh_1588_aux_time_interrupt_enable:IOH_1588_AUXMODE_MASTER \ ++ invoking ioh_1588_amms_imask_set\n"); ++ ioh_am_cbptr = callBack; ++ ioh_1588_amms_imask_set(); ++ ++ } else { ++ IOH_DEBUG ++ ("ioh_1588_aux_time_interrupt_enable:IOH_1588_AUXMODE_SLAVE \ ++ invoking ioh_1588_asms_imask_set\n"); ++ ioh_as_cbptr = callBack; ++ ioh_1588_asms_imask_set(); ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_time_interrupt_disable( ++ * enum ioh1588AuxMode auxMode) ++ * ++ * @brief Disables the interrupt for the Auxiliary Master/Slave mode for ++ * Time ++ * Stamp in the IEEE 1588 hardware assist block ++ * ++ * @remarks This API will disable the Auxiliary Master/Slave ++ * Time stamp Interrupt. The main steps followed in this ++ * function are: ++ * - Return IOH_1588_INVALIDPARAM if auxMode passed is not valid ++ * - Modify the Time Sync Controller register to disable the ++ * interrupt ++ * - Clear the callback handler ++ * ++ * ++ * @param auxMode [IN] - Auxiliary slave or master mode ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Invalid mode specified ++ */ ++enum ioh_status ioh_1588_aux_time_interrupt_disable(enum ioh1588AuxMode auxMode) ++{ ++ /* Verify the parameters */ ++ if (IOH_1588_AUXMODE_INVALID <= auxMode) { ++ IOH_DEBUG("ioh_1588_aux_time_interrupt_disable:invalid param \ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ if (IOH_1588_AUXMODE_MASTER == auxMode) { ++ IOH_DEBUG ++ ("ioh_1588_aux_time_interrupt_disable:\ ++ IOH_1588_AUXMODE_MASTER\ ++ invoking ioh_1588_amms_imask_clear\n"); ++ ioh_1588_amms_imask_clear(); ++ ioh_am_cbptr = (ioh1588AuxTimeCallback) NULL; ++ } else { ++ IOH_DEBUG ++ ("ioh_1588_aux_time_interrupt_disable:\ ++ IOH_1588_AUXMODE_SLAVE\ ++ invoking ioh_1588_asms_imask_clear\n"); ++ ioh_1588_asms_imask_clear(); ++ ioh_as_cbptr = (ioh1588AuxTimeCallback) NULL; ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_time_poll( ++ * enum ioh1588AuxMode auxMode, unsigned long *pollFlag, ++ * struct ioh1588TimeValue*auxTime) ++ * ++ * @brief Poll for the Auxiliary Time Stamp captured event for the mode ++ * requested ++ * ++ * @remarks Polls for the Time stamp in the appropriate Auxiliary Snapshot ++ * Registers based on the mode specified. Return true and ++ * the contents of the Auxiliary snapshot if it is available ++ * otherwise return false. The main steps followed in this function ++ * are: ++ * - Validate the parameters and return IOH_1588_INVALIDPARAM if ++ * found invalid ++ * - If callbacks registered, return status ++ * IOH_1588_INTERRUPTMODEINUSE ++ * - Read the TS_Event register to check for the presence of valid ++ * snapshot ++ * - If the event is not set, return status IOH_1588_NOTIMESTAMP ++ * - Read the AuxSlaveModeSnap or AuxMasterModeSnap low, high ++ * registers depending on the auxMode ++ * - Clear the event from TS_Event register ++ * ++ * ++ * @param auxMode [IN] Auxiliary Snapshot Register ++ * (Master/Slave) to be checked ++ * @param pollFlag [OUT] TRUE if time stamp captured in aux ++ * snapshot register ++ * FALSE if the time stamp not captured ++ * @param auxTime [OUT] Buffer for returning captured Auxiliary ++ * Snapshot time ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Invalid parameter passed ++ * @li IOH_1588_INTERRUPTMODEINUSE - Interrupt mode is in use ++ */ ++enum ioh_status ++ioh_1588_aux_time_poll(enum ioh1588AuxMode auxMode, unsigned long *pollFlag, ++ struct ioh1588TimeValue *auxTime) ++{ ++ unsigned long ammsFlag = FALSE; ++ unsigned long asmsFlag = FALSE; ++ ++ /* Verify the parameters */ ++ if (((unsigned long *)NULL == pollFlag) || ++ (IOH_1588_AUXMODE_INVALID <= auxMode) || ++ ((struct ioh1588TimeValue *) NULL == auxTime)) { ++ IOH_DEBUG("ioh_1588_aux_time_poll:invalid param \ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Get Auxiliary Master/Slave Mode Snapshot */ ++ if (IOH_1588_AUXMODE_MASTER == auxMode) { ++ IOH_DEBUG("ioh_1588_aux_time_poll:IOH_1588_AUXMODE_MASTER\n"); ++ /* Is interrupt mode of processing is enabled? */ ++ if ((ioh1588AuxTimeCallback) NULL != ioh_am_cbptr) { ++ IOH_DEBUG ++ ("ioh_1588_aux_time_poll:interrupt mode in use\n"); ++ return IOH_1588_INTERRUPTMODEINUSE; ++ } ++ ++ /* Is the Auxiliary Master Mode Snapshot available? */ ++ ammsFlag = ioh_1588_amms_evt_get(); ++ if (FALSE == ammsFlag) { ++ IOH_DEBUG("ioh_1588_aux_time_poll:NO Auxiliary Master \ ++ Mode Snapshot available\n"); ++ *pollFlag = FALSE; ++ auxTime->timeValueLowWord = 0; ++ auxTime->timeValueHighWord = 0; ++ return IOH_1588_SUCCESS; ++ } ++ ++ /* Get Auxiliary Master Snapshot */ ++ ioh_1588_aux_master_snap_get(&auxTime->timeValueLowWord, ++ &auxTime->timeValueHighWord); ++ IOH_DEBUG("ioh_1588_aux_time_poll:Auxiliary Master Snapshot \ ++ low=%lx,high=%lx\n", auxTime->timeValueLowWord, \ ++ auxTime->timeValueHighWord); ++ ++ *pollFlag = TRUE; ++ ++ /* Clear the snapshot availability condition */ ++ IOH_DEBUG ++ ("ioh_1588_aux_time_poll:invoking ioh_1588_amms_evt_clear\n"); ++ ioh_1588_amms_evt_clear(); ++ } else { /* IOH_1588_AUXMODE_SLAVE == auxMode */ ++ ++ IOH_DEBUG("ioh_1588_aux_time_poll:IOH_1588_AUXMODE_SLAVE\n"); ++ /* Is interrupt mode of processing is enabled? */ ++ if ((ioh1588AuxTimeCallback) NULL != ioh_as_cbptr) { ++ IOH_DEBUG ++ ("ioh_1588_aux_time_poll:interrupt mode in use\n"); ++ return IOH_1588_INTERRUPTMODEINUSE; ++ } ++ ++ /* Is the Auxiliary Slave Mode Snapshot available? */ ++ asmsFlag = ioh_1588_asms_evt_get(); ++ if (FALSE == asmsFlag) { ++ IOH_DEBUG("ioh_1588_aux_time_poll:NO Auxiliary Slave \ ++ Mode Snapshot available\n"); ++ *pollFlag = FALSE; ++ auxTime->timeValueLowWord = 0; ++ auxTime->timeValueHighWord = 0; ++ return IOH_1588_SUCCESS; ++ } ++ ++ /* Get Auxiliary Slave Snapshot */ ++ ioh_1588_aux_slave_snap_get(&auxTime->timeValueLowWord, ++ &auxTime->timeValueHighWord); ++ IOH_DEBUG("ioh_1588_aux_time_poll:Auxiliary Slave Snapshot \ ++ low=%lx,high=%lx\n", auxTime->timeValueLowWord, \ ++ auxTime->timeValueHighWord); ++ ++ *pollFlag = TRUE; ++ ++ /* Clear the snapshot availability condition */ ++ IOH_DEBUG ++ ("ioh_1588_aux_time_poll:invoking ioh_1588_amms_evt_clear\n"); ++ ioh_1588_asms_evt_clear(); ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_reset(void) ++ * ++ * @brief Resets the IEEE 1588 hardware assist block ++ * ++ * @remarks Resets the IEEE 1588 hardware assist block. The ++ * main steps followed in this function are: ++ * - Set the reset bit of Time Sync Control register ++ * - Clear the reset bit of Time Sync Control register ++ * -Note: For A0/A1 sample, test mode setting is enabled for ++ * the 64 bit System Time Register. This is a work around for ++ * the non continuous value in the 64 bit System Time Register ++ * consisting of High(32bit) / Low(32bit) ++ * ++ * ++ * @param None ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation is successful ++ */ ++enum ioh_status ioh_1588_reset(void) ++{ ++ /* Reset Hardware Assist */ ++ IOH_DEBUG("ioh_1588_reset:invoking ioh_1588_block_reset\n"); ++ ioh_1588_block_reset(); ++ ++ /* Clear Stats */ ++ ioh_1588_stats.rxMsgs = ioh_1588_stats.txMsgs = 0; ++ ++ /* Unregister any Callback Routines */ ++ IOH_DEBUG("ioh_1588_reset:unregistering callbacks\n"); ++ ioh_pps_cbptr = (ioh1588PulsePerSecondCallback) NULL; ++ ioh_am_cbptr = (ioh1588AuxTimeCallback) NULL; ++ ioh_as_cbptr = (ioh1588AuxTimeCallback) NULL; ++ ioh_tt_cbptr = (ioh1588TargetTimeCallback) NULL; ++ ++#ifdef IOH_IEEE1588_A0_A1_SAMPLE_BUG ++ /*enable all 32 bits in system time registers */ ++ ioh_1588_set_system_time_count(); ++#endif ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_chnl_reset(enum ioh1588PTPPort ptpPort) ++ * ++ * @brief Resets the IEEE 1588 channel by resetting the hardware block ++ * ++ * @remarks This API also sets the reset bit in the IEEE1588 to fully ++ * resets the block. The main steps followed in this function ++ * are: ++ * - Return IOH_1588_INVALIDPARAM if ptpPort passed is not valid ++ * - Perform a block level reset by invoking ioh_1588_reset ++ * ++ * ++ * @param ptpPort [IN] The PTP port that is to be reset ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_chnl_reset(enum ioh1588PTPPort ptpPort) ++{ ++ IOH_DEBUG("ioh_1588_chnl_reset:invoking ioh_1588_reset\n"); ++ return ioh_1588_reset(); ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_stats_get(struct ioh1588Stats *stats) ++ * ++ * @brief Returns the ioh1588 Statistics ++ * ++ * @remarks This API will return the statistics of the snapshots captured ++ * for ++ * receive and transmit of messages. The main steps followed in ++ * this ++ * function are: ++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL ++ * - Return the counter values stored for Rx and Tx messages ++ * ++ * ++ * @param stats [OUT] Buffer for returning the statistics ++ * counter values ++ * ++ * ++ * @note These counters are updated only when the client application ++ * polls for ++ * the time stamps or interrupt are enabled. ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation is successful ++ * @li IOH_1588_INVALIDPARAM - NULL parameter passed ++ */ ++ ++enum ioh_status ioh_1588_stats_get(struct ioh1588Stats *stats) ++{ ++ /* Verify the parameter */ ++ if ((struct ioh1588Stats *) NULL == stats) { ++ IOH_DEBUG("ioh_1588_stats_get:invalid param \ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Return the statistics */ ++ stats->rxMsgs = ioh_1588_stats.rxMsgs; ++ stats->txMsgs = ioh_1588_stats.txMsgs; ++ IOH_DEBUG("ioh_1588_stats_get:stats-txMsg=%lx,rxMsg=%lx\n", ++ stats->txMsgs, stats->rxMsgs); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn void ioh_1588_stats_reset(void) ++ * ++ * @brief Resets the statistics counters ++ * ++ * @remarks This API will reset the statistics counters maintained by the ++ * driver ++ * ++ * @param None ++ * @retval None ++ */ ++void ioh_1588_stats_reset(void) ++{ ++ /* Clear the statistics */ ++ IOH_DEBUG("ioh_1588_stats_reset:clearing stats\n"); ++ ioh_1588_stats.rxMsgs = ioh_1588_stats.txMsgs = 0; ++ ++ return; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn void ioh_1588_save_state(void) ++ * ++ * @brief Save the state of all registers ++ * ++ * @remarks Save the content of all registers of IEEE1588 module ++ * ++ * @param None. ++ * ++ * @retval None ++ */ ++void ioh_1588_save_state(void) ++{ ++ int i; ++ unsigned long val; ++ ++ /* Time stamp control register */ ++ ioh_1588_regs.ts_control = ++ (ioh_1588_ttm_imask_get() << IOH_1588_TSC_TTM_SHIFT) | ++ (ioh_1588_asms_imask_get() << IOH_1588_TSC_ASMS_SHIFT) | ++ (ioh_1588_amms_imask_get() << IOH_1588_TSC_AMMS_SHIFT) | ++ (ioh_1588_pps_imask_get() << IOH_1588_TSC_PPSM_SHIFT); ++ IOH_DEBUG("ioh_1588_save_state:TS_CONTROL reg=%lx\n", ++ ioh_1588_regs.ts_control); ++ ++ /* ++ * Time stamp event register; clear on write, ++ * so no point in reading and then saving; ++ * Will be cleared on restore to start in a clean slate ++ */ ++ ioh_1588_regs.ts_event = IOH_1588_TSE_TTIPEND | IOH_1588_TSE_SNS | ++ IOH_1588_TSE_SNM | IOH_1588_TSE_PPS; ++ IOH_DEBUG("ioh_1588_save_state:TS_EVENT reg=%lx\n", ++ ioh_1588_regs.ts_event); ++ ++ /* Addend register */ ++ ioh_1588_addend_get(&ioh_1588_regs.ts_addend); ++ IOH_DEBUG("ioh_1588_save_state:TS_ADDEND reg=%lx\n", ++ ioh_1588_regs.ts_addend); ++ ++ /* PPS comapre register */ ++ ioh_1588_pps_get(&ioh_1588_regs.ts_compare); ++ IOH_DEBUG("ioh_1588_save_state:TS_COMPARE reg=%lx\n", ++ ioh_1588_regs.ts_compare); ++ ++ /* System time Low and Hi registers */ ++ ioh_1588_sys_snap_get(&ioh_1588_regs.ts_syslo, &ioh_1588_regs.ts_syshi); ++ IOH_DEBUG("ioh_1588_save_state:sys time reg-low =%lx,high=%lx\n", ++ ioh_1588_regs.ts_syslo, ioh_1588_regs.ts_syshi); ++ ++ /* Target time Low and Hi registers */ ++ ioh_1588_tgt_snap_get(&ioh_1588_regs.ts_tgtlo, &ioh_1588_regs.ts_tgthi); ++ IOH_DEBUG("ioh_1588_save_state:target time reg-low =%lx,high=%lx\n", ++ ioh_1588_regs.ts_tgtlo, ioh_1588_regs.ts_tgthi); ++ ++#if 0 ++ /* ++ * Below registers are read only, so no point in reading/storing, since ++ * we can't restore them ++ */ ++ /* Slave mode snapshot Low and Hi registers */ ++ ioh_1588_aux_slave_snap_get(&ioh_1588_regs.ts_asmslo, ++ &ioh_1588_regs.ts_asmshi); ++ ++ /* Master mode snapshot Low and Hi registers */ ++ ioh_1588_aux_master_snap_get(&ioh_1588_regs.ts_ammslo, ++ &ioh_1588_regs.ts_ammshi); ++#endif ++ ioh_1588_regs.ts_cc = ++ (ioh_1588_master_mode_get() << IOH_1588_CC_MM_SHIFT) | ++ (ioh_1588_timestamp_all_get() << IOH_1588_CC_TA_SHIFT) | ++ (ioh_1588_op_mode_get() << IOH_1588_CC_MODE_SHIFT) | ++ (ioh_1588_version_get() << IOH_1588_CC_VERSION_SHIFT); ++ IOH_DEBUG("ioh_1588_save_state:TS_CC reg=%lx\n", ioh_1588_regs.ts_cc); ++ ++ /* Channel event register, not saved - will be cleared on restore */ ++ ioh_1588_regs.ts_ce = IOH_1588_CE_TXS | IOH_1588_CE_RXS; ++ ++#if 0 ++ /* ++ * Below registers are read only, so no point in reading/storing, since ++ * we can't restore them ++ */ ++ ioh_1588_rx_snap_get(&ioh_1588_regs.ts_xslo, &ioh_1588_regs.ts_xshi); ++ ioh_1588_tx_snap_get(&ioh_1588_regs.ts_rslo, &ioh_1588_regs.ts_rshi); ++ ioh_1588_uuid_seqid_get(&ioh_1588_regs.ts_uuidlo, ++ &ioh_1588_regs.ts_uuidhi); ++ ++ /* CAN */ ++ ioh_1588_can_snap_get(&ioh_1588_regs.ts_cxslo, &ioh_1588_regs.ts_cxshi); ++#endif ++ ++ /* CAN Channel event register, not saved - will be cleared on restore */ ++ ioh_1588_regs.ts_cce = IOH_1588_CE_OVR | IOH_1588_CE_VAL; ++ ++ /* Ethernet CAN selector register */ ++ ioh_1588_regs.ts_sel = ++ (ioh_1588_eth_enable_get() << IOH_1588_ECS_ETH_SHIFT) | ++ (ioh_1588_can_enable_get() << IOH_1588_ECS_CAN_SHIFT); ++ IOH_DEBUG("ioh_1588_save_state:TS_SEL reg=%lx\n", ioh_1588_regs.ts_sel); ++ ++ /* Station Address registers */ ++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) { ++ ioh_1588_station_get(i, &val); ++ ioh_1588_regs.ts_sti[i] = val & 0xff; ++ IOH_DEBUG("ioh_1588_save_state:TS_ST[%d] reg=%d\n", i, ++ ioh_1588_regs.ts_sti[i]); ++ } ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn void ioh_1588_restore_state(void) ++ * ++ * @brief Restore the state of all registers ++ * ++ * @remarks Restores the content of all registers of IEEE1588 module. ++ * Note: For A0/A1 sample, test mode setting is enabled for ++ * the 64 bit System Time Register. This is a work around for ++ * the non continuous value in the 64 bit System Time ++ * Register ++ * consisting of High(32bit) / Low(32bit) ++ * ++ * @param None ++ * @retval None ++ */ ++void ioh_1588_restore_state(void) ++{ ++ int i; ++ ++ /* Time stamp control register */ ++ if (ioh_1588_regs.ts_control & IOH_1588_TSC_TTM_MASK) { ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_ttm_imask_set\n"); ++ ioh_1588_ttm_imask_set(); ++ } ++ if (ioh_1588_regs.ts_control & IOH_1588_TSC_ASMS_MASK) { ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_asms_imask_set\n"); ++ ioh_1588_asms_imask_set(); ++ } ++ if (ioh_1588_regs.ts_control & IOH_1588_TSC_AMMS_MASK) { ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_amms_imask_set\n"); ++ ioh_1588_amms_imask_set(); ++ } ++ if (ioh_1588_regs.ts_control & IOH_1588_TSC_PPSM_MASK) { ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_pps_imask_set\n"); ++ ioh_1588_pps_imask_set(); ++ } ++ ++ /* Time stamp event register; clear all events */ ++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_ttm_evt_clear\n"); ++ ioh_1588_ttm_evt_clear(); ++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_asms_evt_clear\n"); ++ ioh_1588_asms_evt_clear(); ++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_amms_evt_clear\n"); ++ ioh_1588_amms_evt_clear(); ++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_pps_evt_clear\n"); ++ ioh_1588_pps_evt_clear(); ++ ++#ifdef IOH_IEEE1588_A0_A1_SAMPLE_BUG ++ /*enable all 32 bits in system time registers */ ++ ioh_1588_set_system_time_count(); ++#endif ++ ++ /* Addend register */ ++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_addend_set\n"); ++ ioh_1588_addend_set(ioh_1588_regs.ts_addend); ++ ++ /* PPS comapre register */ ++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_pps_set\n"); ++ ioh_1588_pps_set(ioh_1588_regs.ts_compare); ++ ++ /* System time Low and Hi registers */ ++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_sys_snap_set\n"); ++ ioh_1588_sys_snap_set(ioh_1588_regs.ts_syslo, ioh_1588_regs.ts_syshi); ++ ++ /* Target time Low and Hi registers */ ++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_tgt_snap_set\n"); ++ ioh_1588_tgt_snap_set(ioh_1588_regs.ts_tgtlo, ioh_1588_regs.ts_tgthi); ++ ++ /* Ethernet Channel Control register */ ++ if (ioh_1588_regs.ts_cc & IOH_1588_CC_MM) { ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_master_mode_set\ ++ with TRUE as parameter\n"); ++ ioh_1588_master_mode_set(TRUE); ++ } ++ if (ioh_1588_regs.ts_cc & IOH_1588_CC_TA) { ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_timestamp_all_set\ ++ with TRUE as parameter\n"); ++ ioh_1588_timestamp_all_set(TRUE); ++ } ++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_op_mode_set\n"); ++ ioh_1588_op_mode_set((ioh_1588_regs.ts_cc & IOH_1588_CC_MODE_MASK) >> ++ IOH_1588_CC_MODE_SHIFT); ++ if (ioh_1588_regs.ts_cc & IOH_1588_CC_VERSION) { ++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_version_set\ ++ with IOH_1588PTP_VERSION_1 as parameter\n"); ++ ioh_1588_version_set(IOH_1588PTP_VERSION_1); ++ } ++ ++ /* Channel event register, cleared on restore */ ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_rx_snap_evt_clear\n"); ++ ioh_1588_rx_snap_evt_clear(); ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_tx_snap_evt_clear\n"); ++ ioh_1588_tx_snap_evt_clear(); ++ ++ /* CAN Channel event register, cleared on restore */ ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_tx_snap_ovr_clear\n"); ++ ioh_1588_can_snap_ovr_clear(); ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_tx_snap_valid_clear\n"); ++ ioh_1588_can_snap_valid_clear(); ++ ++ /* Ethernet CAN selector register */ ++ if (ioh_1588_regs.ts_sel & IOH_1588_ECS_ETH) { ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_eth_enable_set\n"); ++ ioh_1588_eth_enable_set(); ++ } ++ if (ioh_1588_regs.ts_sel & IOH_1588_ECS_CAN) { ++ IOH_DEBUG ++ ("ioh_1588_restore_state:invoking ioh_1588_can_enable_set\n"); ++ ioh_1588_can_enable_set(); ++ } ++ ++ /* Station Address registers */ ++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) { ++ IOH_DEBUG("ioh_1588_restore_state:invoking ioh_1588_station_set\ ++ for station=%d\n", i); ++ ioh_1588_station_set(i, ioh_1588_regs.ts_sti[i]); ++ } ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn void ioh_1588_show(void) ++ * ++ * @brief Display the dump of IEEE 1588 registers ++ * ++ * @remarks This API will dump the contents of configuration, event and ++ * snapshot ++ * registers of the IEEE1588 module ++ * ++ * @param None. ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS ++ */ ++enum ioh_status ioh_1588_show(void) ++{ ++ int i; ++ unsigned long flag = FALSE; ++ unsigned long reg_low = 0; ++ unsigned long reg_hi = 0; ++ unsigned int seq_id = 0; ++ unsigned long uuid_low = 0; ++ unsigned long uuid_hi = 0; ++ ++ /*dump all register as such */ ++ IOH_DEBUG("TS Control Register offset = %x,content = %x\n", ++ IOH_1588_TSC_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_TSC_OFFSET)); ++ IOH_DEBUG("TS Event Register offset = %x,content = %x\n", ++ IOH_1588_TSE_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_TSE_OFFSET)); ++ IOH_DEBUG("TS Addend Register offset = %x,content = %x\n", ++ IOH_1588_ADD_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_ADD_OFFSET)); ++ IOH_DEBUG("TS Accumulator Register offset = %x,content = %x\n", ++ IOH_1588_ACC_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_ACC_OFFSET)); ++ IOH_DEBUG("TS Test Register offset = %x,content = %x\n", ++ IOH_1588_TST_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_TST_OFFSET)); ++ IOH_DEBUG("TS PPS Compare Register offset = %x,content = %x\n", ++ IOH_1588_PPS_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_PPS_OFFSET)); ++ IOH_DEBUG("TS System Time Low Register offset = %x,content = %x\n", ++ IOH_1588_STL_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_STL_OFFSET)); ++ IOH_DEBUG("TS System Time High Register offset = %x,content = %x\n", ++ IOH_1588_STH_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_STH_OFFSET)); ++ IOH_DEBUG("TS Target Time Low Register offset = %x,content = %x\n", ++ IOH_1588_TTL_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_TTL_OFFSET)); ++ IOH_DEBUG("TS Target Time High Register offset = %x,content = %x\n", ++ IOH_1588_TTH_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_TTH_OFFSET)); ++ IOH_DEBUG ++ ("TS Aux Slave Mode Snapshot Low Register offset = %x,content = %x\n", ++ IOH_1588_ASSL_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_ASSL_OFFSET)); ++ IOH_DEBUG ++ ("TS Aux Slave Mode Snapshot High Register offset = %x,content = %x\n", ++ IOH_1588_ASSH_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_ASSH_OFFSET)); ++ IOH_DEBUG ++ ("TS Aux Master Mode Snapshot Low Register offset = %x,content = %x\n", ++ IOH_1588_AMSL_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_AMSL_OFFSET)); ++ IOH_DEBUG ++ ("TS Aux Master Mode Snapshot High Register offset = %x,content = %x\n", ++ IOH_1588_AMSH_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_AMSH_OFFSET)); ++ IOH_DEBUG("TS Channel Control Register offset = %x,content = %x\n", ++ IOH_1588_CC_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_CC_OFFSET)); ++ IOH_DEBUG("TS Channel Event Register offset = %x,content = %x\n", ++ IOH_1588_CE_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_CE_OFFSET)); ++ IOH_DEBUG("TS Tx Snapshot High Register offset = %x,content = %x\n", ++ IOH_1588_XSH_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_XSH_OFFSET)); ++ IOH_DEBUG("TS Tx Snapshot Low Register offset = %x,content = %x\n", ++ IOH_1588_XSL_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_XSL_OFFSET)); ++ IOH_DEBUG("TS Rx Snapshot Low Register offset = %x,content = %x\n", ++ IOH_1588_RSL_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_RSL_OFFSET)); ++ IOH_DEBUG("TS Rx Snapshot High Register offset = %x,content = %x\n", ++ IOH_1588_RSH_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_RSH_OFFSET)); ++ IOH_DEBUG("TS Source UUID Low Register offset = %x,content = %x\n", ++ IOH_1588_UID_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_UID_OFFSET)); ++ IOH_DEBUG ++ ("TS Source UUID High/SequenceID Register offset = %x,content = %x\n", ++ IOH_1588_SID_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_SID_OFFSET)); ++ IOH_DEBUG("TS CAN Channel Status Register offset = %x,content = %x\n", ++ IOH_1588_CCE_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_CCE_OFFSET)); ++ IOH_DEBUG("TS CAN Snapshot Low Register offset = %x,content = %x\n", ++ IOH_1588_CXSL_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_CXSL_OFFSET)); ++ IOH_DEBUG("TS CAN Snapshot High Register offset = %x,content = %x\n", ++ IOH_1588_CXSH_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_CXSH_OFFSET)); ++ IOH_DEBUG("TS Ethernet/CAN Selecti Register offset = %x,content = %x\n", ++ IOH_1588_ECS_OFFSET, ++ IOH_READ32(ioh_1588_base + IOH_1588_ECS_OFFSET)); ++ /* Station Address registers */ ++ IOH_DEBUG("TS Station Address [1-6]"); ++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) { ++ ioh_1588_station_get(i, ®_low); ++ IOH_DEBUG(":%02lx", reg_low); ++ } ++ IOH_DEBUG("\n"); ++ ++ /* Target time reached interrupt mask */ ++ flag = ioh_1588_ttm_imask_get(); ++ IOH_LOG(KERN_ERR, "Target Time Interrupt Mask: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Auxiliary Slave Mode Snapshot interrupt mask */ ++ flag = ioh_1588_asms_imask_get(); ++ IOH_LOG(KERN_ERR, "ASMS Interrupt Mask: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Auxiliary Master Mode Snapshot interrupt mask */ ++ flag = ioh_1588_amms_imask_get(); ++ IOH_LOG(KERN_ERR, "AMMS Interrupt Mask: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Pulse per second interrupt mask */ ++ flag = ioh_1588_pps_imask_get(); ++ IOH_LOG(KERN_ERR, "PPS Interrupt Mask: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* TS_Event Register */ ++ /* Target time interrupt event */ ++ flag = ioh_1588_ttm_evt_get(); ++ IOH_LOG(KERN_ERR, "Target Time Interrupt Pending: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Auxiliary Slave Mode Snapshot event */ ++ flag = ioh_1588_asms_evt_get(); ++ IOH_LOG(KERN_ERR, "ASMS Snapshot Event: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Auxiliary Master Mode Snapshot event */ ++ flag = ioh_1588_amms_evt_get(); ++ IOH_LOG(KERN_ERR, "AMMS Snapshot Event: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* PPS Match event */ ++ flag = ioh_1588_pps_evt_get(); ++ IOH_LOG(KERN_ERR, "PPS Match Event: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Addend Register */ ++ reg_low = 0; ++ ioh_1588_addend_get(®_low); ++ IOH_LOG(KERN_ERR, "Frequency Scaling Value: %lx\n", reg_low); ++ ++ /* PPS Comapre Register */ ++ reg_low = 0; ++ ioh_1588_pps_get(®_low); ++ IOH_LOG(KERN_ERR, "PPS Compare Register Value: %lx\n", reg_low); ++ ++ /* System Time registers */ ++ reg_low = reg_hi = 0; ++ ioh_1588_sys_snap_get(®_low, ®_hi); ++ IOH_LOG(KERN_ERR, "System Time (Hi:Low): %lx : %lx\n", reg_hi, reg_low); ++ ++ /* Target Time registers */ ++ reg_low = reg_hi = 0; ++ ioh_1588_tgt_snap_get(®_low, ®_hi); ++ IOH_LOG(KERN_ERR, "Target Time (Hi:Low): %lx : %lx\n", reg_hi, reg_low); ++ ++ /* Auxiliary Slave Mode Snapshot registers */ ++ reg_low = reg_hi = 0; ++ ioh_1588_aux_slave_snap_get(®_low, ®_hi); ++ IOH_LOG(KERN_ERR, ++ "Auxiliary Slave Mode Snapshot (Hi:Low) : %lx : %lx\n", reg_hi, ++ reg_low); ++ ++ /* Auxiliary Master Mode Snapshot registers */ ++ reg_low = reg_hi = 0; ++ ioh_1588_aux_master_snap_get(®_low, ®_hi); ++ IOH_LOG(KERN_ERR, ++ "Auxiliary Master Mode Snapshot (Hi:Low): %lx : %lx\n", reg_hi, ++ reg_low); ++ ++ /* Ethernet port */ ++ IOH_LOG(KERN_ERR, "\nPTP Eth Port\n"); ++ ++ /* Master Mode */ ++ flag = ioh_1588_master_mode_get(); ++ IOH_LOG(KERN_ERR, "Master Mode: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Timestamp All PTP messages */ ++ flag = ioh_1588_timestamp_all_get(); ++ IOH_LOG(KERN_ERR, "Timestamp All Messages: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Version */ ++ flag = ioh_1588_version_get(); ++ IOH_LOG(KERN_ERR, "Version support: %s\n", ++ ((TRUE == flag) ? "v1 and v2" : "v1 only")); ++ ++ /* Receive Snapshot Locked */ ++ flag = ioh_1588_rx_snap_evt(); ++ IOH_LOG(KERN_ERR, "Receive Snapshot Locked: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Transmit Snapshot Locked */ ++ flag = ioh_1588_tx_snap_evt(); ++ IOH_LOG(KERN_ERR, "Transmit Snapshot Locked: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Receive Snapshot registers */ ++ reg_low = reg_hi = 0; ++ ioh_1588_rx_snap_get(®_low, ®_hi); ++ IOH_LOG(KERN_ERR, "Receive Snapshot (Hi:Low): %lx : %lx\n", reg_hi, ++ reg_low); ++ ++ /* Transmit Snapshot registers */ ++ reg_low = reg_hi = 0; ++ ioh_1588_tx_snap_get(®_low, ®_hi); ++ IOH_LOG(KERN_ERR, "Transmit Snapshot (Hi:Low): %lx : %lx\n", reg_hi, ++ reg_low); ++ ++ /* UUID and Seqquence Id */ ++ ioh_1588_uuid_seqid_get(&uuid_low, &uuid_hi, &seq_id); ++ IOH_LOG(KERN_ERR, "UUID (Hi:Lo): %lx : %lx\n", uuid_hi, uuid_low); ++ IOH_LOG(KERN_ERR, "Sequence id: %x\n", seq_id); ++ ++ /* CAN port */ ++ IOH_LOG(KERN_ERR, "\nPTP CAN Port:\n"); ++ ++ /* Snapshot Valid */ ++ flag = ioh_1588_can_snap_valid(); ++ IOH_LOG(KERN_ERR, "Snapshot Valid : %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Snapshot Overrun */ ++ flag = ioh_1588_can_snap_ovr(); ++ IOH_LOG(KERN_ERR, "Snapshot Overrun: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* CAN Snapshot registers */ ++ reg_low = reg_hi = 0; ++ ioh_1588_can_snap_get(®_low, ®_hi); ++ IOH_LOG(KERN_ERR, "CAN Snapshot (Hi:Low): %lx : %lx\n", reg_hi, ++ reg_low); ++ ++ /* Ethernet Selector */ ++ flag = ioh_1588_eth_enable_get(); ++ IOH_LOG(KERN_ERR, "\nEthernet Enable: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* CAN Selector */ ++ flag = ioh_1588_can_enable_get(); ++ IOH_LOG(KERN_ERR, "CAN Enable: %s\n", ++ ((TRUE == flag) ? "Set" : "Clear")); ++ ++ /* Station Address Registers */ ++ IOH_LOG(KERN_ERR, "Station Address [1-6]"); ++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) { ++ ioh_1588_station_get(i, ®_low); ++ IOH_LOG(KERN_ERR, ":%02lx", reg_low); ++ } ++ IOH_LOG(KERN_ERR, "\n"); ++ ++ /* Statistics */ ++ IOH_LOG(KERN_ERR, ++ "Receive Snapshot Count: %lu\nTransmit Snapshot Count: %lu\n", ++ ioh_1588_stats.rxMsgs, ioh_1588_stats.txMsgs); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_can_poll ( ++ * enum ioh1588PTPPort ptpPort, ++ * struct ioh1588TimeValue *ptpTimeStamp) ++ * ++ * @brief Polls the IEEE 1588 message time stamp detect status on a given ++ * CAN PTP Port. ++ * ++ * @remarks This API polls for the availability of a time stamp on a CAN ++ * port. ++ * ++ * @param ptpPort [IN] PTP port to poll ++ * @param ptpTimeStamp [OUT] Buffer to store the snapshot captured ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed ++ * @li IOH_1588_NOTIMESTAMP - No time stamp available ++ */ ++enum ioh_status ++ioh_1588_ptp_can_poll(enum ioh1588PTPPort ptpPort, \ ++ struct ioh1588TimeValue *ptpTimeStamp) ++{ ++ unsigned long valid = FALSE; ++ unsigned long overrun = FALSE; ++ ++ /* Verify the parameters for proper values */ ++ if ((ptpPort != IOH_1588_CAN_0_1588PTP_PORT) || ++ ((struct ioh1588TimeValue *) NULL == ptpTimeStamp)) { ++ IOH_DEBUG("ioh_1588_ptp_can_poll:invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Check whether a new timestamp available? */ ++ IOH_DEBUG("ioh_1588_ptp_can_poll:invoking ioh_1588_can_snap_valid\n"); ++ valid = ioh_1588_can_snap_valid(); ++ ++ /* there is not a valid timestamp */ ++ if (TRUE != valid) { ++ IOH_DEBUG("ioh_1588_ptp_can_poll:no valid timestamp\ ++ returning IOH_1588_NOTIMESTAMP\n"); ++ return IOH_1588_NOTIMESTAMP; ++ } ++ ++ /* check overrun bit before retreiving timestamp */ ++ IOH_DEBUG("ioh_1588_ptp_can_poll:invoking ioh_1588_can_snap_ovr\n"); ++ overrun = ioh_1588_can_snap_ovr(); ++ ++ /* if the timestamp has been overwritten */ ++ if (TRUE == overrun) { ++ IOH_DEBUG("ioh_1588_ptp_can_poll:overrun occured\n"); ++ /* reset valid and overrun bits */ ++ IOH_DEBUG ++ ("ioh_1588_ptp_can_poll:invoking \ ++ ioh_1588_can_snap_valid_clear\n"); ++ ioh_1588_can_snap_valid_clear(); ++ IOH_DEBUG ++ ("ioh_1588_ptp_can_poll:invoking \ ++ ioh_1588_can_snap_ovr_clear\n"); ++ ioh_1588_can_snap_ovr_clear(); ++ ++ /* return no valid timestamp available */ ++ ptpTimeStamp->timeValueLowWord = 0; ++ ptpTimeStamp->timeValueHighWord = 0; ++ ++ IOH_DEBUG ++ ("ioh_1588_ptp_can_poll:returning IOH_1588_NOTIMESTAMP\n"); ++ return IOH_1588_NOTIMESTAMP; ++ } ++ ++ /* Fetch the receive timestamp */ ++ ioh_1588_can_snap_get(&ptpTimeStamp->timeValueLowWord, ++ &ptpTimeStamp->timeValueHighWord); ++ IOH_DEBUG("ioh_1588_ptp_can_poll:timestamp-low=%lx,high=%lx\n", ++ ptpTimeStamp->timeValueLowWord, ++ ptpTimeStamp->timeValueHighWord); ++ ++ /* check overrun bit again to ensure timestamp is valid */ ++ overrun = ioh_1588_can_snap_ovr(); ++ ++ /* if the timestamp has been overwritten */ ++ if (TRUE == overrun) { ++ IOH_DEBUG("ioh_1588_ptp_can_poll:overrun occured\n"); ++ /* reset valid and overrun bits */ ++ IOH_DEBUG ++ ("ioh_1588_ptp_can_poll:invoking \ ++ ioh_1588_can_snap_valid_clear\n"); ++ ioh_1588_can_snap_valid_clear(); ++ IOH_DEBUG ++ ("ioh_1588_ptp_can_poll:invoking \ ++ ioh_1588_can_snap_ovr_clear\n"); ++ ioh_1588_can_snap_ovr_clear(); ++ ++ /* return no valid timestamp available */ ++ ptpTimeStamp->timeValueLowWord = 0; ++ ptpTimeStamp->timeValueHighWord = 0; ++ ++ IOH_DEBUG ++ ("ioh_1588_ptp_can_poll:returning IOH_1588_NOTIMESTAMP\n"); ++ return IOH_1588_NOTIMESTAMP; ++ } ++ ++ /* reset valid bit */ ++ IOH_DEBUG ++ ("ioh_1588_ptp_can_poll:invoking ioh_1588_can_snap_valid_clear\n"); ++ ioh_1588_can_snap_valid_clear(); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_handler(void) ++ * ++ * @brief Interrupt handler for the IEEE 1588 module ++ * ++ * @remarks Interrupt handler for the IEEE 1588 module ++ * The Interrupts are handled in the following order ++ * - 1 - Target Time Reached/Hit Condition ++ * - 2 - Auxiliary Master Timestamp ++ * - 3 - Auxiliary Slave Timestamp ++ * - 4 - pulse per second ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_handler(void) ++{ ++ struct ioh1588TimeValue tgt_time = { 0, 0 }; ++ struct ioh1588TimeValue aux_time = { 0, 0 }; ++ unsigned long pps; ++ ++ /* If valid callbacks are available process each interrupt */ ++ ++ /* Handle Target Time Reached or Exceeded Interrupt */ ++ if ((NULL != ioh_tt_cbptr) && (TRUE == ioh_1588_ttm_evt_get())) { ++ IOH_DEBUG ++ ("ioh_1588_handler:Target Time Reached or Exceeded \ ++ Interrupt\n"); ++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_ttm_imask_clear\ ++ to disable interrupts\n"); ++ /* Disable interrupt */ ++ ioh_1588_ttm_imask_clear(); ++ ++ /* Target Time registers contents */ ++ ioh_1588_tgt_snap_get(&tgt_time.timeValueLowWord, ++ &tgt_time.timeValueHighWord); ++ IOH_DEBUG("ioh_1588_handler:target time-low=%lx,high=%lx\n", ++ tgt_time.timeValueLowWord, ++ tgt_time.timeValueHighWord); ++ ++ IOH_DEBUG("ioh_1588_handler:invoking callback\n"); ++ /* Invoke client callback */ ++ (*ioh_tt_cbptr) (tgt_time); ++ ++ /* Clear the target time reached condition (ttipend bit) */ ++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_ttm_evt_clear\n"); ++ ioh_1588_ttm_evt_clear(); ++ } ++ ++ /* Handle Auxiliary Master Mode Snapshot Interrupt */ ++ if ((NULL != ioh_am_cbptr) && (TRUE == ioh_1588_amms_evt_get())) { ++ IOH_DEBUG ++ ("ioh_1588_handler:Auxiliary Master Mode Snapshot Interrupt\n"); ++ /* Disable interrupt */ ++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_amms_imask_clear\ ++ to disable interrupts\n"); ++ ioh_1588_amms_imask_clear(); ++ ++ /* Fetch Auxiliary Master Mode Snapshot */ ++ ioh_1588_aux_master_snap_get(&aux_time.timeValueLowWord, ++ &aux_time.timeValueHighWord); ++ IOH_DEBUG ++ ("ioh_1588_handler:Auxiliary Master Mode Snapshot-low=%lx,\ ++ high=%lx\n", ++ aux_time.timeValueLowWord, aux_time.timeValueHighWord); ++ ++ IOH_DEBUG("ioh_1588_handler:invoking callback\n"); ++ /* Return Auxiliary Master Mode Snapshot */ ++ (*ioh_am_cbptr) (IOH_1588_AUXMODE_MASTER, aux_time); ++ ++ /* Clear the snapshot availability condition */ ++ IOH_DEBUG ++ ("ioh_1588_handler:invoking ioh_1588_amms_evt_clear\n"); ++ ioh_1588_amms_evt_clear(); ++ } ++ ++ /* Handle Auxiliary Slave Mode Snapshot Interrupt */ ++ if ((NULL != ioh_as_cbptr) && (TRUE == ioh_1588_asms_evt_get())) { ++ IOH_DEBUG ++ ("ioh_1588_handler:Auxiliary Slave Mode Snapshot Interrupt\n"); ++ /* Disable interrupt */ ++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_asms_imask_clear\ ++ to disable interrupts\n"); ++ ioh_1588_asms_imask_clear(); ++ ++ /* Fetch Auxiliary Slave Mode Snapshot */ ++ ioh_1588_aux_slave_snap_get(&aux_time.timeValueLowWord, ++ &aux_time.timeValueHighWord); ++ IOH_DEBUG ++ ("ioh_1588_handler:Auxiliary Master Mode Snapshot-low=%lx,\ ++ high=%lx\n", ++ aux_time.timeValueLowWord, aux_time.timeValueHighWord); ++ ++ /* Return Auxiliary Slave Mode Snapshot */ ++ IOH_DEBUG("ioh_1588_handler:invoking callback\n"); ++ (*ioh_as_cbptr) (IOH_1588_AUXMODE_SLAVE, aux_time); ++ ++ /* Clear the snapshot availability condition */ ++ IOH_DEBUG ++ ("ioh_1588_handler:invoking ioh_1588_asms_evt_clear\n"); ++ ioh_1588_asms_evt_clear(); ++ } ++ ++ /* Handle Pulse Per Second Interrupt */ ++ if ((NULL != ioh_pps_cbptr) && (TRUE == ioh_1588_pps_evt_get())) { ++ IOH_DEBUG("ioh_1588_handler:Pulse Per Second Interrupt\n"); ++ /* Disable interrupt */ ++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_pps_imask_clear\ ++ to disable interrupts\n"); ++ ioh_1588_pps_imask_clear(); ++ ++ /* Fetch PPS compare register */ ++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_pps_get\n"); ++ ioh_1588_pps_get(&pps); ++ ++ /* Invoke the call back */ ++ IOH_DEBUG("ioh_1588_handler:invoking callback\n"); ++ (*ioh_pps_cbptr) (pps); ++ ++ /* Clear the snapshot availability condition */ ++ IOH_DEBUG("ioh_1588_handler:invoking ioh_1588_pps_evt_clear\n"); ++ ioh_1588_pps_evt_clear(); ++ ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_version_get( ++ * enum ioh1588PTPPort ptpPort, enum ioh1588PTPVersion *ptpVersion) ++ * ++ * @brief Retrieves IEEE 1588 PTP version supported on the given PTP port. ++ * ++ * @remarks This API retrieves IEEE 1588 PTP version supported on given PTP ++ * port. ++ * The main steps followed in this function are: ++ * - Return IOH_1588_INVALIDPARAM if ptpPort passed is not valid or ++ * ptpVersion passed is NULL ++ * - Ensure that the module is initialized and the port is valid ++ * - Return the PTP version that is supported from the ++ * TS_Channel_Control register, bit 31 ++ * ++ * ++ * @param ptpPort [IN] PTP port ++ * @param ptpVersion [OUT] Version supported on PTP port ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation is successful ++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed ++ */ ++enum ioh_status ++ioh_1588_ptp_version_get(enum ioh1588PTPPort ptpPort, \ ++ enum ioh1588PTPVersion *ptpVersion) ++{ ++ /* Verify the parameters for proper values */ ++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) || (ptpVersion == NULL)) { ++ IOH_DEBUG("ioh_1588_ptp_version_get:invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ IOH_DEBUG("ioh_1588_ptp_version_get:invoking ioh_1588_version_get\n"); ++ *ptpVersion = ioh_1588_version_get(); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_version_set( ++ * enum ioh1588PTPPort ptpPort, ++ * enum ioh1588PTPVersion ptpVersion) ++ * ++ * @brief Configures IEEE 1588 PTP version to be used on given PTP port. ++ * ++ * @remarks This API set the IEEE 1588 PTP version to be used on given PTP ++ * port. ++ * The main steps followed in this function are: ++ * - Validate parameter ++ * - Ensure that the module is initialized and the version ++ * requested is valid ++ * - Set the version in TS_Channel_Control register, bit 31 ++ * ++ * ++ * @param ptpPort [IN] PTP port ++ * @param ptpVersion [IN] Version to be supported on PTP port ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation is successful ++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed ++ */ ++enum ioh_status ++ioh_1588_ptp_version_set(enum ioh1588PTPPort ptpPort, \ ++ enum ioh1588PTPVersion ptpVersion) ++{ ++ /* Verify the parameters for proper values */ ++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) || ++ ((ptpVersion != IOH_1588PTP_VERSION_0) && ++ (ptpVersion != IOH_1588PTP_VERSION_1))) { ++ IOH_DEBUG("ioh_1588_ptp_version_set:invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ IOH_DEBUG("ioh_1588_ptp_version_get:invoking ioh_1588_version_set\n"); ++ ioh_1588_version_set(ptpVersion); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_operation_mode_set( ++ * enum ioh1588PTPPort ptpPort, ++ * enum ioh1588PTPOperationMode ptpMode) ++ * ++ * @brief Configure the IEEE 1588 PTP operation mode of given PTP port. ++ * ++ * @remarks This API will set the operation mode on given PTP port. ++ * The main steps followed in this function are: ++ * - Ensure that the module is initialized and the mode requested ++ * is valid ++ * - If not valid, return status IOH_1588_INVALIDPARAM ++ * - Set the requested operation mode in TS_Channel_Control ++ * register, bits 16-20 ++ * ++ * ++ * @param ptpPort [IN] PTP port to configure ++ * @param ptpMode [IN] Operation mode to be used ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Invalid parameters passed ++ */ ++enum ioh_status ++ioh_1588_ptp_operation_mode_set(enum ioh1588PTPPort ptpPort, ++ enum ioh1588PTPOperationMode ptpMode) ++{ ++ /* Verify the parameters for proper values */ ++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) || ++ ((ptpMode != IOH_1588PTP_OP_MODE_SYNC_DELAYREQ_MSGS) && ++ (ptpMode != IOH_1588PTP_OP_MODE_V1_ALL_MSGS) && ++ (ptpMode != IOH_1588PTP_OP_MODE_V1_V2_EVENT_MSGS) && ++ (ptpMode != IOH_1588PTP_OP_MODE_V1_V2_ALL_MSGS))) { ++ IOH_DEBUG("ioh_1588_ptp_operation_mode_set:invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ IOH_DEBUG("ioh_1588_ptp_version_get:invoking ioh_1588_op_mode_set\n"); ++ ioh_1588_op_mode_set(ptpMode); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_operation_mode_get( ++ * enum ioh1588PTPPort ptpPort, ++ * enum ioh1588PTPOperationMode *ptpMode) ++ * ++ * @brief Gets the current PTP operation mode of given PTP port. ++ * ++ * @remarks This API will get the operation mode of given PTP port. ++ * The main steps followed in this function are: ++ * - Ensure that the module is initialized and the port is valid ++ * - If not valid, return status IOH_1588_INVALIDPARAM ++ * - Return the PTP operation mode that is currently in use by ++ * reading the TS_Channel_Control register, bits 16-20 ++ * ++ * ++ * @param ptpPort [IN] PTP port to configure ++ * @param ptpMode [OUT] Address where PTP operation mode is ++ * returned ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Null parameter passed ++ */ ++enum ioh_status ++ioh_1588_ptp_operation_mode_get(enum ioh1588PTPPort ptpPort, ++ enum ioh1588PTPOperationMode *ptpMode) ++{ ++ /* Verify the parameters for proper values */ ++ if ((ptpPort != IOH_1588_GBE_0_1588PTP_PORT) || (ptpMode == NULL)) { ++ IOH_DEBUG("ioh_1588_ptp_operation_mode_get:invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ IOH_DEBUG ++ ("ioh_1588_ptp_operation_mode_get:invoking ioh_1588_op_mode_get\n"); ++ *ptpMode = ioh_1588_op_mode_get(); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_pulse_per_sec_interrupt_enable( ++ * ioh1588PulsePerSecondCallback callBack) ++ * ++ * @brief Enable the Pulse Per Second match interrupt ++ * ++ * @remarks This API will enable the Pulse Per Second match interrupt. ++ * This interrupt is generated when the low word of System ++ * Time matches the value in the Pulse Per Second compare ++ * register in the IEEE hardware assist block. The main steps ++ * followed in this function are: ++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL ++ * - Modify the Time Sync Controller register to enable the ++ * interrupt ++ * - Set the callback routine ++ * ++ * @param callBack [IN] Routine to be invoked when interrupt ++ * fires ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Null parameter passed ++ */ ++enum ioh_status ++ioh_1588_pulse_per_sec_interrupt_enable(ioh1588PulsePerSecondCallback callBack) ++{ ++ /* Verify the parameter */ ++ if ((ioh1588PulsePerSecondCallback) NULL == callBack) { ++ IOH_DEBUG ++ ("ioh_1588_pulse_per_sec_interrupt_enable:invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Register the Callback */ ++ ioh_pps_cbptr = callBack; ++ ++ /* Set target time interrupt mask */ ++ IOH_DEBUG("ioh_1588_pulse_per_sec_interrupt_enable:invoking \ ++ ioh_1588_pps_imask_set\n"); ++ ioh_1588_pps_imask_set(); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_pulse_per_sec_interrupt_disable(void) ++ * ++ * @brief Disable the Pulse Per Second match interrupt ++ * ++ * @remarks This API will disable the Pulse Per Second match interrupt. ++ * This interrupt is generated when the low word of System ++ * Time matches the value in the Pulse Per Second compare ++ * register in the IEEE hardware assist block. The main ++ * steps followed in this function are: ++ * - Modify the Time Sync Controller register to disable the ++ * interrupt ++ * - Clear the callback routine ++ * ++ * @param None ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_pulse_per_sec_interrupt_disable(void) ++{ ++ /* Clear pulse per second interrupt mask */ ++ IOH_DEBUG("ioh_1588_pulse_per_sec_interrupt_disable:invoking \ ++ ioh_1588_pps_imask_clear\n"); ++ ioh_1588_pps_imask_clear(); ++ ++ /* Unregister the Callback */ ++ ioh_pps_cbptr = (ioh1588PulsePerSecondCallback) NULL; ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_pulse_per_sec_time_set(unsigned long ++ * ppsTime) ++ * ++ * @brief Sets the Pulse Per Second match time in the IEEE 1588 hardware ++ * assist block ++ * ++ * @remarks This API will set the PPS match register with the value supplied ++ * The main steps followed in this function are: ++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL ++ * - Set the time in PPS Compare Register ++ * ++ * ++ * @param ppsTime [IN] Value to be stored in pps match register ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation is successful ++ * @li IOH_1588_INVALIDPARAM - Null parameter passed ++ */ ++enum ioh_status ioh_1588_pulse_per_sec_time_set(unsigned long ppsTime) ++{ ++ unsigned long old_mask = FALSE; ++ ++ /* Retrieve existing pps mask value */ ++ old_mask = ioh_1588_pps_imask_get(); ++ IOH_DEBUG ++ ("ioh_1588_pulse_per_sec_time_set:target time interrupt mask=%lx\n", ++ old_mask); ++ ++ /* ++ * Clear the pps time interrupt mask so that the interrupt will not come ++ * during the time we manipulate the registers. ++ */ ++ IOH_DEBUG ++ ("ioh_1588_pulse_per_sec_time_set:invoking ioh_1588_pps_imask_clear\ ++ to clear the pps interrupt mask\n"); ++ ioh_1588_pps_imask_clear(); ++ ++ /* Update the PPS time */ ++ IOH_DEBUG ++ ("ioh_1588_pulse_per_sec_time_set:invoking ioh_1588_pps_set\n"); ++ ++ ioh_1588_pps_set(ppsTime); ++ ++ /* ++ * Let the hardware assist re-evaluate the pps reached ++ * condition based on the new pps value ++ */ ++ IOH_DEBUG ++ ("ioh_1588_pulse_per_sec_time_set:invoking ioh_1588_pps_evt_clear\n"); ++ ioh_1588_pps_evt_clear(); ++ ++ /* Restore the preserved pps interrupt mask value */ ++ if (TRUE == old_mask) { ++ IOH_DEBUG ++ ("ioh_1588_pulse_per_sec_time_set:invoking \ ++ ioh_1588_pps_imask_set\n"); ++ ioh_1588_pps_imask_set(); ++ } ++ ++ IOH_DEBUG ++ ("ioh_1588_pulse_per_sec_time_set:returning IOH_1588_SUCCESS\n"); ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_pulse_per_sec_time_get( ++ * unsigned long *ppsTime) ++ * ++ * @brief Gets the Pulse Per Second match time from the IEEE 1588 hardware ++ * assist block ++ * ++ * @remarks This API will get the PPS match register content ++ * from IEEE 1588 block. The main steps followed in this ++ * function are: ++ * - Return IOH_1588_INVALIDPARAM if argument passed is NULL ++ * - Return the time from PPS compare register ++ * ++ * ++ * @param ppsTime [OUT] Buffer for returning the pps match value ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Null parameter passed ++ */ ++enum ioh_status ioh_1588_pulse_per_sec_time_get(unsigned long *ppsTime) ++{ ++ /* Verify the parameter */ ++ if ((unsigned long *)NULL == ppsTime) { ++ IOH_DEBUG("ioh_1588_pulse_per_sec_time_get:invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Retrieve PPS Value */ ++ IOH_DEBUG ++ ("ioh_1588_pulse_per_sec_time_get:invoking ioh_1588_pps_get\n"); ++ ioh_1588_pps_get(ppsTime); ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_eth_enable(void) ++ * ++ * @brief Sets the eth_enb bit (bit 0) of Ethernet-CAN Select Register ++ * @remarks This API enables the IEEE 1588 hardware time stamping of PTP ++ * traffic ++ * on the Ethernet interface ++ * ++ * @param None ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_eth_enable(void) ++{ ++ if (ioh_1588_base != 0) { ++ IOH_DEBUG ++ ("ioh_1588_eth_enable:invoking ioh_1588_eth_enable_set\n"); ++ ioh_1588_eth_enable_set(); ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_eth_disable(void) ++ * ++ * @brief Clears the eth_enb bit (bit 0) of Ethernet-CAN Select Register ++ * @remarks This API disables the IEEE 1588 hardware time stamping of PTP ++ * traffic ++ * on the Ethernet interface ++ * ++ * @param None ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_eth_disable(void) ++{ ++ if (ioh_1588_base != 0) { ++ IOH_DEBUG ++ ("ioh_1588_eth_disable:invoking ioh_1588_eth_enable_clear\n"); ++ ioh_1588_eth_enable_clear(); ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_can_enable(void) ++ * ++ * @brief Sets the can_enb bit (bit 1) of Ethernet-CAN Select Register ++ * @remraks This API enables the IEEE 1588 hardware time stamping of PTP ++ * traffic ++ * on the CAN interface ++ * ++ * @param None ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_can_enable(void) ++{ ++ if (ioh_1588_base != 0) { ++ IOH_DEBUG ++ ("ioh_1588_can_enable:invoking ioh_1588_can_enable_set\n"); ++ ioh_1588_can_enable_set(); ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_can_disable(void) ++ * ++ * @brief Clear the can_enb bit (bit 1) of Ethernet-CAN Select Register ++ * @remarks This API disables the IEEE 1588 hardware time stamping of PTP ++ * traffic ++ * on the CAN interface ++ * ++ * @param None ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ */ ++enum ioh_status ioh_1588_can_disable(void) ++{ ++ if (ioh_1588_base != 0) { ++ IOH_DEBUG ++ ("ioh_1588_can_disable:invoking ioh_1588_can_enable_clear\n"); ++ ioh_1588_can_enable_clear(); ++ } ++ ++ return IOH_1588_SUCCESS; ++} ++ ++/** ++ * @ingroup IEEE_1588_UtilitiesAPI ++ * @fn static int get_decimal(unsigned char ch) ++ * ++ * @brief Returns the decimal value of the passed ++ * hexadecimal value. ++ * ++ * @note Returns -1 if the passed arguement is invalid. ++ * ++ * @param ch [IN] The hexadecimal value that has to be converted. ++ * ++ * @retval int ++ * - On Success --> decimal Value ++ * - Invalid value --> -1 ++ */ ++static int get_decimal(unsigned char ch) ++{ ++ int ret; ++ ++ if ((ch >= '0') && (ch <= '9')) { ++ ret = ch - '0'; ++ return ret; ++ } else if ((ch >= 'A') && (ch <= 'F')) { ++ ret = 10 + ch - 'A'; ++ return ret; ++ } else if ((ch >= 'a') && (ch <= 'f')) { ++ ret = 10 + ch - 'a'; ++ return ret; ++ } ++ ++ return -1; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_set_station_address ( ++ * unsigned char *addr) ++ * ++ * @brief This API sets the station address used by IEEE 1588 hardware ++ * when looking ++ * at PTP traffic on the ethernet interface ++ * ++ * @param addr [IN] Address which contain the column separated ++ * address to be used ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Invalid address string ++ */ ++enum ioh_status ioh_1588_set_station_address(unsigned char *addr) ++{ ++ int i; ++ ++ /* Verify the parameter */ ++ if ((ioh_1588_base == 0) || (unsigned char *)NULL == addr) { ++ IOH_DEBUG("ioh_1588_set_station_address :invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) { /* For all station ++ address bytes */ ++ unsigned long val = 0; ++ int tmp; ++ ++ tmp = get_decimal(addr[i * 3]); ++ if (tmp < 0) { ++ IOH_DEBUG("ioh_1588_set_station_address :invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ val = tmp * 16; ++ tmp = get_decimal(addr[(i * 3) + 1]); ++ if (tmp < 0) { ++ IOH_DEBUG("ioh_1588_set_station_address :invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ val += tmp; ++ if ((i < 5) && (addr[(i * 3) + 2] != ':')) { /* Expects ':' ++ separated addresses */ ++ IOH_DEBUG("ioh_1588_set_station_address :invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ /* Ideally we should set the address only after validating ++ entire string */ ++ IOH_DEBUG ++ ("ioh_1588_set_station_address \ ++ :invoking ioh_1588_station_set\n"); ++ ioh_1588_station_set(i, val); ++ } ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_get_station_address(char *addr) ++ * @brief This API gets the station address currently used by IEEE 1588 ++ * hardware when looking at PTP traffic on the ethernet interface ++ * ++ * @param addr [OUT] Buffer to which column separated address is ++ * returned ++ * @retval enum ioh_status ++ * @li IOH_1588_SUCCESS - Operation successful ++ * @li IOH_1588_INVALIDPARAM - Null parameter passed ++ */ ++enum ioh_status ioh_1588_get_station_address(char *addr) ++{ ++ int i; ++ ++ /* Verify the parameter */ ++ if ((char *)NULL == addr) { ++ IOH_DEBUG("ioh_1588_get_station_address:invalid params\ ++ returning IOH_1588_INVALIDPARAM\n"); ++ return IOH_1588_INVALIDPARAM; ++ } ++ ++ for (i = 0; i < IOH_1588_STATION_BYTES; i++) { ++ unsigned long val = 0; ++ ++ ioh_1588_station_get(i, &val); ++ addr[i * 3] = val / 16; ++ if (addr[i * 3] > 9) ++ addr[i * 3] += 'a' - 10; ++ else ++ addr[i * 3] += '0'; ++ addr[i * 3 + 1] = val % 16; ++ if (addr[i * 3 + 1] > 9) ++ addr[i * 3 + 1] += 'a' - 10; ++ else ++ addr[i * 3 + 1] += '0'; ++ addr[i * 3 + 2] = ':'; ++ } ++ addr[17] = '\0'; ++ return IOH_1588_SUCCESS; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_target_time_interrupt_enable( ++ * void *callBack) ++ * ++ * @brief This API just returns an error. ++ * ++ * @remarks This API is just for compatibility. It just returns an error. ++ * ++ * @param callBack [IN] Callback to be invoked when interrupt ++ * fires ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_UNSUPPORTED - Operation is not supported ++ */ ++enum ioh_status ioh_1588_aux_target_time_interrupt_enable(void *callBack) ++{ ++ IOH_DEBUG("ioh_1588_aux_target_time_interrupt_enable:unsupported\n"); ++ return IOH_1588_UNSUPPORTED; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_target_time_interrupt_disable(void) ++ * ++ * @brief This API just returns an error. ++ * ++ * @remarks This API is just for compatibility. It just returns an error. ++ * ++ * @param None ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_UNSUPPORTED - Operation is not supported ++ */ ++enum ioh_status ioh_1588_aux_target_time_interrupt_disable(void) ++{ ++ IOH_DEBUG("ioh_1588_aux_target_time_interrupt_disable:unsupported\n"); ++ return IOH_1588_UNSUPPORTED; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_target_time_poll( ++ * unsigned long *attmPollFlag, ++ * struct ioh1588TimeValue *targetTime) ++ * ++ * @brief This API just returns an error. ++ * ++ * @remarks This API is just for compatibility. It just returns an error. ++ * ++ * @param attmPollFlag [OUT] Flag returning the availablity of a ++ * snapshot ++ * @param targetTime [OUT] Snapshot captured ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_UNSUPPORTED - Operation supported ++ */ ++enum ioh_status ++ioh_1588_aux_target_time_poll(unsigned long *attmPollFlag, ++ struct ioh1588TimeValue *targetTime) ++{ ++ IOH_DEBUG("ioh_1588_aux_target_time_poll:unsupported\n"); ++ return IOH_1588_UNSUPPORTED; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_target_time_set( ++ * struct ioh1588TimeValue targetTime) ++ * ++ * @brief This API just returns an error. ++ * ++ * @remarks This API is just for compatibility. It just returns an error. ++ * ++ * @param targetTime [IN] Time to set to ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_UNSUPPORTED - Operation supported ++ */ ++enum ioh_status ioh_1588_aux_target_time_set(struct ioh1588TimeValue targetTime) ++{ ++ IOH_DEBUG("ioh_1588_aux_target_time_set:unsupported\n"); ++ return IOH_1588_UNSUPPORTED; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_target_time_get( ++ * struct ioh1588TimeValue *targetTime) ++ * ++ * @brief This API just returns an error. ++ * ++ * @remarks This API is just for compatibility. It just returns an error. ++ * ++ * @param targetTime [OUT] Buffer for returning time snapshot ++ * ++ * ++ * @retval enum ioh_status ++ * @li IOH_1588_UNSUPPORTED - Operation supported ++ */ ++enum ioh_status ioh_1588_aux_target_time_get( ++ struct ioh1588TimeValue *targetTime) ++{ ++ IOH_DEBUG("ioh_1588_aux_target_time_get:unsupported\n"); ++ return IOH_1588_UNSUPPORTED; ++} ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * ++ * @fn int ioh_1588_eth_can_get(void) ++ * ++ * @brief This function returns the modes [ethernet/CAN] enabled ++ * ++ * @retval int ++ * - the modes enabled ++ */ ++int ioh_1588_eth_can_get(void) ++{ ++ int ieee_mode = 0; ++ ++ if (ioh_1588_eth_enable_get() == 1) ++ ieee_mode |= IOH_IEEE1588_ETH; ++ if (ioh_1588_can_enable_get() == 1) ++ ieee_mode |= IOH_IEEE1588_CAN; ++ ++ return ieee_mode; ++} ++ ++#ifdef IOH_IEEE1588_A0_A1_SAMPLE_BUG ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * ++ * @fn void ioh_1588_set_system_time_count(void) ++ * ++ * @brief This function enables all 64 bits in system time registers ++ * [high & low]. This is a work-around for non continuous value ++ * in the SystemTime Register ++ * ++ * @retval none ++ */ ++void ioh_1588_set_system_time_count(void) ++{ ++ IOH_REG_32_WRITE((ioh_1588_base + 0xC0), 0x1); ++ IOH_REG_32_WRITE((ioh_1588_base + 0xC4), 0xFFFFFFFF); ++ IOH_REG_32_WRITE((ioh_1588_base + 0xC0), 0x0); ++} ++#endif +diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.h topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.h +--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.h 1970-01-01 09:00:00.000000000 +0900 ++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_hal.h 2010-03-09 07:40:00.000000000 +0900 +@@ -0,0 +1,885 @@ ++ /*! ++ * @file ioh_1588_hal.h ++ * @brief ++ * This file lists the declarations of IEEE_1588_HALLayer APIs. ++ * @version 0.92 ++ * @section ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * History: ++ * modified to support Intel IOH GE IEEE 1588 hardware ++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. ++ * All rights reserved. ++ * derived from ++ * IEEE 1588 Time Synchronization Driver for Intel EP80579 ++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ */ ++ ++#ifndef IOH_1588_HAL_H ++#define IOH_1588_HAL_H ++ ++#include "pch_1588_main.h" ++ ++/* IOH 1588 Hardware Assist Module Register offsets */ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSC_OFFSET ++@brief TS Control Register Offset ++*/ ++#define IOH_1588_TSC_OFFSET (0x00) /* TS_Control */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSE_OFFSET ++@brief TS Event Register Offset ++*/ ++#define IOH_1588_TSE_OFFSET (0x04) /* TS_Event */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_ADD_OFFSET ++@brief TS Addend Register Offset ++*/ ++#define IOH_1588_ADD_OFFSET (0x08) /* TS_Addend */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_ACC_OFFSET ++@brief TS Accumulator Register Offset ++*/ ++#define IOH_1588_ACC_OFFSET (0x0C) /* TS_Accum */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TST_OFFSET ++@brief TS Test Register Offset ++*/ ++#define IOH_1588_TST_OFFSET (0x10) /* TS_Test */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_PPS_OFFSET ++@brief TS PPS Compare Register Offset ++*/ ++#define IOH_1588_PPS_OFFSET (0x14) /* TS_PPS_Compare */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_STL_OFFSET ++@brief TS System Time Low Register Offset ++*/ ++#define IOH_1588_STL_OFFSET (0x20) /* TS_SysTimeLo */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_STH_OFFSET ++@brief TS System Time High Register Offset ++*/ ++#define IOH_1588_STH_OFFSET (0x24) /* TS_SysTimeHi */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TTL_OFFSET ++@brief TS Target Time Low Register Offset ++*/ ++#define IOH_1588_TTL_OFFSET (0x28) /* TS_TrgtLo */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TTH_OFFSET ++@brief TS Target Time High Register Offset ++*/ ++#define IOH_1588_TTH_OFFSET (0x2c) /* TS_TrgtHi */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_ASSL_OFFSET ++@brief TS Aux Slave Mode Snapshot Low Register Offset ++*/ ++#define IOH_1588_ASSL_OFFSET (0x30) /* TS_ASMSLo */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_ASSH_OFFSET ++@brief TS Aux Slave Mode Snapshot High Register Offset ++*/ ++#define IOH_1588_ASSH_OFFSET (0x34) /* TS_ASMSHi */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_ASSH_OFFSET ++@brief TS Aux Master Mode Snapshot Low Register Offset ++*/ ++#define IOH_1588_AMSL_OFFSET (0x38) /* TS_AMMSLo */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_AMSH_OFFSET ++@brief TS Aux Master Mode Snapshot High Register Offset ++*/ ++#define IOH_1588_AMSH_OFFSET (0x3C) /* TS_AMMSHi */ ++ ++/* Ethernet */ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CC_OFFSET ++@brief TS Channel Control Register Offset ++*/ ++#define IOH_1588_CC_OFFSET (0x40) /* TS_Ch_Contr */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CE_OFFSET ++@brief TS Channel Event Register Offset ++*/ ++#define IOH_1588_CE_OFFSET (0x44) /* TS_Ch_Event */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_XSL_OFFSET ++@brief TS Tx Snapshot Low Register Offset ++*/ ++#define IOH_1588_XSL_OFFSET (0x48) /* TS_TxSnapLo */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_XSH_OFFSET ++@brief TS Tx Snapshot High Register Offset ++*/ ++#define IOH_1588_XSH_OFFSET (0x4C) /* TS_TxSnapHi */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_RSL_OFFSET ++@brief TS Rx Snapshot Low Register Offset ++*/ ++#define IOH_1588_RSL_OFFSET (0x50) /* TS_RxSnapLo */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_RSH_OFFSET ++@brief TS Rx Snapshot High Register Offset ++*/ ++#define IOH_1588_RSH_OFFSET (0x54) /* TS_RxSnapHi */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_UID_OFFSET ++@brief TS Source UUID Low Register Offset ++*/ ++#define IOH_1588_UID_OFFSET (0x58) /* TS_SrcUUID */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_SID_OFFSET ++@brief TS Source UUID High/SequenceID Register Offset ++*/ ++#define IOH_1588_SID_OFFSET (0x5C) /* TS_SrcUUID */ ++ ++/* CAN */ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CCE_OFFSET ++@brief TS CAN Channel Status Register Offset ++*/ ++#define IOH_1588_CCE_OFFSET (0x60) /* TS_CAN_Stat */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CXSL_OFFSET ++@brief TS CAN Snapshot Low Register Offset ++*/ ++#define IOH_1588_CXSL_OFFSET (0x64) /* TS_CAN_Snap */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CXSH_OFFSET ++@brief TS CAN Snapshot High Register Offset ++*/ ++#define IOH_1588_CXSH_OFFSET (0x68) /* TS_CAN_Snap */ ++ ++/* Selector */ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_ECS_OFFSET ++@brief TS Ethernet/CAN Select Register Offset ++*/ ++#define IOH_1588_ECS_OFFSET (0x6c) /* TS_SEL */ ++ ++/* Station Address 1-6 */ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_STA_OFFSET ++@brief TS Station Address Register Offset ++*/ ++#define IOH_1588_STA_OFFSET (0x70) /* TS_ST1 */ ++ ++/* Bit Masks of Control Register */ ++/* Hardware Assist Reset */ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSC_RESET_SHIFT ++@brief Reset Bit position in Control Register ++*/ ++#define IOH_1588_TSC_RESET_SHIFT 0 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSC_RESET ++@brief Bit Maks for Reset Bit in Control Register ++*/ ++#define IOH_1588_TSC_RESET (1 << IOH_1588_TSC_RESET_SHIFT) ++ ++/* Target Time Interrupt Mask */ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSC_TIM_SHIFT ++@brief Bit position of Target Time Interrupt Bit in Control ++ Register ++*/ ++#define IOH_1588_TSC_TTM_SHIFT 1 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSC_TIM_MASK ++@brief Bit Mask for Target Time Interrupt in Control Register ++*/ ++#define IOH_1588_TSC_TTM_MASK (1 << IOH_1588_TSC_TTM_SHIFT) ++ ++/* Auxiliary Slave Mode snapshot Interrupt Mask */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSC_ASMS_SHIFT ++@brief Bit position of Aux Slave Mode snapshot ++ Interrupt in Control Register ++*/ ++#define IOH_1588_TSC_ASMS_SHIFT 2 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSC_ASMS_MASK ++@brief Bit Mask for Aux Slave Mode snapshot ++ Interrupt in Control Register ++*/ ++#define IOH_1588_TSC_ASMS_MASK (1 << IOH_1588_TSC_ASMS_SHIFT) ++ ++/* Auxiliary Master Mode snapshot Interrupt Mask */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSC_AMMS_SHIFT ++@brief Bit position for for Aux Master Mode snapshot ++ Interrupt in Control Register ++*/ ++#define IOH_1588_TSC_AMMS_SHIFT 3 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSC_AMMS_MASK ++@brief Bit mask for for Aux Master Mode snapshot ++ Interrupt in Control Register ++*/ ++#define IOH_1588_TSC_AMMS_MASK (1 << IOH_1588_TSC_AMMS_SHIFT) ++ ++/* Pulse Per Second Interrupt Mask */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSC_PPSM_SHIFT ++@brief Bit position of Pulse Per Second ++ Interrupt in Control Register ++*/ ++#define IOH_1588_TSC_PPSM_SHIFT 4 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSC_PPSM_MASK ++@brief Bit mask of Pulse Per Second ++ Interrupt in Control Register ++*/ ++#define IOH_1588_TSC_PPSM_MASK (1 << IOH_1588_TSC_PPSM_SHIFT) ++ ++/* Bit Masks of Event Register */ ++/* Target Time Interrupt Pending Event */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSE_TTIPEND_SHIFT ++@brief Bit position of Target Time Interrupt ++ Pending in Event Register ++*/ ++#define IOH_1588_TSE_TTIPEND_SHIFT 1 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSE_TTIPEND ++@brief Bit mask of Target Time Interrupt ++ Pending in Event Register ++*/ ++#define IOH_1588_TSE_TTIPEND (1 << IOH_1588_TSE_TTIPEND_SHIFT) ++ ++/* Auxiliary Slave Mode snapshot Event */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSE_SNS_SHIFT ++@brief Bit position of Aux Slave Mode snapshot ++ in Event Register ++*/ ++#define IOH_1588_TSE_SNS_SHIFT 2 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSE_SNS ++@brief Bit mask of Aux Slave Mode snapshot ++ in Event Register ++*/ ++#define IOH_1588_TSE_SNS (1 << IOH_1588_TSE_SNS_SHIFT) ++ ++/* Auxiliary Master Mode snapshot Event */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSE_SNM_SHIFT ++@brief Bit position of Aux Master Mode snapshot ++ in Event Register ++*/ ++#define IOH_1588_TSE_SNM_SHIFT 3 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSE_SNM ++@brief Bit mask of Aux Master Mode snapshot ++ in Event Register ++*/ ++#define IOH_1588_TSE_SNM (1 << IOH_1588_TSE_SNM_SHIFT) ++ ++/* Pulse Per Second Match */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSE_PPS_SHIFT ++@brief Bit position of Pusle Per Second Match ++ in Event Register ++*/ ++#define IOH_1588_TSE_PPS_SHIFT 4 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_TSE_PPS ++@brief Bit mask of Pusle Per Second Match ++ in Event Register ++*/ ++#define IOH_1588_TSE_PPS (1 << IOH_1588_TSE_PPS_SHIFT) ++ ++/* Bit Masks of Channel Control Register */ ++/* Timestamp Master or Slave Mode Control Flag */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CC_MM_SHIFT ++@brief Bit position of Timestamp Master/Slave Mode ++ in Channel Control Register ++*/ ++#define IOH_1588_CC_MM_SHIFT 0 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CC_MM ++@brief Bit mask of Timestamp Master/Slave Mode ++ control flag in ++ in Channel Control Register ++*/ ++#define IOH_1588_CC_MM (1 << IOH_1588_CC_MM_SHIFT) ++ ++/* Timestamp All Messages Control Flag */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CC_TA_SHIFT ++@brief Bit position of Timestamp all messages ++ Mode control flag ++ in Channel Control Register ++*/ ++#define IOH_1588_CC_TA_SHIFT 1 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CC_TA ++@brief Bit mask of Timestamp all messages ++ Mode control flag ++ in Channel Control Register ++*/ ++#define IOH_1588_CC_TA (1 << IOH_1588_CC_TA_SHIFT) ++ ++/* Mode bits */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CC_MODE_SHIFT ++@brief Bit position of mode bits ++ in Channel Control Register ++*/ ++#define IOH_1588_CC_MODE_SHIFT 16 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CC_MODE_MASK ++@brief Bit mask for mode bits ++ in Channel Control Register ++*/ ++#define IOH_1588_CC_MODE_MASK (0x001F0000) ++ ++/* Version bit */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CC_VERSION_SHIFT ++@brief Bit position for version bits ++ in Channel Control Register ++*/ ++#define IOH_1588_CC_VERSION_SHIFT 31 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CC_VERSION ++@brief Bit mask for version bits ++ in Channel Control Register ++*/ ++#define IOH_1588_CC_VERSION (1 << IOH_1588_CC_VERSION_SHIFT) ++ ++/* Bit Masks of Channel Event Register */ ++/* Transmit Snapshot Locked Indicator Flag */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CE_TXS ++@brief Bit mask for Transmit Snapshot Locked bit ++ in Channel Event Register ++*/ ++#define IOH_1588_CE_TXS (1 << 0) ++ ++/* Receive Snapshot Locked Indicator Flag */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CE_TXS ++@brief Bit mask for Receive Snapshot Locked bit ++ in Channel Event Register ++*/ ++#define IOH_1588_CE_RXS (1 << 1) ++ ++/* Bit Masks of CAN Channel Event Register */ ++/* Overrun Indicator Flag */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CE_OVR ++@brief Bit mask for Overrun Indicator bit ++ in Channel Event Register ++*/ ++#define IOH_1588_CE_OVR (1 << 0) ++ ++/* Valid Indicator Flag */ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_CE_VAL ++@brief Bit mask for Valid Indicator bit ++ in Channel Event Register ++*/ ++#define IOH_1588_CE_VAL (1 << 1) ++ ++/* Ethernet Enable bit */ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_ECS_ETH_SHIFT ++@brief Bit position for Ethernet Enable bit ++ in Ethernet/CAN select Register ++*/ ++#define IOH_1588_ECS_ETH_SHIFT 0 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_ECS_ETH ++@brief Bit mask for Ethernet Enable bit ++ in Ethernet/CAN select Register ++*/ ++#define IOH_1588_ECS_ETH (1 << IOH_1588_ECS_ETH_SHIFT) ++/* Can Enable bit */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_ECS_CAN_SHIFT ++@brief Bit position for CAN Enable bit ++ in Ethernet/CAN select Register ++*/ ++#define IOH_1588_ECS_CAN_SHIFT 1 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_ECS_CAN ++@brief Bit mask for CAN Enable bit ++ in Ethernet/CAN select Register ++*/ ++#define IOH_1588_ECS_CAN (1 << IOH_1588_ECS_CAN_SHIFT) ++ ++/* Station Address bytes */ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def IOH_1588_STATION_BYTES ++@brief Bytes for Station Address ++*/ ++#define IOH_1588_STATION_BYTES 6 ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@def DRIVER_NAME ++@brief The name of this driver ++*/ ++#define DRIVER_NAME "ioh_ieee1588" ++ ++#define IOH_IEEE1588_ETH (1 << 0) ++#define IOH_IEEE1588_CAN (1 << 1) ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@typedef typedef void (*ioh1588TargetTimeCallback) ++ (struct ioh1588TimeValue tgt_time) ++@brief Pointer for Callback function for Target Time interrupt ++@see ++ - ioh_1588_blpl_base_address_set ++ - ioh_1588_target_time_interrupt_enable ++ - ioh_1588_target_time_interrupt_disable ++ - ioh_1588_target_time_poll ++ - ioh_1588_reset ++*/ ++typedef void (*ioh1588TargetTimeCallback) (struct ioh1588TimeValue tgt_time); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@typedef typedef void (*ioh1588AuxTimeCallback) ++ (enum ioh1588AuxMode aux_mode, ++ struct ioh1588TimeValue aux_time) ++@brief Pointer for Callback function for Aux Time interrupt ++@see ++ - ioh_1588_blpl_base_address_set ++ - ioh_1588_aux_time_interrupt_enable ++ - ioh_1588_aux_time_interrupt_disable ++ - ioh_1588_aux_time_poll ++ - ioh_1588_reset ++*/ ++typedef void (*ioh1588AuxTimeCallback) (enum ioh1588AuxMode aux_mode, ++ struct ioh1588TimeValue aux_time); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++@typedef typedef void (*ioh1588PulsePerSecondCallback)( ++ unsigned long pps) ++@brief Pointer for Callback function for Pulse Per Second ++ interrupt ++@see ++ - ioh_1588_blpl_base_address_set ++ - ioh_1588_pulse_per_sec_interrupt_enable ++ - ioh_1588_pulse_per_sec_interrupt_disable ++ - ioh_1588_reset ++*/ ++typedef void (*ioh1588PulsePerSecondCallback) (unsigned long pps); ++ ++/** ++ * prototypes of HAL APIs ++ */ ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_blpl_base_address_set(unsigned long base_addr) ++ */ ++enum ioh_status ioh_1588_blpl_base_address_set(unsigned long base_addr); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_port_config_set( ++ * enum ioh1588PTPPort ptpPort, ++ * enum ioh1588PTPPortMode ptpPortMode) ++ */ ++enum ioh_status ++ioh_1588_ptp_port_config_set(enum ioh1588PTPPort ptpPort, ++ enum ioh1588PTPPortMode ptpPortMode); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_port_config_get( ++ * enum ioh1588PTPPort ptpPort, ++ * enum ioh1588PTPPortMode *ptpPortMode) ++ */ ++enum ioh_status ++ioh_1588_ptp_port_config_get(enum ioh1588PTPPort ptpPort, ++ enum ioh1588PTPPortMode *ptpPortMode); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_rx_poll( ++ * enum ioh1588PTPPort ptpPort, ++ * struct ioh1588PtpMsgData *ptpMsgData) ++ * ++ * ++ */ ++enum ioh_status ++ioh_1588_ptp_rx_poll( ++ enum ioh1588PTPPort ptpPort, \ ++ struct ioh1588PtpMsgData *ptpMsgData); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_tx_poll( ++ * enum ioh1588PTPPort ptpPort, ++ * struct ioh1588PtpMsgData *ptpMsgData) ++ * ++ */ ++enum ioh_status ++ioh_1588_ptp_tx_poll( ++ enum ioh1588PTPPort ptpPort, \ ++ struct ioh1588PtpMsgData *ptpMsgData); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_system_time_set( ++ * struct ioh1588TimeValue systemTime) ++ * ++ */ ++enum ioh_status ioh_1588_system_time_set(struct ioh1588TimeValue systemTime); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_system_time_get( ++ * struct ioh1588TimeValue *systemTime) ++ * ++ */ ++enum ioh_status ioh_1588_system_time_get(struct ioh1588TimeValue *systemTime); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_tick_rate_set(unsigned long tickRate) ++ * ++ */ ++enum ioh_status ioh_1588_tick_rate_set(unsigned long tickRate); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_tick_rate_get(unsigned long *tickRate) ++ * ++ */ ++enum ioh_status ioh_1588_tick_rate_get(unsigned long *tickRate); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_target_time_interrupt_enable( ++ * ioh1588TargetTimeCallback callBack) ++ * ++ */ ++enum ioh_status ++ioh_1588_target_time_interrupt_enable(ioh1588TargetTimeCallback callBack); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_target_time_interrupt_disable(void) ++ * ++ */ ++enum ioh_status ioh_1588_target_time_interrupt_disable(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_target_time_poll( ++ * unsigned long *ttmPollFlag, ++ * struct ioh1588TimeValue *targetTime) ++ * ++ */ ++enum ioh_status ++ioh_1588_target_time_poll(unsigned long *ttmPollFlag, ++ struct ioh1588TimeValue *targetTime); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_target_time_set( ++ * struct ioh1588TimeValue targetTime) ++ * ++ */ ++enum ioh_status ioh_1588_target_time_set(struct ioh1588TimeValue targetTime); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_target_time_get( ++ * struct ioh1588TimeValue *targetTime) ++ * ++ */ ++enum ioh_status ioh_1588_target_time_get(struct ioh1588TimeValue *targetTime); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_time_interrupt_enable( ++ enum ioh1588AuxMode auxMode, ++ * ioh1588AuxTimeCallback callBack) ++ * ++ */ ++enum ioh_status ++ioh_1588_aux_time_interrupt_enable(enum ioh1588AuxMode auxMode, ++ ioh1588AuxTimeCallback callBack); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_time_interrupt_disable( ++ enum ioh1588AuxMode auxMode) ++ * ++ */ ++enum ioh_status ioh_1588_aux_time_interrupt_disable( ++ enum ioh1588AuxMode auxMode); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_time_poll( ++ * enum ioh1588AuxMode auxMode, ++ * unsigned long *pollFlag, ++ * struct ioh1588TimeValue *auxTime) ++ * ++ */ ++enum ioh_status ++ioh_1588_aux_time_poll(enum ioh1588AuxMode auxMode, ++ unsigned long *pollFlag, ++ struct ioh1588TimeValue *auxTime); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_reset(void) ++ * ++ */ ++enum ioh_status ioh_1588_reset(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_chnl_reset(enum ioh1588PTPPort ptpPort) ++ * ++ */ ++enum ioh_status ioh_1588_chnl_reset(enum ioh1588PTPPort ptpPort); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_stats_get(struct ioh1588Stats *stats) ++ * ++ */ ++enum ioh_status ioh_1588_stats_get(struct ioh1588Stats *stats); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn void ioh_1588_stats_reset(void) ++ * ++ */ ++void ioh_1588_stats_reset(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn void ioh_1588_show(void) ++ * ++ */ ++enum ioh_status ioh_1588_show(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_pulse_per_sec_interrupt_enable( ++ * ioh1588PulsePerSecondCallback callBack) ++ * ++ */ ++enum ioh_status ++ioh_1588_pulse_per_sec_interrupt_enable(ioh1588PulsePerSecondCallback callBack); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_pulse_per_sec_interrupt_disable(void) ++ * ++ */ ++enum ioh_status ioh_1588_pulse_per_sec_interrupt_disable(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_pulse_per_sec_time_get(unsigned long *ppsTime) ++ * ++ */ ++enum ioh_status ioh_1588_pulse_per_sec_time_get(unsigned long *ppsTime); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_pulse_per_sec_time_set(unsigned long ppsTime) ++ * ++ */ ++enum ioh_status ioh_1588_pulse_per_sec_time_set(unsigned long ppsTime); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_can_poll ( ++ * enum ioh1588PTPPort ptpPort, ++ * struct ioh1588TimeValue *ptpTimeStamp) ++ * ++ */ ++enum ioh_status ioh_1588_ptp_can_poll(enum ioh1588PTPPort ptpPort, ++ struct ioh1588TimeValue *ptpTimeStamp); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_version_get(enum ioh1588PTPPort ptpPort, ++ * enum ioh1588PTPVersion *ptpVersion) ++ * ++ */ ++enum ioh_status ++ioh_1588_ptp_version_get(enum ioh1588PTPPort ptpPort, ++ enum ioh1588PTPVersion *ptpVersion); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_version_set(enum ioh1588PTPPort ptpPort, ++ * enum ioh1588PTPVersion ptpVersion) ++ * ++ */ ++enum ioh_status ++ioh_1588_ptp_version_set( ++ enum ioh1588PTPPort ptpPort, \ ++ enum ioh1588PTPVersion ptpVersion); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_operation_mode_set( ++ * enum ioh1588PTPPort ptpPort, ++ * enum ioh1588PTPOperationMode ptpMode) ++ * ++ */ ++enum ioh_status ++ioh_1588_ptp_operation_mode_set(enum ioh1588PTPPort ptpPort, ++ enum ioh1588PTPOperationMode ptpMode); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_ptp_operation_mode_get(enum ioh1588PTPPort ptpPort, ++ * enum ioh1588PTPOperationMode *ptpMode) ++ */ ++enum ioh_status ++ioh_1588_ptp_operation_mode_get(enum ioh1588PTPPort ptpPort, ++ enum ioh1588PTPOperationMode *ptpMode); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_handler(void) ++ * ++ */ ++enum ioh_status ioh_1588_handler(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_target_time_interrupt_enable(void *callBack) ++ * ++ */ ++enum ioh_status ioh_1588_aux_target_time_interrupt_enable(void *callBack); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_target_time_interrupt_disable(void) ++ * ++ */ ++enum ioh_status ioh_1588_aux_target_time_interrupt_disable(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_target_time_poll( ++ * unsigned long *attmPollFlag, struct ioh1588TimeValue *targetTime) ++ * ++ */ ++enum ioh_status ++ioh_1588_aux_target_time_poll(unsigned long *attmPollFlag, ++ struct ioh1588TimeValue *targetTime); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_target_time_set( ++ * struct ioh1588TimeValue targetTime) ++ * ++ */ ++enum ioh_status ioh_1588_aux_target_time_set( ++ struct ioh1588TimeValue targetTime); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_aux_target_time_get( ++ * struct ioh1588TimeValue *targetTime) ++ * ++ */ ++enum ioh_status ioh_1588_aux_target_time_get( ++ struct ioh1588TimeValue *stargetTime); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_disable_interrupts(void) ++ * ++ */ ++enum ioh_status ioh_1588_disable_interrupts(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_interrupt_pending(unsigned long *pending) ++ * ++ */ ++enum ioh_status ioh_1588_interrupt_pending(unsigned long *pending); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_eth_enable(void) ++ * ++ */ ++enum ioh_status ioh_1588_eth_enable(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_eth_disable(void) ++ * ++ */ ++enum ioh_status ioh_1588_eth_disable(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_can_enable(void) ++ * ++ */ ++enum ioh_status ioh_1588_can_enable(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_can_disable(void) ++ * ++ */ ++enum ioh_status ioh_1588_can_disable(void); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_set_station_address (unsigned char *addr) ++ * ++ */ ++enum ioh_status ioh_1588_set_station_address(unsigned char *addr); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn enum ioh_status ioh_1588_get_station_address(char *addr) ++ * ++ */ ++enum ioh_status ioh_1588_get_station_address(char *addr); ++ ++/*! @ingroup IEEE_1588_HALLayerAPI ++ * @fn int ioh_1588_eth_can_get(void) ++ * ++ */ ++int ioh_1588_eth_can_get(void); ++ ++#ifdef IOH_IEEE1588_A0_A1_SAMPLE_BUG ++void ioh_1588_set_system_time_count(void); ++#endif ++ ++#endif /* IOH_1588_HAL_H */ +diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.c topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.c +--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.c 1970-01-01 09:00:00.000000000 +0900 ++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.c 2010-03-09 10:33:42.000000000 +0900 +@@ -0,0 +1,1192 @@ ++ /*! ++ * @file ioh_1588_main.c ++ * @brief ++ * This file contains the definitions of the IEEE_1588_InterfaceLayer APIs ++ * @version 0.92 ++ * @section ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * History: ++ * modified to support Intel IOH GE IEEE 1588 hardware ++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. ++ * All rights reserved. ++ * derived from ++ * IEEE 1588 Time Synchronization Driver for Intel EP80579 ++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ */ ++ ++#include "pch_1588_pci.h" ++#include "pch_1588_main.h" ++#include "pch_1588_hal.h" ++#include "pch_debug.h" ++#include <linux/sched.h> ++ ++/* Linux functions prototypes */ ++static int ioh_1588_open(struct inode *inode, struct file *filep); ++static int ioh_1588_release(struct inode *inode, struct file *filep); ++static int ioh_1588_ioctl(struct inode *inode, struct file *filep, ++ unsigned int cmd, unsigned long arg); ++ ++/* Linux file operations */ ++/*! @ingroup IEEE_1588_Global ++ * @var ioh_1588_fops ++ * @brief The structure variable used to specify the ++ * driver specific functionalities to the kernel ++ * subsystem. ++*/ ++const struct file_operations ioh_1588_fops = { ++ .owner = THIS_MODULE, ++ .open = ioh_1588_open, ++ .release = ioh_1588_release, ++ .ioctl = ioh_1588_ioctl, ++}; ++ ++/* For notify ioctls - values are populated from isr callbacks */ ++/*! @ingroup IEEE_1588_Global ++ * @var ioh_1588_target_time ++ * @brief This variable is updated from the target time reached callback ++ */ ++struct ioh1588TimeValue ioh_1588_target_time; ++/*! @ingroup IEEE_1588_Global ++ * @var ioh_1588_aux_time ++ * @brief This variable is updated from the Auxiliary master/slave time ++ * captured callback ++ */ ++struct ioh1588AuxTimeIoctl ioh_1588_aux_time; ++/*! @ingroup IEEE_1588_Global ++ * @var ioh_1588_pps_time ++ * @brief This variable is updated from the Pulse per second match ++ * callback ++ */ ++unsigned long ioh_1588_pps_time; ++ ++typedef int (*ioc_func_ptr) (unsigned long cmd, char *arg); ++static int ioc_handle_notify(unsigned long cmd, char *buf); ++static int ioc_handle_clr_notify(unsigned long cmd, char *buf); ++static int ioc_handle_reset(unsigned long cmd, char *buf); ++static int ioc_handle_show(unsigned long cmd, char *buf); ++static int ioc_handle_stats(unsigned long cmd, char *buf); ++static int ioc_handle_stats_reset(unsigned long cmd, char *buf); ++static int ioc_handle_int_enable(unsigned long cmd, char *buf); ++static int ioc_handle_int_disable(unsigned long cmd, char *buf); ++static int ioc_handle_port_config(unsigned long cmd, char *buf); ++static int ioc_handle_poll(unsigned long cmd, char *buf); ++static int ioc_handle_time_set(unsigned long cmd, char *buf); ++static int ioc_handle_time_get(unsigned long cmd, char *buf); ++static int ioc_handle_tick_rate(unsigned long cmd, char *buf); ++static int ioc_handle_pps_reqt(unsigned long cmd, char *buf); ++static int ioc_handle_version_reqt(unsigned long cmd, char *buf); ++static int ioc_handle_op_mode_reqt(unsigned long cmd, char *buf); ++ ++/* IOCTL command and their associated functions */ ++ ++/*! @ingroup IEEE_1588_Global ++ * @struct ioh_1588_ioc_tbl ++ * @brief Structure to map the ioctl command to the associated function ++ */ ++static const struct ioh_1588_ioc_tbl { ++ unsigned long cmd; ++ ioc_func_ptr func; ++} ioh_1588_ioc_tbl[] = { ++ { ++ IOCTL_1588_TARG_TIME_NOTIFY, ioc_handle_notify}, { ++ IOCTL_1588_AUX_TIME_NOTIFY, ioc_handle_notify}, { ++ IOCTL_1588_PULSE_PER_SEC_NOTIFY, ioc_handle_notify}, { ++ IOCTL_1588_AUX_TARG_TIME_NOTIFY, ioc_handle_notify}, { ++ IOCTL_1588_TARG_TIME_CLR_NOTIFY, ioc_handle_clr_notify}, { ++ IOCTL_1588_AUX_TIME_CLR_NOTIFY, ioc_handle_clr_notify}, { ++ IOCTL_1588_PULSE_PER_SEC_CLR_NOTIFY, ioc_handle_clr_notify}, { ++ IOCTL_1588_AUX_TARG_TIME_CLR_NOTIFY, ioc_handle_clr_notify}, { ++ IOCTL_1588_RESET, ioc_handle_reset}, { ++ IOCTL_1588_CHNL_RESET, ioc_handle_reset}, /* for this case too */ ++ { ++ IOCTL_1588_SHOW_ALL, ioc_handle_show}, { ++ IOCTL_1588_STATS_GET, ioc_handle_stats}, { ++ IOCTL_1588_STATS_RESET, ioc_handle_stats_reset}, { ++ IOCTL_1588_TARG_TIME_INTRPT_ENABLE, ioc_handle_int_enable}, { ++ IOCTL_1588_AUX_TIME_INTRPT_ENABLE, ioc_handle_int_enable}, { ++ IOCTL_1588_PULSE_PER_SEC_INTRPT_ENABLE, ioc_handle_int_enable}, { ++ IOCTL_1588_AUX_TARG_TIME_INTRPT_ENABLE, ioc_handle_int_enable}, { ++ IOCTL_1588_TARG_TIME_INTRPT_DISABLE, ioc_handle_int_disable}, { ++ IOCTL_1588_AUX_TIME_INTRPT_DISABLE, ioc_handle_int_disable}, { ++ IOCTL_1588_PULSE_PER_SEC_INTRPT_DISABLE, ioc_handle_int_disable}, { ++ IOCTL_1588_AUX_TARG_TIME_INTRPT_DISABLE, ioc_handle_int_disable}, { ++ IOCTL_1588_PORT_CONFIG_SET, ioc_handle_port_config}, { ++ IOCTL_1588_PORT_CONFIG_GET, ioc_handle_port_config}, { ++ IOCTL_1588_RX_POLL, ioc_handle_poll}, { ++ IOCTL_1588_TX_POLL, ioc_handle_poll}, { ++ IOCTL_1588_CAN_POLL, ioc_handle_poll}, { ++ IOCTL_1588_TARG_TIME_POLL, ioc_handle_poll}, { ++ IOCTL_1588_AUX_TIME_POLL, ioc_handle_poll}, { ++ IOCTL_1588_AUX_TARG_TIME_POLL, ioc_handle_poll}, { ++ IOCTL_1588_SYS_TIME_SET, ioc_handle_time_set}, { ++ IOCTL_1588_TARG_TIME_SET, ioc_handle_time_set}, { ++ IOCTL_1588_AUX_TARG_TIME_SET, ioc_handle_time_set}, { ++ IOCTL_1588_SYS_TIME_GET, ioc_handle_time_get}, { ++ IOCTL_1588_TARG_TIME_GET, ioc_handle_time_get}, { ++ IOCTL_1588_AUX_TARG_TIME_GET, ioc_handle_time_get}, { ++ IOCTL_1588_TICK_RATE_GET, ioc_handle_tick_rate}, { ++ IOCTL_1588_TICK_RATE_SET, ioc_handle_tick_rate}, { ++ IOCTL_1588_PULSE_PER_SEC_TIME_SET, ioc_handle_pps_reqt}, { ++ IOCTL_1588_PULSE_PER_SEC_TIME_GET, ioc_handle_pps_reqt}, { ++ IOCTL_1588_PORT_VERSION_SET, ioc_handle_version_reqt}, { ++ IOCTL_1588_PORT_VERSION_GET, ioc_handle_version_reqt}, { ++ IOCTL_1588_PORT_OPERATION_MODE_SET, ioc_handle_op_mode_reqt}, { ++IOCTL_1588_PORT_OPERATION_MODE_GET, ioc_handle_op_mode_reqt},}; ++ ++#define IOH_1588_IOC_TBL_ENTRIES \ ++ (sizeof ioh_1588_ioc_tbl / sizeof ioh_1588_ioc_tbl[0]) ++ ++/*! @ingroup IEEE_1588_InterfaceLayerAPI ++ * @fn int ioh_1588_open(struct inode *inode, struct file *filep) ++ * @brief This function is called when the driver interface is opened ++ * @remarks This function is registered at the driver initialization ++ * point (module_init) and invoked when a process opens the ++ * IEEE 1588 device node. ++ * ++ * @param inode [IN] pointer to device inode structure ++ * @param filep [IN] pointer to open file structure ++ * ++ * @return int ++ * - Returns 0 on success and <0 on failure ++ */ ++static int ioh_1588_open(struct inode *inode, struct file *filep) ++{ ++ if (ioh_1588_devp->suspend) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_open returning as device is suspended\n"); ++ return -EINTR; ++ } ++ IOH_DEBUG("ioh_1588_open\n"); ++ ++ return 0; ++} ++ ++/*! @ingroup IEEE_1588_InterfaceLayerAPI ++ * @fn int ioh_1588_release(struct inode *inode, struct file *filep) ++ * @brief This function is called when the driver interface is closed ++ * @remarks This function is registered at the driver initialization ++ * point (module_init) and invoked when the last process ++ * which has an open file table entry for the device ++ * exits or does a close of the device file. ++ * ++ * @param inode [IN] pointer to device inode structure ++ * @param filep [IN] pointer to open file structure ++ * ++ * @retval int ++ * - Returns 0 on success and <0 on failure ++ */ ++static int ioh_1588_release(struct inode *inode, struct file *filep) ++{ ++ IOH_DEBUG("ioh_1588_release\n"); ++ ++ return 0; ++} ++ ++/*! @ingroup IEEE_1588_InterfaceLayerAPI ++ * @fn int ioh_1588_ioctl(struct inode *inode, struct file *filep, ++ * unsigned int cmd, unsigned long arg) ++ * @brief This function implements the ioctl interface of the driver ++ * @remarks This function is registered at the driver initialization ++ * point (module_init) and invoked when a user process ++ * invokes the .ioctl. call on the device ++ * ++ * @param inode [IN] pointer to device inode structure ++ * @param filep [IN] pointer to open file structure ++ * @param cmd [IN] ioctl command ++ * @param arg [INOUT] argument passed to the command ++ * ++ * @retval int ++ * - Returns 0 on success and <0 on failure ++ */ ++static int ioh_1588_ioctl(struct inode *inode, struct file *filep, ++ unsigned int cmd, unsigned long arg) ++{ ++ char buffer[0x64]; ++ unsigned int argsz; ++ int i, ret = 0; ++ ++ if ((!ioh_1588_devp->initialized) || (ioh_1588_devp->suspend)) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl:device is suspended OR \ ++ uninitialized\n"); ++ return -EINTR; ++ } ++ ++ argsz = _IOC_SIZE(cmd); ++ ++ if (argsz > sizeof buffer) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: buffer size too small.\n"); ++ return -EINVAL; ++ } ++ ++ /* if data is being written to the driver */ ++ if (_IOC_DIR(cmd) & _IOC_WRITE) { ++ /* get the data passed in by user */ ++ if (copy_from_user(&buffer, (void *)arg, argsz)) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: could not copy user space \ ++ data.\n"); ++ return -EFAULT; ++ } ++ } ++ ++ for (i = 0; i < IOH_1588_IOC_TBL_ENTRIES; i++) { ++ if (ioh_1588_ioc_tbl[i].cmd == cmd) { ++ ret = ioh_1588_ioc_tbl[i].func(cmd, buffer); ++ break; ++ } ++ } ++ if (i >= IOH_1588_IOC_TBL_ENTRIES) { /* did not find a match */ ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: unknown command (0x%x)\n", ++ cmd); ++ return -EINVAL; ++ } ++ ++ /* if data is being read from the driver */ ++ if ((ret == 0) && (_IOC_DIR(cmd) & _IOC_READ)) { ++ if (copy_to_user((void *)arg, buffer, argsz)) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: could not copy data to user \ ++ space.\n"); ++ return -EFAULT; ++ } ++ } ++ ++ return ret; ++} ++ ++/* Handles all NOTIFY IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_notify (unsigned long cmd, char *buf) ++ * @brief Handles all NOTIFY IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf [OUT] the reference to data to be returned ++ * @retval int ++ * - 0 ++ * <hr> ++ */ ++static int ioc_handle_notify(unsigned long cmd, char *buf) ++{ ++ unsigned int bytes_ret = 0; ++ void *param_addr = NULL; ++ wait_queue_head_t *event = NULL; ++ unsigned int eventnum = 0; ++ ++ if (IOCTL_1588_AUX_TARG_TIME_NOTIFY == cmd) { ++ IOH_LOG(KERN_ERR, "ioc_handle_notify \ ++ returning...[cmd = IOCTL_1588_AUX_TARG_TIME_NOTIFY]\n"); ++ return -EINVAL; ++ } ++ /* request to be notified of a 1588 interrupt event Target Time */ ++ else if (cmd == IOCTL_1588_TARG_TIME_NOTIFY) { ++ IOH_DEBUG ++ ("ioc_handle_notify cmd = IOCTL_1588_TARG_TIME_NOTIFY]\n"); ++ event = &ioh_1588_devp->notify_evt[TARG_TIME_EVENT_NUM]; ++ bytes_ret = sizeof(struct ioh1588TimeValue); ++ param_addr = &ioh_1588_target_time; ++ eventnum = TARG_TIME_EVENT_NUM; ++ } else if (cmd == IOCTL_1588_AUX_TIME_NOTIFY) { ++ IOH_DEBUG ++ ("ioc_handle_notify cmd = IOCTL_1588_AUX_TIME_NOTIFY]\n"); ++ event = &ioh_1588_devp->notify_evt[AUX_TIME_EVENT_NUM]; ++ bytes_ret = sizeof(struct ioh1588AuxTimeIoctl); ++ param_addr = &ioh_1588_aux_time; ++ eventnum = AUX_TIME_EVENT_NUM; ++ } else { ++ event = &ioh_1588_devp->notify_evt[PPS_EVENT_NUM]; ++ bytes_ret = sizeof(unsigned long); ++ param_addr = &ioh_1588_pps_time; ++ eventnum = PPS_EVENT_NUM; ++ } ++ ++ ioh_1588_devp->event_flags[eventnum] = 0; ++ ++ /* wait infinitely for a 1588 interrupt event to occur */ ++ IOH_DEBUG("ioc_handle_notify waiting for interrupt event...\n"); ++ wait_event_interruptible(*event, ++ ioh_1588_devp->event_flags[eventnum] == 1); ++ IOH_DEBUG("ioc_handle_notify got interrupt event...\n"); ++ ++ /* copy global data retreived from interrupt handler */ ++ (void)memcpy((void *)&buf, (const void *)param_addr, bytes_ret); ++ ++ /* reset global data to 0 */ ++ (void)memset((void *)param_addr, 0, bytes_ret); ++ ++ ioh_1588_devp->event_flags[eventnum] = 0; ++ ++ return 0; ++} ++ ++/* Handles all CLEAR NOTIFY IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_clr_notify (unsigned long cmd, char *buf) ++ * @brief Handles all CLEAR NOTIFY IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf unused ++ * @retval int ++ * - 0 on success ++ * - -EINVAL for unsupported IOCTL ++ * <hr> ++ */ ++static int ioc_handle_clr_notify(unsigned long cmd, char *buf) ++{ ++ unsigned int eventnum = 0; ++ ++ /* ++ * request to release a notify thread that is waiting ++ * on a 1588 interrupt event ++ */ ++ if (cmd == IOCTL_1588_TARG_TIME_CLR_NOTIFY) { ++ IOH_DEBUG ++ ("ioc_handle_clr_notify cmd=\ ++ IOCTL_1588_TARG_TIME_CLR_NOTIFY\n"); ++ eventnum = TARG_TIME_EVENT_NUM; ++ } else if (cmd == IOCTL_1588_AUX_TIME_CLR_NOTIFY) { ++ IOH_DEBUG ++ ("ioc_handle_clr_notify cmd=\ ++ IOCTL_1588_AUX_TIME_CLR_NOTIFY\n"); ++ eventnum = AUX_TIME_EVENT_NUM; ++ } else if (cmd == IOCTL_1588_PULSE_PER_SEC_CLR_NOTIFY) { ++ IOH_DEBUG ++ ("ioc_handle_clr_notify cmd=\ ++ IOCTL_1588_PULSE_PER_SEC_CLR_NOTIFY\n"); ++ eventnum = PPS_EVENT_NUM; ++ } else if (cmd == IOCTL_1588_AUX_TARG_TIME_CLR_NOTIFY) { ++ IOH_DEBUG ++ ("ioc_handle_clr_notify cmd=\ ++ IOCTL_1588_AUX_TARG_TIME_CLR_NOTIFY\n"); ++ IOH_LOG(KERN_ERR, "ioc_handle_clr_notify returning -EINVAL\n"); ++ return -EINVAL; ++ } ++ ++ ioh_1588_devp->event_flags[eventnum] = 1; ++ ++ IOH_DEBUG("ioc_handle_clr_notify waking up blocking notify call...\n"); ++ wake_up_interruptible(&ioh_1588_devp->notify_evt[eventnum]); ++ return 0; ++} ++ ++/* Handles reset and channel reset IOCTLs */ ++ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_reset (unsigned long cmd, char *buf) ++ * @brief Handles reset and channel reset IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf unused ++ * @retval int ++ * - 0 on success ++ * - -EINVAL when hardware reset fails ++ * <hr> ++ */ ++static int ioc_handle_reset(unsigned long cmd, char *buf) ++{ ++ int i = 0; ++ int ieee_mode; ++ unsigned char station[STATION_ADDR_LEN] = "00:00:00:00:00:00"; ++ ++ IOH_DEBUG("ioc_handle_reset: invoking ioh_1588_reset\n"); ++ ++ /*retrieve eth/CAN mode */ ++ ieee_mode = ioh_1588_eth_can_get(); ++ ++ /*retrive station address */ ++ ioh_1588_get_station_address(station); ++ ++ /* reset the 1588 hardware */ ++ if (ioh_1588_reset() != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioc_handle_reset: ioh_1588_reset failed\n"); ++ return -EINVAL; ++ } ++ /* Anyway, now clear all the events */ ++ for (i = 0; i < NUM_EVENTS; i++) ++ ioh_1588_devp->event_flags[i] = 0; ++ /*set ETH/CAN mode */ ++ if (ieee_mode & IOH_IEEE1588_ETH) ++ ioh_1588_eth_enable(); ++ if (ieee_mode & IOH_IEEE1588_CAN) ++ ioh_1588_can_enable(); ++ ++ /*set station address */ ++ if (strcmp(station, "00:00:00:00:00:00") != 0) { ++ if (ioh_1588_set_station_address(station) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_reset: could not set station \ ++ address\n"); ++ } ++ } ++ ++ IOH_DEBUG("ioc_handle_reset: returning 0\n"); ++ return 0; ++} ++ ++/* Handles reset statistics IOCTL */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_stats_reset (unsigned long cmd, char *buf) ++ * @brief Handles reset statistics IOCTLs ++ * @param cmd unused ++ * @param buf unused ++ * @retval int ++ * - 0 on success ++ * <hr> ++ */ ++static int ioc_handle_stats_reset(unsigned long cmd, char *buf) ++{ ++ ++ IOH_DEBUG("ioc_handle_stats_reset: invoking ioh_1588_stats_reset\n"); ++ ioh_1588_stats_reset(); ++ IOH_DEBUG("ioc_handle_stats_reset: returning 0\n"); ++ return 0; ++} ++ ++/* Handles get statistics IOCTL */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_stats (unsigned long cmd, char *buf) ++ * @brief Handles get statistics IOCTL ++ * @param cmd [IN] the IOCTL command ++ * @param buf [OUT] reference to statistics retrieved ++ * @retval int ++ * - 0 on success ++ * <hr> ++ */ ++static int ioc_handle_stats(unsigned long cmd, char *buf) ++{ ++ IOH_DEBUG("ioc_handle_stats: invoking ioh_ioh_1588_stats_get\n"); ++ if (ioh_1588_stats_get((struct ioh1588Stats *) buf) != \ ++ IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_stats_get failed\n"); ++ return -EINVAL; ++ } ++ IOH_DEBUG("ioc_handle_statst: returning 0\n"); ++ return 0; ++} ++ ++/* Handles show all IOCTL */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_show (unsigned long cmd, char *buf) ++ * @brief Handles show all IOCTL ++ * @param cmd unused ++ * @param buf unused ++ * @retval int ++ * - 0 on success ++ * - -EINVAL when @ref ioh_1588_show fails ++ * <hr> ++ */ ++static int ioc_handle_show(unsigned long cmd, char *buf) ++{ ++ IOH_DEBUG("ioc_handle_show: invoking ioh_1588_show\n"); ++ if (ioh_1588_show() != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: ioh_1588_show failed\n"); ++ return -EINVAL; ++ } ++ IOH_DEBUG("ioc_handle_show: returning 0\n"); ++ return 0; ++} ++ ++/* Handles all interrupt enable IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_int_enable (unsigned long cmd, char *buf) ++ * @brief Handles all interrupt enable IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf [IN] the reference to auxiliary mode ++ * @retval int ++ * - 0 on success ++ * - -EINVAL failed to enable interrupt ++ * <hr> ++ */ ++static int ioc_handle_int_enable(unsigned long cmd, char *buf) ++{ ++ int ret = 0; ++ ++ if (IOCTL_1588_TARG_TIME_INTRPT_ENABLE == cmd) { ++ IOH_DEBUG ++ ("ioc_handle_int_enable cmd=\ ++ IOCTL_1588_TARG_TIME_INTRPT_ENABLE \ ++ invoking \ ++ ioh_1588_target_time_interrupt_enable\n"); ++ if (ioh_1588_target_time_interrupt_enable(target_time_callback) ++ != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \ ++ ioh_1588_target_time_interrupt_enable \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } else if (IOCTL_1588_AUX_TIME_INTRPT_ENABLE == cmd) { ++ enum ioh1588AuxMode aux_mode; ++ IOH_DEBUG ++ ("ioc_handle_int_enable cmd=\ ++ IOCTL_1588_AUX_TIME_INTRPT_ENABLE \ ++ invoking ioh_1588_aux_time_interrupt_enable\n"); ++ ++ (void)memcpy((void *)&aux_mode, (const void *)buf, ++ sizeof(enum ioh1588AuxMode)); ++ ++ if (ioh_1588_aux_time_interrupt_enable ++ (aux_mode, auxiliary_time_callback) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \ ++ ioh_1588_aux_time_interrupt_enable \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } else if (IOCTL_1588_PULSE_PER_SEC_INTRPT_ENABLE == cmd) { ++ IOH_DEBUG ++ ("ioc_handle_int_enable cmd=\ ++ IOCTL_1588_PULSE_PER_SEC_INTRPT_ENABLE \ ++ invoking \ ++ ioh_1588_pulse_per_sec_interrupt_enable\n"); ++ if (ioh_1588_pulse_per_sec_interrupt_enable ++ (pulse_per_sec_callback) ++ != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \ ++ ioh_1588_pps_interrupt_enable \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } else { /* IOCTL_1588_AUX_TARG_TIME_INTRPT_ENABLE */ ++ ++ IOH_DEBUG ++ ("ioc_handle_int_enable cmd=\ ++ OCTL_1588_AUX_TARG_TIME_INTRPT_ENABLE \ ++ invoking \ ++ ioh_1588_aux_target_time_interrupt_enable\n"); ++ if (ioh_1588_aux_target_time_interrupt_enable((void *)NULL) ++ != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \ ++ ioh_1588_aux_target_time_interrupt_enable \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } ++ return ret; ++} ++ ++/* Handles all interrupt disable IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_int_disable (unsigned long cmd, char *buf) ++ * @brief Handles all interrupt enable IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf [IN] the reference to auxiliary mode ++ * @retval int ++ * - 0 on success ++ * - -EINVAL failed to disable interrupt ++ * <hr> ++ */ ++static int ioc_handle_int_disable(unsigned long cmd, char *buf) ++{ ++ int ret = 0; ++ ++ if (IOCTL_1588_TARG_TIME_INTRPT_DISABLE == cmd) { ++ IOH_DEBUG ++ ("ioc_handle_int_disable cmd=\ ++ IOCTL_1588_TARG_TIME_INTRPT_DISABLE \ ++ invoking \ ++ ioh_1588_target_time_interrupt_disable\n"); ++ if (ioh_1588_target_time_interrupt_disable() ++ != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \ ++ ioh_1588_target_time_interrupt_disable \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } else if (IOCTL_1588_AUX_TIME_INTRPT_DISABLE == cmd) { ++ enum ioh1588AuxMode aux_mode; ++ IOH_DEBUG ++ ("ioc_handle_int_disable cmd=\ ++ IOCTL_1588_AUX_TIME_INTRPT_DISABLE \ ++ invoking \ ++ ioh_1588_aux_time_interrupt_disable\n"); ++ ++ (void)memcpy((void *)&aux_mode, (const void *)buf, ++ sizeof(enum ioh1588AuxMode)); ++ ++ if (ioh_1588_aux_time_interrupt_disable(aux_mode) ++ != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \ ++ ioh_1588_aux_time_interrupt_disable \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } else if (IOCTL_1588_PULSE_PER_SEC_INTRPT_DISABLE == cmd) { ++ IOH_DEBUG ++ ("ioc_handle_int_disable cmd=\ ++ IOCTL_1588_PULSE_PER_SEC_INTRPT_DISABLE \ ++ invoking \ ++ ioh_1588_pulse_per_sec_interrupt_disable\n"); ++ if (ioh_1588_pulse_per_sec_interrupt_disable() != ++ IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \ ++ ioh_1588_pulse_per_sec_interrupt_disable \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } else { /* IOCTL_1588_AUX_TARG_TIME_INTRPT_DISABLE */ ++ ++ IOH_DEBUG ++ ("ioc_handle_int_disable cmd=\ ++ IOCTL_1588_AUX_TARG_TIME_INTRPT_DISABLE \ ++ invoking \ ++ ioh_1588_aux_target_time_interrupt_disable\n"); ++ if (ioh_1588_aux_target_time_interrupt_disable() != ++ IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \ ++ ioh_1588_aux_target_time_interrupt_disable \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } ++ return ret; ++} ++ ++/* Handles port config set/get IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_port_config (unsigned long cmd, char *buf) ++ * @brief Handles port config set/get IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf [IN] the port configuration ++ * @retval int ++ * - 0 on success ++ * - -EINVAL failed to set/get port configuration ++ * <hr> ++ */ ++static int ioc_handle_port_config(unsigned long cmd, char *buf) ++{ ++ struct ioh1588PortCfgIoctl *port_cfg_ioctl = \ ++ (struct ioh1588PortCfgIoctl *) buf; ++ ++ if (IOCTL_1588_PORT_CONFIG_SET == cmd) { ++ IOH_DEBUG ++ ("ioc_handle_port_config cmd = IOCTL_1588_PORT_CONFIG_SET \ ++ invoking ioh_1588_ptp_port_config_set\n"); ++ ++ if (ioh_1588_ptp_port_config_set(port_cfg_ioctl->ptpPort, ++ port_cfg_ioctl->ptpPortMode) != ++ IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_ptp_port_config_set \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } else { /* IOCTL_1588_PORT_CONFIG_GET */ ++ ++ IOH_DEBUG ++ ("ioc_handle_port_config cmd = IOCTL_1588_PORT_CONFIG_GET \ ++ invoking ioh_1588_ptp_port_config_get\n"); ++ if (ioh_1588_ptp_port_config_get ++ (port_cfg_ioctl->ptpPort, ++ &port_cfg_ioctl->ptpPortMode) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_ptp_port_config_get \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/* Handles all POLL IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_poll (unsigned long cmd, char *buf) ++ * @brief Handles all poll IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf [IN] the poll configuration ++ * @retval int ++ * - 0 on success ++ * - -EINVAL on failure ++ * <hr> ++ */ ++static int ioc_handle_poll(unsigned long cmd, char *buf) ++{ ++ int ret = 0; ++ struct ioh1588RxTxPollIoctl *poll_ioctl = \ ++ (struct ioh1588RxTxPollIoctl *) buf; ++ struct ioh1588CANPollIoctl *can_poll_ioctl = \ ++ (struct ioh1588CANPollIoctl *) buf; ++ struct ioh1588TimePollIoctl *time_poll_ioctl = \ ++ (struct ioh1588TimePollIoctl *) buf; ++ ++ if (IOCTL_1588_RX_POLL == cmd) { ++ IOH_DEBUG("ioc_handle_poll: cmd = IOCTL_1588_RX_POLL \ ++ invoking ioh_1588_ptp_rx_poll\n"); ++ ret = ioh_1588_ptp_rx_poll(poll_ioctl->ptpPort, ++ &poll_ioctl->ptpMsgData); ++ if ((ret != IOH_1588_SUCCESS) && \ ++ (ret != IOH_1588_NOTIMESTAMP)) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_ptp_rx_poll \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } else if (IOCTL_1588_TX_POLL == cmd) { ++ IOH_DEBUG("ioc_handle_poll: cmd = IOCTL_1588_TX_POLL \ ++ invoking ioh_1588_ptp_tx_poll\n"); ++ ret = ioh_1588_ptp_tx_poll(poll_ioctl->ptpPort, ++ &poll_ioctl->ptpMsgData); ++ if ((ret != IOH_1588_SUCCESS) && \ ++ (ret != IOH_1588_NOTIMESTAMP)) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_ptp_tx_poll \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } else if (IOCTL_1588_CAN_POLL == cmd) { ++ IOH_DEBUG("ioc_handle_poll: cmd = IOCTL_1588_CAN_POLL \ ++ invoking ioh_1588_ptp_can_poll\n"); ++ ret = ioh_1588_ptp_can_poll(can_poll_ioctl->ptpPort, ++ &can_poll_ioctl->ptpTimeStamp); ++ if ((ret != IOH_1588_SUCCESS) && \ ++ (ret != IOH_1588_NOTIMESTAMP)) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_ptp_can_poll \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } else if (IOCTL_1588_TARG_TIME_POLL == cmd) { ++ IOH_DEBUG("ioc_handle_poll: cmd = IOCTL_1588_TARG_TIME_POLL " ++ "invoking ioh_1588_target_time_poll\n"); ++ if (ioh_1588_target_time_poll(&time_poll_ioctl->pollFlag, ++ &time_poll_ioctl->timeVal) != ++ IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_target_time_poll \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } else if (IOCTL_1588_AUX_TIME_POLL == cmd) { ++ IOH_DEBUG("ioc_handle_poll: cmd = IOCTL_1588_AUX_TIME_POLL " ++ "invoking ioh_1588_aux_time_poll\n"); ++ if (ioh_1588_aux_time_poll(time_poll_ioctl->auxMode, ++ &time_poll_ioctl->pollFlag, ++ &time_poll_ioctl->timeVal) ++ != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_aux_time_poll \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } else { /* IOCTL_1588_AUX_TARG_TIME_POLL */ ++ ++ IOH_DEBUG ++ ("ioc_handle_poll: cmd = IOCTL_1588_AUX_TARG_TIME_POLL " ++ "invoking ioh_1588_aux_target_time_poll\n"); ++ if (ioh_1588_aux_target_time_poll ++ (&time_poll_ioctl->pollFlag, ++ &time_poll_ioctl->timeVal) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_aux_target_time_poll \ ++ failed\n"); ++ ret = -EINVAL; ++ } ++ } ++ if ((unsigned long)ret == IOH_1588_NOTIMESTAMP) ++ ret = 0; ++ return ret; ++} ++ ++/* Handles all Time Set IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_time_set (unsigned long cmd, char *buf) ++ * @brief Handles all Time Set IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf [IN] the time value ++ * @retval int ++ * - 0 on success ++ * - -EINVAL on failure ++ * <hr> ++ */ ++static int ioc_handle_time_set(unsigned long cmd, char *buf) ++{ ++ struct ioh1588TimeValue time_value; ++ ++ (void)memcpy((void *)&time_value, (const void *)buf, ++ sizeof(struct ioh1588TimeValue)); ++ ++ if (IOCTL_1588_SYS_TIME_SET == cmd) { ++ IOH_DEBUG("ioc_handle_time_set cmd=IOCTL_1588_SYS_TIME_SET \ ++ invoking ioh_1588_system_time_set\n"); ++ if (ioh_1588_system_time_set(time_value) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_system_time_set \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } else if (IOCTL_1588_TARG_TIME_SET == cmd) { ++ IOH_DEBUG("ioc_handle_time_set cmd=IOCTL_1588_TARG_TIME_SET \ ++ invoking ioh_1588_target_time_set\n"); ++ if (ioh_1588_target_time_set(time_value) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_target_time_set \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } else { /* IOCTL_1588_AUX_TARG_TIME_SET */ ++ ++ IOH_DEBUG ++ ("ioc_handle_time_set cmd=IOCTL_1588_AUX_TARG_TIME_SET \ ++ invoking ioh_1588_aux_target_time_set\n"); ++ if (ioh_1588_aux_target_time_set(time_value) != ++ IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_aux_target_time_set \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/* Handles all Time Get IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_time_get (unsigned long cmd, char *buf) ++ * @brief Handles all Time Get IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf [OUT] the time value ++ * @retval int ++ * - 0 on success ++ * - -EINVAL on failure ++ * <hr> ++ */ ++static int ioc_handle_time_get(unsigned long cmd, char *buf) ++{ ++ struct ioh1588TimeValue time_value; ++ ++ if (IOCTL_1588_SYS_TIME_GET == cmd) { ++ IOH_DEBUG("ioc_handle_time_get cmd=IOCTL_1588_SYS_TIME_GET \ ++ invoking ioh_1588_system_time_get\n"); ++ if (ioh_1588_system_time_get(&time_value) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_system_time_get \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } else if (IOCTL_1588_TARG_TIME_GET == cmd) { ++ IOH_DEBUG("ioc_handle_time_get cmd=IOCTL_1588_TARG_TIME_GET \ ++ invoking ioh_1588_target_time_get\n"); ++ if (ioh_1588_target_time_get(&time_value) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_target_time_get \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } else { /* IOCTL_1588_AUX_TARG_TIME_GET */ ++ ++ IOH_DEBUG ++ ("ioc_handle_time_get cmd=IOCTL_1588_AUX_TARG_TIME_GET \ ++ invoking ioh_1588_aux_target_time_get\n"); ++ if (ioh_1588_aux_target_time_get(&time_value)) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_aux_target_time_set \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } ++ ++ (void)memcpy((void *)buf, (const void *)&time_value, ++ sizeof(struct ioh1588TimeValue)); ++ return 0; ++} ++ ++/* Handles tick rate get/set IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_tick_rate (unsigned long cmd, char *buf) ++ * @brief Handles tick rate get/set IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf [OUT] the tick rate ++ * @retval int ++ * - 0 on success ++ * - -EINVAL on failure ++ * <hr> ++ */ ++static int ioc_handle_tick_rate(unsigned long cmd, char *buf) ++{ ++ unsigned long val; ++ ++ if (IOCTL_1588_TICK_RATE_GET == cmd) { ++ IOH_DEBUG("ioc_handle_tick_rate cmd =IOCTL_1588_TICK_RATE_GET \ ++ invoking ioh_1588_tick_rate_get\n"); ++ if (ioh_1588_tick_rate_get(&val) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_tick_rate_get \ ++ failed\n"); ++ return -EINVAL; ++ } ++ ++ (void)memcpy((void *)buf, (const void *)&val, sizeof val); ++ } else { /* (cmd == IOCTL_1588_TICK_RATE_SET) */ ++ ++ IOH_DEBUG("ioc_handle_tick_rate cmd =IOCTL_1588_TICK_RATE_SET \ ++ invoking ioh_1588_tick_rate_set\n"); ++ (void)memcpy((void *)&val, (const void *)buf, sizeof val); ++ ++ if (ioh_1588_tick_rate_set(val) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_tick_rate_set \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/* Handles pps time get/set IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_pps_reqt (unsigned long cmd, char *buf) ++ * @brief Handles pps time get/set IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf [INOUT] the pulse per second value ++ * @retval int ++ * - 0 on success ++ * - -EINVAL on failure ++ * <hr> ++ */ ++static int ioc_handle_pps_reqt(unsigned long cmd, char *buf) ++{ ++ unsigned long val; ++ ++ if (IOCTL_1588_PULSE_PER_SEC_TIME_SET == cmd) { ++ IOH_DEBUG ++ ("ioc_handle_pps_reqt cmd=\ ++ IOCTL_1588_PULSE_PER_SEC_TIME_SET \ ++ invoking ioh_1588_pulse_per_sec_time_set\n"); ++ (void)memcpy((void *)&val, (const void *)buf, sizeof val); ++ if (ioh_1588_pulse_per_sec_time_set(val) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \ ++ ioh_1588_pulse_per_sec_time_set \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } else { /* IOCTL_1588_PULSE_PER_SEC_TIME_GET */ ++ ++ IOH_DEBUG ++ ("ioc_handle_pps_reqt cmd=\ ++ IOCTL_1588_PULSE_PER_SEC_TIME_GET \ ++ invoking ioh_1588_pulse_per_sec_time_get\n"); ++ if (ioh_1588_pulse_per_sec_time_get(&val) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_ioctl: \ ++ ioh_1588_pulse_per_sec_time_get failed\n"); ++ return -EINVAL; ++ } ++ (void)memcpy((void *)buf, (const void *)&val, sizeof val); ++ } ++ return 0; ++} ++ ++/* Handles ptp version get/set IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_version_reqt (unsigned long cmd, char *buf) ++ * @brief Handles ptp version get/set IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf [INOUT]the ptp version ++ * @retval int ++ * - 0 on success ++ * - -EINVAL on failure ++ * <hr> ++ */ ++static int ioc_handle_version_reqt(unsigned long cmd, char *buf) ++{ ++ struct ioh1588VersionIoctl *version_ioctl = \ ++ (struct ioh1588VersionIoctl *) buf; ++ ++ if (IOCTL_1588_PORT_VERSION_SET == cmd) { ++ IOH_DEBUG ++ ("ioc_handle_version_reqt cmd=IOCTL_1588_PORT_VERSION_SET \ ++ invoking ioh_1588_ptp_version_set\n"); ++ if (ioh_1588_ptp_version_set ++ (version_ioctl->ptpPort, ++ version_ioctl->ptpVersion) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_ptp_version_set \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } else { /* IOCTL_1588_PORT_VERSION_GET */ ++ ++ IOH_DEBUG ++ ("ioc_handle_version_reqt cmd=IOCTL_1588_PORT_VERSION_GET \ ++ invoking ioh_1588_ptp_version_get\n"); ++ if (ioh_1588_ptp_version_get ++ (version_ioctl->ptpPort, ++ &version_ioctl->ptpVersion) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: ioh_1588_ptp_version_get \ ++ failed\n"); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/* Handles ptp operation mode get/set IOCTLs */ ++/*! @ingroup IEEE_1588_UtilitiesAPI ++ * @fn ioc_handle_op_mode_reqt (unsigned long cmd, char *buf) ++ * @brief Handles ptp operation mode get/set IOCTLs ++ * @param cmd [IN] the IOCTL command ++ * @param buf [INOUT]the ptp operation mode ++ * @retval int ++ * - 0 on success ++ * - -EINVAL on failure ++ * <hr> ++ */ ++static int ioc_handle_op_mode_reqt(unsigned long cmd, char *buf) ++{ ++ struct ioh1588OperationModeIoctl *opmode_ioctl = ++ (struct ioh1588OperationModeIoctl *) buf; ++ ++ if (IOCTL_1588_PORT_OPERATION_MODE_SET == cmd) { ++ IOH_DEBUG ++ ("ioc_handle_op_mode_reqt cmd=\ ++ IOCTL_1588_PORT_OPERATION_MODE_SET \ ++ invoking ioh_1588_ptp_operation_mode_set\n"); ++ if (ioh_1588_ptp_operation_mode_set ++ (opmode_ioctl->ptpPort, ++ opmode_ioctl->ptpOpMode) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: \ ++ ioh_1588_ptp_operation_mode_set failed\n"); ++ return -EINVAL; ++ } ++ } else { /* IOCTL_1588_PORT_OPERATION_MODE_GET */ ++ ++ IOH_DEBUG ++ ("ioc_handle_op_mode_reqt cmd=\ ++ IOCTL_1588_PORT_OPERATION_MODE_GET \ ++ invoking ioh_1588_ptp_operation_mode_get\n"); ++ if (ioh_1588_ptp_operation_mode_get ++ (opmode_ioctl->ptpPort, ++ &opmode_ioctl->ptpOpMode) != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_ioctl: \ ++ ioh_1588_ptp_operation_mode_get failed\n"); ++ return -EINVAL; ++ } ++ } ++ return 0; ++} ++ ++/*! @ingroup InterfaceLayerNotifyRoutines ++ * @fn irqreturn_t ioh_1588_isr(int irq, void *p_data) ++ * @brief This function is the driver interrupt service routine. ++ * ++ * @param irq [IN] interrupt number ++ * @param p_data caller data ++ * ++ * @retval irqreturn_t ++ * - IRQ_HANDLED => interrupt handled, ++ * - IRQ_NONE => this device did not interrupt ++ */ ++irqreturn_t ioh_1588_isr(int irq, void *p_data) ++{ ++ unsigned long pending = 0; ++ ++ (void)ioh_1588_interrupt_pending(&pending); ++ if (!pending) { ++ IOH_DEBUG("ioh_1588_isr: no pending interrupt\n"); ++ return IRQ_NONE; ++ } ++ ++ if (ioh_1588_handler() != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, "ioh_1588_isr: ioh_1588_handler failed\n"); ++ return IRQ_NONE; ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++/*! @ingroup InterfaceLayerNotifyRoutines ++ * @fn void target_time_callback(struct ioh1588TimeValue tgt_time) ++ * @brief The callback function that is called from the HAL ++ * when the target time expired interrupt occurs ++ * ++ * @param tgt_time target time register timestamp ++ * ++ * @retval None ++ */ ++void target_time_callback(struct ioh1588TimeValue tgt_time) ++{ ++ /* ++ * copy the target time value to the global value to be read by the ++ * notify ioctl ++ */ ++ (void)memcpy((void *)&ioh_1588_target_time, (const void *)&tgt_time, ++ sizeof(struct ioh1588TimeValue)); ++ ++ ioh_1588_devp->event_flags[TARG_TIME_EVENT_NUM] = 1; ++ ++ IOH_DEBUG("target_time_callback: signalling the notify ioctl \ ++ that the target time has expired\n"); ++ /* signal the notify ioctl that the target time has expired */ ++ wake_up_interruptible(&ioh_1588_devp->notify_evt[TARG_TIME_EVENT_NUM]); ++} ++ ++/*! @ingroup InterfaceLayerNotifyRoutines ++ * @fn void auxiliary_time_callback(enum ioh1588AuxMode aux_mode, ++ * struct ioh1588TimeValue aux_time) ++ * @brief The callback function that is called from the HAL ++ * when an aux time interrupt has occurred ++ * ++ * @param aux_mode master, slave, or any ++ * @param aux_time aux time register timestamp ++ * ++ * @return None ++ */ ++void auxiliary_time_callback(enum ioh1588AuxMode aux_mode, \ ++ struct ioh1588TimeValue aux_time) ++{ ++ /* ++ * copy the aux time value and aux mode to the global value ++ * to be read by the notify ioctl ++ */ ++ ++ ioh_1588_aux_time.auxMode = aux_mode; ++ (void)memcpy((void *)&ioh_1588_aux_time.auxTime, ++ (const void *)&aux_time, \ ++ sizeof(struct ioh1588AuxTimeIoctl)); ++ ++ ioh_1588_devp->event_flags[AUX_TIME_EVENT_NUM] = 1; ++ ++ IOH_DEBUG("auxiliary_time_callback: signalling the notify ioctl \ ++ that the auxiliary time stamp has been set\n"); ++ ++ /* ++ * signal the notify ioctl that the aux timestamp has been set ++ */ ++ wake_up_interruptible(&ioh_1588_devp->notify_evt[AUX_TIME_EVENT_NUM]); ++} ++ ++/*! @ingroup InterfaceLayerNotifyRoutines ++ * @fn void pulse_per_sec_callback(unsigned long pps) ++ * @brief This is a callback function that will be called from the HAL ++ * when the pulse per second time has expired which generates an ++ * interrupt ++ * ++ * @param pps pulse per second register timestamp ++ * ++ * @retval None ++ */ ++void pulse_per_sec_callback(unsigned long pps) ++{ ++ ioh_1588_pps_time = pps; ++ ++ ioh_1588_devp->event_flags[PPS_EVENT_NUM] = 1; ++ ++ IOH_DEBUG("pulse_per_sec_callback: signalling the notify ioctl \ ++ that the pulse per second time has expired\n"); ++ /* signal the notify ioctl that the pulse per second time has expired */ ++ ++ wake_up_interruptible(&ioh_1588_devp->notify_evt[PPS_EVENT_NUM]); ++} +diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.h topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.h +--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.h 1970-01-01 09:00:00.000000000 +0900 ++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_main.h 2010-03-09 10:22:48.000000000 +0900 +@@ -0,0 +1,702 @@ ++ /*! ++ * @file ioh_1588_main.h ++ * @brief ++ * This file contains the declarations of IEEE_1588_InterfaceLayer APIs ++ * @version 0.92 ++ * @section ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * History: ++ * modified to support Intel IOH GE IEEE 1588 hardware ++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. ++ * All rights reserved. ++ * derived from ++ * IEEE 1588 Time Synchronization Driver for Intel EP80579 ++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ */ ++ ++#ifndef IOH_1588_MAIN_H ++#define IOH_1588_MAIN_H ++ ++#ifdef __GNUC__ ++#define UNUSED __attribute__ ((unused)) ++#define UNUSED_ARG(x) ++#else ++#define UNUSED ++#define UNUSED_ARG(x) (void) x ++#endif ++ ++#include <linux/ioctl.h> ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++/*! @defgroup IEEE1588*/ ++ ++/*! @defgroup IEEE_1588_Global ++ * @ingroup IEEE1588 ++ * @brief This group describes the global entities within ++ * the module. ++ * @remarks This group includes all the global data structures ++ * used within the modules. These are mainly used to ++ * store the device related information, so that it can ++ * be used by other functions of the modules. ++ * <hr> ++ * */ ++ ++/*! @defgroup IEEE_1588_PCILayer ++ * @ingroup IEEE1588 ++ * @brief This group describes the PCI layer interface ++ * functionalities. ++ * @remarks This group contains the functions and data structures ++ * that are used to interface the module with PCI Layer ++ * subsystem of the Kernel. ++ * <hr> ++ * */ ++ ++/*! @defgroup IEEE_1588_InterfaceLayer ++ * @ingroup IEEE1588 ++ * @brief This group describes the Driver interface functionalities. ++ * @remarks This group contains the data structures and functions used ++ * to interface the module driver with the kernel subsystem. ++ * <hr> ++ * */ ++ ++/*! @defgroup IEEE_1588_HALLayer ++ * @ingroup IEEE1588 ++ * @brief This group describes the hardware specific functionalities. ++ * @remarks This group contains the functions and data structures used ++ * by the module to communicate with the hardware. These ++ * functions are device specific and designed according to the ++ * device specifications. ++ * <hr> ++ * */ ++ ++/*! @defgroup IEEE_1588_Utilities ++ * @ingroup IEEE1588 ++ * @brief This group describes the utility functionalities. ++ * @remarks This group contains the functions and data structures used ++ * to assist the other functionalities in their operations. ++ * <hr> ++ **/ ++ ++/*! @defgroup IEEE_1588_PCILayerAPI ++ * @ingroup IEEE_1588_PCILayer ++ * @brief This group contains the API(functions) used as the PCI ++ * interface between the Kernel subsystem and the module. ++ *<hr> ++ **/ ++ ++/*! @defgroup IEEE_1588_PCILayerFacilitators ++ * @ingroup IEEE_1588_PCILayer ++ * @brief This group contains the data structures used by the PCI ++ * Layer APIs for their functionalities. ++ * <hr> ++ **/ ++ ++/*! @defgroup IEEE_1588_InterfaceLayerAPI ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @brief This group contains the API(functions) used as the Driver ++ * interface between the Kernel subsystem and the module. ++ * <hr> ++ **/ ++ ++/*! @defgroup IEEE_1588_InterfaceLayerFacilitators ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @brief This group contains the data structures used by the Driver ++ * interface APIs for their functionalities. ++ * <hr> ++ **/ ++ ++/*! @defgroup IEEE_1588_HALLayerAPI ++ * @ingroup IEEE_1588_HALLayer ++ * @brief This group contains the APIs(functions) used to interact with ++ * the hardware. These APIs act as an interface between the ++ * hardware and the other driver functions. ++ * <hr> ++ **/ ++ ++/*! @defgroup IEEE_1588_UtilitiesAPI ++ * @ingroup IEEE_1588_Utilities ++ * @brief This group contains the APIs(functions) used by other ++ * functions ++ * in their operations. ++ * <hr> ++ **/ ++ ++/* 1588 module ioctl command codes */ ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOC_1588_BASE ++ * @brief The unique one byte data used to define ++ * the IOCTL commands ++ */ ++#define IOC_1588_BASE 0x88 ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PORT_CONFIG_SET ++ * @brief Set the IEEE 1588 Ethernet port to Mater/Slave/All mode ++ */ ++#define IOCTL_1588_PORT_CONFIG_SET \ ++ _IOW(IOC_1588_BASE, 0, struct ioh1588PortCfgIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PORT_CONFIG_GET ++ * @brief Get the IEEE 1588 Ethernet port Configuration mode ++ */ ++#define IOCTL_1588_PORT_CONFIG_GET \ ++ _IOWR(IOC_1588_BASE, 1, struct ioh1588PortCfgIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_RX_POLL ++ * @brief Poll for receive timestamp captured on the IEEE 1588 ethernet ++ * channel ++ */ ++#define IOCTL_1588_RX_POLL _IOWR(IOC_1588_BASE, 2, struct ioh1588RxTxPollIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_TX_POLL ++ * @brief Poll for transmit timestamp captured on the IEEE 1588 ethernet ++ * channel ++ */ ++#define IOCTL_1588_TX_POLL _IOWR(IOC_1588_BASE, 3, struct ioh1588RxTxPollIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_CAN_POLL ++ * @brief Poll for timestamp captured on the IEEE 1588 CAN channel ++ */ ++#define IOCTL_1588_CAN_POLL _IOWR(IOC_1588_BASE, 4, struct ioh1588CANPollIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_SYS_TIME_GET ++ * @brief Get the IEEE 1588 system time from the module ++ */ ++#define IOCTL_1588_SYS_TIME_GET _IOR(IOC_1588_BASE, 5, struct ioh1588TimeValue) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_SYS_TIME_SET ++ * @brief Set the IEEE 1588 system time on the module ++ */ ++#define IOCTL_1588_SYS_TIME_SET _IOW(IOC_1588_BASE, 6, struct ioh1588TimeValue) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_TICK_RATE_SET ++ * @brief Set the frequency scaling value used on IEEE 1588 module ++ */ ++#define IOCTL_1588_TICK_RATE_SET _IOW(IOC_1588_BASE, 7, unsigned long) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_TICK_RATE_GET ++ * @brief Get the frequency scaling value used on IEEE 1588 module ++ */ ++#define IOCTL_1588_TICK_RATE_GET _IOR(IOC_1588_BASE, 8, unsigned long) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_TARG_TIME_INTRPT_ENABLE ++ * @brief Enable the target time reached/exceeded interrupt on IEEE 1588 module ++ */ ++#define IOCTL_1588_TARG_TIME_INTRPT_ENABLE _IO(IOC_1588_BASE, 9) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_TARG_TIME_INTRPT_DISABLE ++ * @brief Disable the target time reached/exceeded interrupt on IEEE 1588 module ++ */ ++#define IOCTL_1588_TARG_TIME_INTRPT_DISABLE _IO(IOC_1588_BASE, 10) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_TARG_TIME_POLL ++ * @brief Poll for the target time reached/exceeded condition on IEEE 1588 ++ * module ++ */ ++#define IOCTL_1588_TARG_TIME_POLL \ ++ _IOR(IOC_1588_BASE, 11, struct ioh1588TimePollIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_TARG_TIME_SET ++ * @brief Set the target time to match on IEEE 1588 module ++ */ ++#define IOCTL_1588_TARG_TIME_SET \ ++ _IOW(IOC_1588_BASE, 12, struct ioh1588TimeValue) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_TARG_TIME_GET ++ * @brief Get the target time currently set on IEEE 1588 module ++ */ ++#define IOCTL_1588_TARG_TIME_GET \ ++ _IOR(IOC_1588_BASE, 13, struct ioh1588TimeValue) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TIME_INTRPT_ENABLE ++ * @brief Enable the auxiliary time captured interrupt on IEEE 1588 module ++ */ ++#define IOCTL_1588_AUX_TIME_INTRPT_ENABLE \ ++ _IOW(IOC_1588_BASE, 14, enum ioh1588AuxMode) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TIME_INTRPT_DISABLE ++ * @brief Disable the auxiliary time captured interrupt on IEEE 1588 module ++ */ ++#define IOCTL_1588_AUX_TIME_INTRPT_DISABLE \ ++ _IOW(IOC_1588_BASE, 15, enum ioh1588AuxMode) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TIME_POLL ++ * @brief Poll for the auxiliary time captured on IEEE 1588 module ++ */ ++#define IOCTL_1588_AUX_TIME_POLL \ ++ _IOWR(IOC_1588_BASE, 16, struct ioh1588TimePollIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_RESET ++ * @brief Reset the IEEE 1588 module ++ */ ++#define IOCTL_1588_RESET _IO(IOC_1588_BASE, 17) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_CHNL_RESET ++ * @brief Reset the IEEE 1588 channel ++ */ ++#define IOCTL_1588_CHNL_RESET _IOW(IOC_1588_BASE, 18, enum ioh1588PTPPort) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_STATS_GET ++ * @brief Get the timestamp captured counters from the IEEE 1588 module ++ */ ++#define IOCTL_1588_STATS_GET _IOR(IOC_1588_BASE, 19, struct ioh1588Stats) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_STATS_RESET ++ * @brief Reset the timestamp captured counters maintained for IEEE 1588 module ++ */ ++#define IOCTL_1588_STATS_RESET _IO(IOC_1588_BASE, 20) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_SHOW_ALL ++ * @brief Display the register contents of IEEE 1588 module ++ */ ++#define IOCTL_1588_SHOW_ALL _IO(IOC_1588_BASE, 21) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TARG_TIME_INTRPT_ENABLE ++ * @brief Enable Auxiliary target time reached interrupt - not supported ++ */ ++#define IOCTL_1588_AUX_TARG_TIME_INTRPT_ENABLE _IO(IOC_1588_BASE, 22) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TARG_TIME_INTRPT_DISABLE ++ * @brief Disable Auxiliary target time reached interrupt - not supported ++ */ ++#define IOCTL_1588_AUX_TARG_TIME_INTRPT_DISABLE _IO(IOC_1588_BASE, 23) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TARG_TIME_POLL ++ * @brief Poll for Auxiliary target time captured - not supported ++ */ ++#define IOCTL_1588_AUX_TARG_TIME_POLL \ ++ _IOR(IOC_1588_BASE, 24, struct ioh1588TimePollIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TARG_TIME_SET ++ * @brief Set Auxiliary target time - not supported ++ */ ++#define IOCTL_1588_AUX_TARG_TIME_SET \ ++ _IOW(IOC_1588_BASE, 25, struct ioh1588TimeValue) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TARG_TIME_GET ++ * @brief Get Auxiliary target time currently set - not supported ++ */ ++#define IOCTL_1588_AUX_TARG_TIME_GET \ ++ _IOR(IOC_1588_BASE, 26, struct ioh1588TimeValue) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PULSE_PER_SEC_INTRPT_ENABLE ++ * @brief Enable Pulse per second match interrupt ++ */ ++#define IOCTL_1588_PULSE_PER_SEC_INTRPT_ENABLE _IO(IOC_1588_BASE, 27) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PULSE_PER_SEC_INTRPT_DISABLE ++ * @brief Disable Pulse per second match interrupt ++ */ ++#define IOCTL_1588_PULSE_PER_SEC_INTRPT_DISABLE _IO(IOC_1588_BASE, 28) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_TARG_TIME_NOTIFY ++ * @brief Block till a target time reached interrupt occurs ++ */ ++#define IOCTL_1588_TARG_TIME_NOTIFY \ ++ _IOR(IOC_1588_BASE, 29, struct ioh1588TimeValue) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TIME_NOTIFY ++ * @brief Block till an auxiliary time captured interrupt occurs ++ */ ++#define IOCTL_1588_AUX_TIME_NOTIFY \ ++ _IOR(IOC_1588_BASE, 30, struct ioh1588AuxTimeIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TARG_TIME_NOTIFY ++ * @brief Block till an auxiliary target time reached interrupt occurs - not ++ * supported ++ */ ++#define IOCTL_1588_AUX_TARG_TIME_NOTIFY \ ++ _IOR(IOC_1588_BASE, 31, struct ioh1588TimeValue) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PULSE_PER_SEC_NOTIFY ++ * @brief Block till a pulse per second match interrupt occurs ++ */ ++#define IOCTL_1588_PULSE_PER_SEC_NOTIFY _IOR(IOC_1588_BASE, 32, unsigned long) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_TARG_TIME_CLR_NOTIFY ++ * @brief Unblock a process waiting on target time reached interrupt ++ */ ++#define IOCTL_1588_TARG_TIME_CLR_NOTIFY _IO(IOC_1588_BASE, 33) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TIME_CLR_NOTIFY ++ * @brief Unblock a process waiting on auxiliary time captured interrupt ++ */ ++#define IOCTL_1588_AUX_TIME_CLR_NOTIFY _IO(IOC_1588_BASE, 34) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_AUX_TARG_TIME_CLR_NOTIFY ++ * @brief Unblock a process waiting on an auxiliary target time reached ++ * interrupt - not supported ++ */ ++#define IOCTL_1588_AUX_TARG_TIME_CLR_NOTIFY _IO(IOC_1588_BASE, 35) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PULSE_PER_SEC_CLR_NOTIFY ++ * @brief Unblock a process waiting on a pulse per second match interrupt ++ */ ++#define IOCTL_1588_PULSE_PER_SEC_CLR_NOTIFY _IO(IOC_1588_BASE, 36) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PULSE_PER_SEC_TIME_GET ++ * @brief Get the currently specified pulse per second match time ++ */ ++#define IOCTL_1588_PULSE_PER_SEC_TIME_GET _IOR(IOC_1588_BASE, 37, unsigned long) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PULSE_PER_SEC_TIME_SET ++ * @brief Specify the pulse per second match time ++ */ ++#define IOCTL_1588_PULSE_PER_SEC_TIME_SET _IOW(IOC_1588_BASE, 38, unsigned long) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PORT_VERSION_SET ++ * @brief Set the PTP version to be used on the given PTP channel ++ */ ++#define IOCTL_1588_PORT_VERSION_SET \ ++ _IOW(IOC_1588_BASE, 39, struct ioh1588VersionIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PORT_VERSION_GET ++ * @brief Get the PTP version used on the given PTP channel ++ */ ++#define IOCTL_1588_PORT_VERSION_GET \ ++ _IOWR(IOC_1588_BASE, 40, struct ioh1588VersionIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PORT_OPERATION_MODE_SET ++ * @brief Set the PTP messages that are matched by the module on the given PTP ++ * channel ++ */ ++#define IOCTL_1588_PORT_OPERATION_MODE_SET \ ++ _IOW(IOC_1588_BASE, 41, struct ioh1588OperationModeIoctl) ++ ++/*! @ingroup IEEE_1588_InterfaceLayer ++ * @def IOCTL_1588_PORT_OPERATION_MODE_GET ++ * @brief Get the PTP messages that are currently matched by the module on given ++ * PTP channel ++ */ ++#define IOCTL_1588_PORT_OPERATION_MODE_GET \ ++ _IOWR(IOC_1588_BASE, 42, struct ioh1588OperationModeIoctl) ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @enum ioh1588PTPPort ++ * @brief IEEE 1588 PTP Communication Port(Channel) ++ */ ++enum ioh1588PTPPort { /* ioh1588PTPPort */ ++ IOH_1588_GBE_0_1588PTP_PORT, /**< PTP Communication Port on GBE-0 */ ++ IOH_1588_CAN_0_1588PTP_PORT, /**< PTP Communication Port on CAN-0 */ ++ IOH_1588_PORT_INVALID /**< Invalid PTP Communication Port */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @enum ioh1588PTPPortMode ++ * @brief PTP Port mode - Master or Slave or any ++ */ ++enum ioh1588PTPPortMode { /* ioh1588PTPPortMode */ ++ IOH_1588PTP_PORT_MASTER, /**< Master Mode */ ++ IOH_1588PTP_PORT_SLAVE, /**< Slave Mode */ ++ IOH_1588PTP_PORT_ANYMODE, /**< Timestamp all messages */ ++ IOH_1588PTP_PORT_MODE_INVALID /**< Invalid PTP Port Mode */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @struct ioh1588PortCfgIoctl ++ * @brief Struct to pass port config data for ioctl call ++ */ ++struct ioh1588PortCfgIoctl { /* ioh1588PortCfgIoctl */ ++ enum ioh1588PTPPort ptpPort; /**< IEEE 1588 PTP Communication Port */ ++ enum ioh1588PTPPortMode ptpPortMode; /**< Master, Slave, ++ or Any mode */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @enum ioh1588PTPMsgType ++ * @brief PTP Messages types that can be detected on communication port ++ */ ++enum ioh1588PTPMsgType { /* ioh1588PTPMsgType */ ++ IOH_1588PTP_MSGTYPE_SYNC, /**< PTP Sync message sent by Master or ++ received by Slave */ ++ IOH_1588PTP_MSGTYPE_DELAYREQ, /**< PTP Delay_Req message sent by Slave ++ or received by Master */ ++ IOH_1588PTP_MSGTYPE_UNKNOWN /**< Other PTP and non-PTP message sent ++ or received by both Master ++ and/or Slave */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @struct ioh1588TimeValue ++ * @brief Struct to hold 64 bit SystemTime and TimeStamp values ++ */ ++struct ioh1588TimeValue { /* ioh1588TimeValue */ ++ unsigned long timeValueLowWord; /**< Lower 32 bits of time value */ ++ unsigned long timeValueHighWord; /**< Upper 32 bits of time value */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @struct ioh1588Uuid ++ * @brief Struct to hold 48 bit UUID values captured in Sync or Delay_Req ++ * messages ++ */ ++struct ioh1588Uuid{ /* ioh1588Uuid */ ++ unsigned long uuidValueLowWord; /**< The lower 32 bits of UUID */ ++ unsigned long uuidValueHighHalfword; /**< The upper 16 bits of UUID */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @struct ioh1588PtpMsgData ++ * @brief Struct for data from the PTP message returned when TimeStamp ++ * available ++ */ ++struct ioh1588PtpMsgData{ /* ioh1588PtpMsgData */ ++ enum ioh1588PTPMsgType ptpMsgType; /**< PTP Messages type */ ++ struct ioh1588TimeValue ptpTimeStamp; /**< 64 bit TimeStamp value from ++ PTP Message */ ++ struct ioh1588Uuid ptpUuid; /**< 48 bit UUID value from the ++ PTP Message */ ++ unsigned int ptpSequenceNumber; /**< 16 bit Sequence Number from PTP ++ Message */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @struct ioh1588RxTxPollIoctl ++ * @brief Struct to pass PTP message data for ioctl call ++ */ ++struct ioh1588RxTxPollIoctl{ /* ioh1588RxTxPollIoctl */ ++ enum ioh1588PTPPort ptpPort; /**< IEEE 1588 PTP Communication Port */ ++ struct ioh1588PtpMsgData ptpMsgData; /**< PTP message data */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @struct ioh1588CANPollIoctl ++ * @brief Struct to pass CAN timestamp data for ioctl call ++ */ ++struct ioh1588CANPollIoctl{ /* ioh1588CANPollIoctl */ ++ enum ioh1588PTPPort ptpPort; /**< IEEE 1588 PTP Communication ++ Port */ ++ struct ioh1588TimeValue ptpTimeStamp; /**< CAN PTP timestamp */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @enum ioh1588AuxMode ++ * @brief Master or Slave Auxiliary Time Stamp (Snap Shot) ++ */ ++enum ioh1588AuxMode{ /* ioh1588AuxMode */ ++ IOH_1588_AUXMODE_MASTER, /**< Auxiliary Master Mode */ ++ IOH_1588_AUXMODE_SLAVE, /**< Auxiliary Slave Mode */ ++ IOH_1588_AUXMODE_INVALID /**< Invalid Auxiliary Mode */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @struct ioh1588TimePollIoctl ++ * @brief Struct to pass timestamp data for ioctl call ++ */ ++struct ioh1588TimePollIoctl { /* ioh1588TimePollIoctl */ ++ unsigned long pollFlag; /**< time event */ ++ struct ioh1588TimeValue timeVal; /**< timestamp value */ ++ enum ioh1588AuxMode auxMode; /**< Master or Slave mode */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @struct ioh1588Stats ++ * @brief Provides the number of times timestamps are locked for rx and tx ++ * PTP ++ * messages. The counters are reinitialized when the module is ++ * reset. ++ */ ++struct ioh1588Stats { /* ioh1588Stats */ ++ unsigned long rxMsgs; /**< Count of timestamps for received PTP Msgs */ ++ unsigned long txMsgs; /**< Count of timestamps for transmitted PTP ++ Msgs */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @struct ioh1588AuxTimeIoctl ++ * @brief Struct to pass aux time data for ioctl call ++ */ ++struct ioh1588AuxTimeIoctl { /* ioh1588AuxTimeIoctl */ ++ enum ioh1588AuxMode auxMode; /**< aux mode: master or slave */ ++ struct ioh1588TimeValue auxTime; /**< aux time snapshot */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @enum ioh1588PTPVersion ++ * @brief 1588 PTP version value that can be detected on communication ++ * port ++ */ ++enum ioh1588PTPVersion { /* ioh1588PTPVersion */ ++ IOH_1588PTP_VERSION_0, /**< support version 1 only */ ++ IOH_1588PTP_VERSION_1, /**< support both version 1 and version ++ 2 */ ++ IOH_1588PTP_VERSION_INVALID /**< Invalid version */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @struct ioh1588VersionIoctl ++ * @brief Struct to pass timestamp data for ioctl call ++ */ ++struct ioh1588VersionIoctl { /* ioh1588VersionIoctl */ ++ enum ioh1588PTPPort ptpPort; /**< IEEE 1588 PTP Communication Port */ ++ enum ioh1588PTPVersion ptpVersion; /**< version value */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @enum ioh1588VersionIoctl ++ * @brief 1588 PTP operation mode value that can be detected on ++ * communication port ++ */ ++enum ioh1588PTPOperationMode { /* ioh1588PTPOperationMode */ ++ IOH_1588PTP_OP_MODE_SYNC_DELAYREQ_MSGS, ++ /**< timestamp version 1 SYNC and DELAYED_REQ only */ ++ IOH_1588PTP_OP_MODE_V1_ALL_MSGS, ++ /**< timestamp version 1 all messages */ ++ IOH_1588PTP_OP_MODE_V1_V2_EVENT_MSGS, ++ /**< timestamp version 1 and 2 event messages only */ ++ IOH_1588PTP_OP_MODE_V1_V2_ALL_MSGS, ++ /**< timestamp version 1 and 2 all messages */ ++ IOH_1588PTP_OP_MODE_INVALID /**< Invalid mode */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_InterfaceLayer ++ * @struct ioh1588OperationModeIoctl ++ * @brief Struct to pass timestamp data for ioctl call ++ */ ++struct ioh1588OperationModeIoctl { /* ioh1588OperationModeIoctl */ ++ enum ioh1588PTPPort ptpPort; /**< IEEE 1588 PTP Communication ++ Port */ ++ enum ioh1588PTPOperationMode ptpOpMode; /**< IEEE 1588 operation mode */ ++}; ++ ++/** ++ * @ingroup IEEE_1588_Global ++ * @enum ioh_status ++ * @brief The status as returned from the HAL ++ */ ++enum ioh_status { /* ioh_status */ ++ IOH_1588_SUCCESS, /**< operation successful */ ++ IOH_1588_INVALIDPARAM, /**< parameter passed is invalid */ ++ IOH_1588_NOTIMESTAMP, /**< no time stamp available when ++ polled */ ++ IOH_1588_INTERRUPTMODEINUSE, /**< while operating in interrupt mode, ++ polling not permitted */ ++ IOH_1588_FAILED, /**< Internal error in driver */ ++ IOH_1588_UNSUPPORTED, /**< Implementation does not support ++ this feature */ ++}; ++ ++/* IEEE 1588 registers to save and restore on suspend/resume */ ++ ++/** @ingroup IEEE_1588_Global ++ * @struct ioh_1588_regs_set ++ * @brief IEEE 1588 registers to save and restore on suspend/resume ++ */ ++struct ioh_1588_regs_set { ++ unsigned long ts_control; ++ unsigned long ts_event; /* not saved, cleared on restore */ ++ unsigned long ts_addend; ++ unsigned long ts_accum; /* not saved/restored */ ++ unsigned long ts_test; /* not saved/restored */ ++ unsigned long ts_compare; ++ unsigned long ts_syslo; ++ unsigned long ts_syshi; ++ unsigned long ts_tgtlo; ++ unsigned long ts_tgthi; ++ unsigned long ts_asmslo; /* not saved/restored */ ++ unsigned long ts_asmshi; /* not saved/restored */ ++ unsigned long ts_ammslo; /* not saved/restored */ ++ unsigned long ts_ammshi; /* not saved/restored */ ++ ++ /* Ethernet */ ++ unsigned long ts_cc; ++ unsigned long ts_ce; /* not saved, cleared on restore */ ++ unsigned long ts_xslo; /* not saved/restored */ ++ unsigned long ts_xshi; /* not saved/restored */ ++ unsigned long ts_rslo; /* not saved/restored */ ++ unsigned long ts_rshi; /* not saved/restored */ ++ unsigned long ts_uuidlo; /* not saved/restored */ ++ unsigned long ts_uuidhi; /* not saved/restored */ ++ ++ /* CAN */ ++ unsigned long ts_cce; /* not saved, cleared on restore */ ++ unsigned long ts_cxslo; /* not saved/restored */ ++ unsigned long ts_cxshi; /* not saved/restored */ ++ ++ unsigned long ts_sel; /* Selector */ ++ unsigned char ts_sti[6]; /* station addresses */ ++}; ++ ++/* callback function prototypes */ ++extern void target_time_callback(struct ioh1588TimeValue targetTime); ++extern void auxiliary_time_callback(enum ioh1588AuxMode aux_mode, \ ++ struct ioh1588TimeValue auxTime); ++extern void pulse_per_sec_callback(unsigned long pps); ++#endif /* IOH_1588_H */ +diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.c topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.c +--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.c 1970-01-01 09:00:00.000000000 +0900 ++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.c 2010-03-09 10:32:42.000000000 +0900 +@@ -0,0 +1,700 @@ ++ /*! ++ * @file ioh_1588_pci.c ++ * @brief ++ * This file contains the definitions of IEEE_1588_PCILayer APIs ++ * @version 0.92 ++ * @section ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * History: ++ * modified to support Intel IOH GE IEEE 1588 hardware ++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. ++ * All rights reserved. ++ * derived from ++ * IEEE 1588 Time Synchronization Driver for Intels EP80579 ++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ */ ++ ++#include "pch_1588_pci.h" ++#include "pch_1588_hal.h" ++#include "pch_debug.h" ++ ++#ifdef CONFIG_PM ++static int ioh_1588_suspend(struct pci_dev *pdev, pm_message_t state); ++static int ioh_1588_resume(struct pci_dev *pdev); ++#endif ++static int ioh_1588_probe(struct pci_dev *pdev, const struct pci_device_id *id); ++static void ioh_1588_remove(struct pci_dev *pdev); ++ ++/*! @ingroup IEEE_1588_PCILayerFacilitators ++ * @struct ioh_1588_pcidev_id ++ * @brief PCI device ids supported by this driver ++ * @remarks This structure is used to specify the Ids of the ++ * devices supported by the driver module during ++ * registering of the module as PCI driver.The values ++ * within the structure is maintained by the kernel ++ * subsystem to recognize the individual devices ++ * when they are attached to the system. Depending ++ * on this the corresponding device functionalities ++ * such as probe, remove, suspend,... are invoked. ++ * ++ * @note This structure contains the Vendor and device ++ * IDs of the device supported by the driver module. ++ * ++ * @see ++ * - ioh_1588_pcidev ++ * <hr> ++ */ ++static const struct pci_device_id ioh_1588_pcidev_id[] = { ++ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_IOH_1588)}, ++ {0}, ++}; ++ ++/* Linux pci operations */ ++/*! @ingroup IEEE_1588_PCILayerFacilitators ++* @struct ioh_1588_pcidev ++* @brief Store the references of PCI driver interfaces to kernel. ++* @remarks This strutcure is used to specify the driver specific ++* functionalities to the kernel subsystem. The kernel invokes ++* these functionalities depending on the supported device and ++* the events that occured. ++* ++* @note This structure is registered with the kernel via the call ++* pci_register_driver from @ref ioh_1588_init ++* @see ++* - ioh_1588_init ++* - ioh_1588_exit ++*<hr> ++*/ ++ ++static struct pci_driver ioh_1588_pcidev = { ++ .name = DRIVER_NAME, ++ .id_table = ioh_1588_pcidev_id, ++ .probe = ioh_1588_probe, ++ .remove = ioh_1588_remove, ++#ifdef CONFIG_PM ++ .suspend = ioh_1588_suspend, ++ .resume = ioh_1588_resume, ++#endif ++}; ++ ++/* instance of driver data structure */ ++/*! @ingroup IEEE_1588_PCILayerFacilitators ++ * @var ioh_1588_dev ++ * @brief instance of driver data structure ++ * @see ++ * - ioh_1588_probe ++ * - ioh_1588_init ++ * - ioh_1588_remove ++ * - ioh_1588_suspend ++ * - ioh_1588_resume ++ * <hr> ++ */ ++static struct ioh_1588_dev ioh_1588_dev; ++ ++/*! @ingroup IEEE_1588_Global ++ * @var ioh_1588_devp ++ * @brief Pointer to driver data structure ++ * @see ++ * - ioc_handle_notify ++ * - ioc_handle_clr_notify ++ * - ioc_handle_reset ++ * - target_time_callback ++ * - auxiliary_time_callback ++ * - pulse_per_sec_callback ++ * - ioh_1588_open ++ * <hr> ++ */ ++ ++struct ioh_1588_dev *ioh_1588_devp = &ioh_1588_dev; ++ ++/*! @ingroup IEEE_1588_PCILayerFacilitators ++ * @struct ioh_1588_params_ ++ * @brief structure to hold the module parameters ++ * @see ++ * - ioh_1588_init ++ * - ioh_1588_probe ++ * <hr> ++ */ ++static struct ioh_1588_params_ { ++ /* module parameters */ ++ int eth_enable; /**< IEEE 1588 on ethernet interface ++ 0=Disabled 1=Enabled (default 1)*/ ++ int can_enable; /**< IEEE 1588 on CAN interface ++ 0=Disabled 1=Enabled (default 0)*/ ++ int major; /**< IEEE 1588 device major number to ++ use (default system assigned)*/ ++ unsigned char station[STATION_ADDR_LEN]; /**< IEEE 1588 station address ++ to use - column separated hex values*/ ++} ioh_1588_param = { ++1, 0, 0, "00:00:00:00:00:00"}; ++ ++module_param_named(eth_enable, ioh_1588_param.eth_enable, bool, 0444); ++MODULE_PARM_DESC(eth_enable, ++ "IEEE 1588 on ethernet interface 0=Disabled 1=Enabled \ ++ (default 1)"); ++ ++module_param_named(can_enable, ioh_1588_param.can_enable, bool, 0444); ++MODULE_PARM_DESC(can_enable, ++ "IEEE 1588 on CAN interface 0=Disabled 1=Enabled (default 0)"); ++ ++module_param_named(major, ioh_1588_param.major, int, 0444); ++MODULE_PARM_DESC(major, ++ "IEEE 1588 device major number to use (default system \ ++ assigned)"); ++ ++module_param_string(station, ioh_1588_param.station, ++ sizeof ioh_1588_param.station, 0444); ++MODULE_PARM_DESC(station, ++ "IEEE 1588 station address to use - column separated hex \ ++ values"); ++ ++/*!@ingroup IEEE_1588_PCILayerAPI ++ * @fn int ioh_1588_probe(struct pci_dev *pdev,const struct pci_device_id *id) ++ * @brief ++ * This function is called right after insmod by the PCI core. Here we enable ++ * the ++ * device to make the device's resources live. We can then read PCI CFG space ++ * and init the device. ++ * ++ * @remarks ++ * The main tasks performed by this method are: ++ * - Allocate PCI resource required using ++ * request_mem_region API ++ * and map the memory to kernel virtual space using ++ * ioremap API. ++ * - Enable the PCI device using pci_enable_device ++ * API. ++ * - Initialize global variables and wait queues ++ * using ++ * init_waitqueue_head API ++ * - Set the memory address to be used by the HAL ++ * using ioh_1588_blpl_base_address_set API ++ * - Register the interrupt handler using request_irq ++ * API ++ * - Register the charecter driver using ++ * sregister_chrdev_region/ ++ * alloc_chrdev_region APIs based on whether major ++ * number has been ++ * provided by the user or not. ++ * - Add the device to the system using the APIs ++ * cdev_init and ++ * cdev_add. ++ * - If any of the above calls fail, undo the steps ++ * performed before the failure and return ++ * appropraite error ++ * status. ++ * - Depending on the parameters passed during module ++ * load, ++ * enable/disable PTP clock synchronization control ++ * on GbE ++ * (using ioh_1588_eth_enable/ioh_1588_eth_disable ++ * API). /CAN ++ * (using ioh_1588_can_enable/ioh_1588_can_disable ++ * API) channel. ++ * - Set the Station address as specified in the ++ * module ++ * parameter using ioh_1588_set_station_address ++ * API ++ * -Note: For A0/A1 sample, test mode setting is enabled for ++ * the 64 bit System Time Register. This is a work around ++ * for ++ * the non continuous value in the 64 bit System Time ++ * Register ++ * consisting of High(32bit) / Low(32bit) ++ * ++ * ++ * @param pdev [INOUT] pci device structure ++ * @param id [IN] list of devices supported by this driver ++ * ++ * @return int ++ * - 0 Success ++ * - -ENODEV request_mem_region or ioremap or ++ * pci_enable_device or request_irq error ++ * ++ * @see ++ * - ioh_1588_pcidev ++ * <hr> ++ */ ++ ++static int __devinit ++ioh_1588_probe(struct pci_dev *pdev, const struct pci_device_id *id) ++{ ++ int ret = 0; ++ dev_t devno; ++ int i; ++ ++ UNUSED_ARG(id); ++ ++ /* enable the 1588 pci device */ ++ ret = pci_enable_device(pdev); ++ if (ret != 0) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_probe:could not enable the pci device\n"); ++ goto exit_error; ++ } ++ IOH_DEBUG("ioh_1588_probe:pci_enable_device success\n"); ++ ++ ioh_1588_dev.mem_base = pci_resource_start(pdev, IO_MEM_BAR); ++ ++ if (!ioh_1588_dev.mem_base) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_probe: could not locate IO memory address\n"); ++ /*disable the pci device */ ++ pci_disable_device(pdev); ++ ret = -ENODEV; ++ goto exit_error; ++ } ++ IOH_DEBUG("ioh_1588_probe:allocated IO memory address\n"); ++ ++ /* retreive the available length of the IO memory space */ ++ ioh_1588_dev.mem_size = pci_resource_len(pdev, IO_MEM_BAR); ++ ++ /* allocate the memory for the device registers */ ++ if (!request_mem_region ++ (ioh_1588_dev.mem_base, ioh_1588_dev.mem_size, "1588_regs")) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_probe: could not allocate register memory \ ++ space\n"); ++ ioh_1588_dev.mem_base = 0; ++ /*disable the pci device */ ++ pci_disable_device(pdev); ++ ret = -EBUSY; ++ goto exit_error; ++ } ++ IOH_DEBUG("ioh_1588_probe:allocated register memory space\n"); ++ ++ /* get the virtual address to the 1588 registers */ ++ ioh_1588_dev.mem_virt = ++ ioremap(ioh_1588_dev.mem_base, ioh_1588_dev.mem_size); ++ ++ if (!ioh_1588_dev.mem_virt) { ++ pci_disable_device(pdev); ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_probe: Could not get virtual address\n"); ++ /*release memory acquired for device registers */ ++ release_mem_region(ioh_1588_dev.mem_base, ++ ioh_1588_dev.mem_size); ++ ioh_1588_dev.mem_base = 0; ++ /*disable the pci device */ ++ pci_disable_device(pdev); ++ ret = -ENOMEM; ++ goto exit_error; ++ } ++ IOH_DEBUG("ioh_1588_probe:obtained virtual address=%p\n", ++ ioh_1588_dev.mem_virt); ++ ++ for (i = 0; i < NUM_EVENTS; i++) { ++ init_waitqueue_head(&ioh_1588_dev.notify_evt[i]); ++ ioh_1588_dev.event_flags[i] = 0; ++ } ++ IOH_DEBUG("ioh_1588_probe:initialized wait queue heads\n"); ++ ++ ret = ++ ioh_1588_blpl_base_address_set((unsigned int)ioh_1588_dev.mem_virt); ++ if (ret != IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_probe: ioh_1588_blpl_base_address_set \ ++ failed\n"); ++ /*unmap io */ ++ iounmap(ioh_1588_dev.mem_virt); ++ ioh_1588_dev.mem_virt = 0; ++ /*release memory acquired for device */ ++ release_mem_region(ioh_1588_dev.mem_base, ++ ioh_1588_dev.mem_size); ++ ioh_1588_dev.mem_base = 0; ++ /*disable device */ ++ pci_disable_device(pdev); ++ goto exit_error; ++ } ++ IOH_DEBUG("ioh_1588_probe:set base address\n"); ++ ++ ret = request_irq(pdev->irq, &ioh_1588_isr, IRQF_SHARED, DRIVER_NAME, ++ &ioh_1588_dev); ++ if (ret != 0) { ++ IOH_LOG(KERN_ERR, "ioh_1588_probe: failed to get irq %d\n", ++ pdev->irq); ++ /*unmap io */ ++ iounmap(ioh_1588_dev.mem_virt); ++ ioh_1588_dev.mem_virt = 0; ++ /*release memory acquired for device */ ++ release_mem_region(ioh_1588_dev.mem_base, ++ ioh_1588_dev.mem_size); ++ ioh_1588_dev.mem_base = 0; ++ /*disable device */ ++ pci_disable_device(pdev); ++ goto exit_error; ++ } ++ IOH_DEBUG("ioh_1588_probe:registered IRQ handler successfully\n"); ++ ++ /*register the module */ ++ if (ioh_1588_param.major != 0) { /* user specified a major ++ number, use it */ ++ IOH_DEBUG("ioh_1588_probe:using user specified major number\n"); ++ devno = MKDEV(ioh_1588_param.major, 0); ++ ret = register_chrdev_region(devno, 1, DRIVER_NAME); ++ ioh_1588_dev.devno = devno; /* store it */ ++ } else { /* request and reserve a device number */ ++ ++ IOH_DEBUG ++ ("ioh_1588_probe:dynamically allocating major number\n"); ++ ret = ++ alloc_chrdev_region(&ioh_1588_dev.devno, 0, 1, DRIVER_NAME); ++ devno = MKDEV(MAJOR(ioh_1588_dev.devno), 0); ++ } ++ if (ret < 0) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_probe: Could not register module (major %d)\ ++ \n", ++ ioh_1588_param.major); ++ /*free irq */ ++ free_irq(pdev->irq, &ioh_1588_dev); ++ /*unmap io */ ++ iounmap(ioh_1588_dev.mem_virt); ++ ioh_1588_dev.mem_virt = 0; ++ /*release memory acquired for device */ ++ release_mem_region(ioh_1588_dev.mem_base, ++ ioh_1588_dev.mem_size); ++ ioh_1588_dev.mem_base = 0; ++ /*disable device */ ++ pci_disable_device(pdev); ++ goto exit_error; ++ } ++ IOH_DEBUG("ioh_1588_probe:registered the module(major %d)\n", ++ ioh_1588_param.major); ++ ++ /* init cdev struct for adding device to kernel */ ++ cdev_init(&ioh_1588_dev.cdev, &ioh_1588_fops); ++ ioh_1588_dev.cdev.owner = THIS_MODULE; ++ ioh_1588_dev.cdev.ops = &ioh_1588_fops; ++ ++ ret = cdev_add(&ioh_1588_dev.cdev, devno, 1); ++ if (ret != 0) { ++ IOH_LOG(KERN_ERR, "ioh_1588_probe: cdev_add failed\n"); ++ /*free region allocated for char device */ ++ unregister_chrdev_region(ioh_1588_dev.devno, 1); ++ /*free irq */ ++ free_irq(pdev->irq, &ioh_1588_dev); ++ /*unmap io */ ++ iounmap(ioh_1588_dev.mem_virt); ++ ioh_1588_dev.mem_virt = 0; ++ /*release memory acquired for device */ ++ release_mem_region(ioh_1588_dev.mem_base, ++ ioh_1588_dev.mem_size); ++ ioh_1588_dev.mem_base = 0; ++ /*disable device */ ++ pci_disable_device(pdev); ++ goto exit_error; ++ } ++ IOH_DEBUG("ioh_1588_probe: cdev_add successful\n"); ++ ++ ioh_1588_dev.initialized = 1; ++ /* indicate success */ ++ ioh_1588_dev.irq = pdev->irq; ++ ++ /*reset the ieee1588 h/w */ ++ ioh_1588_reset(); ++ ++ if (ioh_1588_param.eth_enable != 0) { /* Enable by default */ ++ IOH_DEBUG("ioh_1588_probe: invoking ioh_1588_eth_enable \ ++ to enable ethernet\n"); ++ (void)ioh_1588_eth_enable(); ++ } else { ++ IOH_DEBUG("ioh_1588_probe: invoking ioh_1588_eth_disable \ ++ to disable ethernet\n"); ++ (void)ioh_1588_eth_disable(); ++ } ++ if (ioh_1588_param.can_enable == 1) { /* Enable if requested */ ++ IOH_DEBUG("ioh_1588_probe: invoking ioh_1588_can_enable \ ++ to enable CAN\n"); ++ (void)ioh_1588_can_enable(); ++ } else { ++ IOH_DEBUG("ioh_1588_probe: invoking ioh_1588_can_disable \ ++ to disable CAN\n"); ++ (void)ioh_1588_can_disable(); ++ } ++ if (strcmp(ioh_1588_param.station, "00:00:00:00:00:00") != 0) { ++ if (ioh_1588_set_station_address(ioh_1588_param.station) != ++ IOH_1588_SUCCESS) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_probe: Invalid station address \ ++ parameter\n" ++ "Module loaded; But, station address not set \ ++ correctly\n"); ++ } ++ } ++ IOH_DEBUG("ioh_1588_probe: probe succeeded\n"); ++ ++ return 0; ++ ++exit_error: ++ ++ IOH_LOG(KERN_ERR, "ioh_1588_probe: probe failed\n"); ++ return ret; ++} ++ ++/*! @ingroup IEEE_1588_PCILayerAPI ++ * @fn void ioh_1588_remove(struct pci_dev *pdev) ++ * @brief ++ * This function is called when the pci driver is being unloaded from the ++ * kernel. ++ * @remarks ++ * The main tasks performed by this method are: ++ * - Free the interrupt line using free_irq API. ++ * - Disable the PCI device using pci_disable_device API. ++ * - Unmap the PCI memory and release the same using iounmap API. ++ * - Delete the char device from the system using cdev_del API. ++ * - Unregister the driver using unregister_chrdev_region API. ++ * ++ * @param pdev [INOUT] pci device structure ++ * ++ * @return None ++ *@see ++ - ioh_1588_pcidev ++ * ++ * <hr> ++ */ ++ ++static void __devexit ioh_1588_remove(struct pci_dev *pdev) ++{ ++ /* disable the interrupts on the 1588 hardware */ ++ IOH_DEBUG("ioh_1588_remove: disabling interrupts by \ ++ invoking ioh_1588_disable_interrupts\n"); ++ (void)ioh_1588_disable_interrupts(); ++ ++ /* free the interrupt */ ++ if (pdev->irq != 0) { ++ free_irq(pdev->irq, &ioh_1588_dev); ++ IOH_DEBUG("ioh_1588_remove: unregistered IRQ handler\n"); ++ } ++ ++ /* unmap the virtual IO memory space */ ++ if (ioh_1588_dev.mem_virt != 0) { ++ iounmap(ioh_1588_dev.mem_virt); ++ IOH_DEBUG ++ ("ioh_1588_remove: unmaped the virtual IO memory space\n"); ++ } ++ ++ /* release the reserved IO memory space */ ++ if (ioh_1588_dev.mem_base != 0) { ++ release_mem_region(ioh_1588_dev.mem_base, ++ ioh_1588_dev.mem_size); ++ IOH_DEBUG ++ ("ioh_1588_remove: released the reserved IO memory \ ++ space\n"); ++ } ++ ++ /* remove cdev struct from system */ ++ cdev_del(&ioh_1588_dev.cdev); ++ IOH_DEBUG("ioh_1588_remove: removed the cdev from system\n"); ++ ++ unregister_chrdev_region(ioh_1588_dev.devno, 1); ++ IOH_DEBUG("ioh_1588_remove:unregisterd the module\n"); ++ ++ /*disable the device */ ++ pci_disable_device(pdev); ++ IOH_DEBUG("ioh_1588_remove:disabled the device\n"); ++ ++ IOH_LOG(KERN_ERR, "ioh_1588_remove: complete\n"); ++} ++ ++#ifdef CONFIG_PM ++/*! @ingroup IEEE_1588_PCILayerAPI ++ * @fn int ioh_1588_suspend(struct pci_dev *pdev,pm_message_t state) ++ * @brief ++ * This function is called to suspend a device before being put into a ++ * low power state. ++ * ++ * @remarks ++ * The main tasks performed by this method are: ++ * - Save PCI configuration space by invoking pci_save_state API. ++ * - If the above step fails, return the error from pci_save_state ++ * API. ++ * - Disable the PCI device using the pci_disable_device API. ++ * - Put the device to new power state using pci_set_power_state ++ * API. ++ * ++ * ++ * @param pdev [INOUT] pci device structure ++ * @param state [IN] suspend state ++ * ++ * @return int ++ * - 0 on success ++ * - -ENOMEM pci_save_state fails ++ * ++ * @see ++ * - ioh_1588_pcidev ++ * <hr> ++ * */ ++static int ioh_1588_suspend(struct pci_dev *pdev, pm_message_t state) ++{ ++ ++ IOH_DEBUG("ioh_1588_suspend: disabling interrupts by \ ++ invoking ioh_1588_disable_interrupts\n"); ++ (void)ioh_1588_disable_interrupts(); ++ ++ ioh_1588_dev.suspend = 1; ++ ++ IOH_DEBUG("ioh_1588_suspend: saving register values by \ ++ invoking ioh_1588_save_state\n"); ++ ioh_1588_save_state(); ++ ++ pci_disable_device(pdev); ++ IOH_DEBUG("ioh_1588_suspend: disabled the device\n"); ++ ++ (void)pci_enable_wake(pdev, PCI_D3hot, 0); ++ IOH_DEBUG("ioh_1588_suspend: disabled PM notifications\n"); ++ ++ if (pci_save_state(pdev) != 0) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_suspend: could not save PCI config state\n"); ++ return -ENOMEM; ++ } ++ IOH_DEBUG("ioh_1588_suspend: saved state\n"); ++ ++ pci_set_power_state(pdev, pci_choose_state(pdev, state)); ++ ++ IOH_DEBUG("ioh_1588_suspend: returning success\n"); ++ return 0; ++} ++ ++/*! @ingroup IEEE_1588_PCILayerAPI ++ * @fn int ioh_1588_resume(struct pci_dev *pdev) ++ * @brief ++ * This function is called to resume a device after being put into a ++ * low power state. ++ * @remarks ++ * The main tasks performed by this method are: ++ * - Restore the power state of the device using ++ * pci_set_power_state ++ * API. ++ * - Restore the PCI configuration space using pci_restore_state ++ * API. ++ * - Enable the PCI device using pci_enable_device API. ++ * - If pci_enable_device fails, return the error status; ++ * else return 0. ++ * ++ * ++ * @param pdev [INOUT] pci device structure ++ * ++ * @return int ++ * - 0 on success ++ * - -EIO pci_enable_device fails ++ * - -EINVAL pci_enable_device fails ++ * @see ++ * - ioh_1588_pcidev ++ * <hr> ++ */ ++ ++static int ioh_1588_resume(struct pci_dev *pdev) ++{ ++ int ret; ++ ++ pci_set_power_state(pdev, PCI_D0); ++ ++ ret = pci_restore_state(pdev); ++ ++ if (ret != 0) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_resume: pci_restore_state failed\n"); ++ return ret; ++ } ++ IOH_DEBUG("ioh_1588_resume: restored state\n"); ++ ++ ret = pci_enable_device(pdev); ++ ++ if (ret) { ++ IOH_LOG(KERN_ERR, ++ "ioh_1588_resume: pci_enable_device failed\n"); ++ return ret; ++ } ++ ++ IOH_DEBUG("ioh_1588_resume: enabled device\n"); ++ ++ (void)pci_enable_wake(pdev, PCI_D3hot, 0); ++ IOH_DEBUG("ioh_1588_resume: disabled PM notifications\n"); ++ ++ IOH_DEBUG("ioh_1588_resume: restoring register values by \ ++ invoking ioh_1588_restore_state\n"); ++ ioh_1588_restore_state(); ++ ++ ioh_1588_dev.suspend = 0; ++ ++ IOH_DEBUG("ioh_1588_resume: returning success\n"); ++ return 0; ++} ++#endif ++ ++/*! @ingroup IEEE_1588_InterfaceLayerAPI ++ * @fn void ioh_1588_exit(void) ++ * @brief Un-loads the IEEE 1588 PCI driver. ++ * @remarks This function is invoked when the driver is ++ * unloaded. The main task performed by this ++ * function is un-registering the module as ++ * PCI driver. ++ * @param None ++ * @return None ++ * <hr> ++ */ ++static void __exit ioh_1588_exit(void) ++{ ++ ++ pci_unregister_driver(&ioh_1588_pcidev); ++ ++ IOH_DEBUG("ioh_1588_exit: Driver unloaded\n"); ++} ++ ++/*! @ingroup IEEE_1588_InterfaceLayerAPI ++ * @fn int ioh_1588_init(void) ++ * @brief Initializes the driver. ++ * @remarks This function is the entry point for the driver. ++ * The main tasks performed by this method are: ++ * - Register IEEE 1588 driver as a PCI driver by calling ++ * pci_register_driver ++ * ++ * @param None ++ * ++ * @return int ++ * - 0 on success ++ * - -EBUSY register_chrdev_region fails ++ * - -ENOMEM cdev_add/register_chrdev_region/ ++ * pci_register_driver fails ++ * - -EEXIST pci_register_driver fails ++ * - -EINVAL pci_register_driver fails ++ * <hr> ++ */ ++static int __init ioh_1588_init(void) ++{ ++ int ret; ++ ++ (void)memset((void *)&ioh_1588_dev, 0, sizeof ioh_1588_dev); ++ ++ /* register the driver with the pci core */ ++ ret = pci_register_driver(&ioh_1588_pcidev); ++ ++ if (ret) ++ IOH_LOG(KERN_ERR, "ioh_1588_init: pci_register failed\n"); ++ ++ IOH_DEBUG("ioh_1588_init: pci_register success\n"); ++ return ret; ++} ++ ++module_init(ioh_1588_init); ++module_exit(ioh_1588_exit); ++MODULE_LICENSE("GPL"); ++MODULE_DEVICE_TABLE(pci, ioh_1588_pcidev_id); +diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.h topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.h +--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.h 1970-01-01 09:00:00.000000000 +0900 ++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_1588_pci.h 2010-03-09 05:27:48.000000000 +0900 +@@ -0,0 +1,122 @@ ++ /*! ++ * @file ioh_1588_pci.h ++ * @brief ++ * This file lists the declarations for IEEE_1588_PCILayer APIs. ++ * @version 0.92 ++ * @section ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * History: ++ * modified to support Intel IOH GE IEEE 1588 hardware ++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. ++ * All rights reserved. ++ * derived from ++ * IEEE 1588 Time Synchronization Driver for Intel EP80579 ++ * Copyright(c) 2007,2008 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ */ ++ ++#ifndef IOH_1588_PCI_H ++#define IOH_1588_PCI_H ++ ++#include <linux/types.h> ++#include <linux/errno.h> ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/poll.h> ++#include <linux/init.h> ++#include <linux/fs.h> ++#include <linux/fcntl.h> ++#include <linux/interrupt.h> ++#include <linux/uaccess.h> ++#include <linux/cdev.h> ++#include <linux/pci.h> ++ ++/*! @ingroup IEEE_1588_Global ++ * @def DRIVER_NAME ++ * @brief Macro representing the name of this driver ++ * <hr> ++ */ ++#define DRIVER_NAME "ioh_ieee1588" ++ ++/*! @ingroup IEEE_1588_Global ++ * @def STATION_ADDR_LEN ++ * @brief Macro representing the station address length ++ * <hr> ++ */ ++#define STATION_ADDR_LEN 20 ++ ++/*! @ingroup IEEE_1588_PCILayer ++ @def PCI_VENDOR_ID_IOH ++ @brief Outlines the PCI Vendor ID for IOH board. ++ */ ++ ++/*! @ingroup IEEE_1588_PCILayer ++ @def PCI_DEVICE_ID_IOH_1588 ++ @brief Outlines the PCI Device ID for IEEE 1588 device. ++ */ ++#define PCI_DEVICE_ID_IOH_1588 0x8819 ++ ++/*! @ingroup IEEE_1588_PCILayer ++ * @def IO_MEM_BAR ++ * @brief Macro representing IO memory BAR ++ * <hr> ++ */ ++#define IO_MEM_BAR 1 ++ ++/* enumeration of events used */ ++ ++/*! @ingroup IEEE_1588_Global ++ * @enum notify_event ++ * @brief enumeration of events used ++ * <hr> ++ */ ++enum _notify_event { ++ TARG_TIME_EVENT_NUM, ++ AUX_TIME_EVENT_NUM, ++ PPS_EVENT_NUM, ++ NUM_EVENTS ++}; ++ ++/* private driver data */ ++/*! @ingroup IEEE_1588_Global ++ * @struct ioh_1588_dev_t ++ * @brief Driver private data ++ * <hr> ++ */ ++struct ioh_1588_dev { ++ dev_t devno; /**< The device (major) number. */ ++ struct cdev cdev; /**< The cdev structure instance. */ ++ void *mem_virt; /**< The virtual memory base address.*/ ++ unsigned int mem_base; /**< The physical memory base address.*/ ++ unsigned int mem_size; /**< The memory size. */ ++ unsigned int irq; /**< The IRQ line of the device.*/ ++ unsigned int suspend:1; /**< The suspend flag. */ ++ unsigned int initialized:1; /**< The initialized flag. */ ++ /* event variables */ ++ unsigned int event_flags[NUM_EVENTS]; /**< The event variables. */ ++ wait_queue_head_t notify_evt[NUM_EVENTS]; /**< The notify event ++ variable.*/ ++}; ++ ++extern struct ioh_1588_dev *ioh_1588_devp; ++extern const struct file_operations ioh_1588_fops; ++irqreturn_t ioh_1588_isr(int irq, void *p_data); ++extern void ioh_1588_save_state(void); ++extern void ioh_1588_restore_state(void); ++ ++#endif /* IOH_1588_PCI_H */ +diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_common.h topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_common.h +--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_common.h 1970-01-01 09:00:00.000000000 +0900 ++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_common.h 2010-03-09 05:56:11.000000000 +0900 +@@ -0,0 +1,146 @@ ++/*! ++ * @file ioh_common.h ++ * @brief Provides the macro definitions used by all files. ++ * @version 1.0.0.0 ++ * @section ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * History: ++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. ++ * All rights reserved. ++ * ++ * created: ++ * WIPRO 03/07/2009 ++ * modified: ++ * WIPRO 05/08/2009 ++ * ++ */ ++ ++#ifndef __IOH_COMMON_H__ ++#define __IOH_COMMON_H__ ++ ++/*! @ingroup Global ++@def IOH_WRITE8 ++@brief Macro for writing 8 bit data to an io/mem address ++*/ ++#define IOH_WRITE8(val, addr) iowrite8((val), (void __iomem *)(addr)) ++/*! @ingroup Global ++@def IOH_LOG ++@brief Macro for writing 16 bit data to an io/mem address ++*/ ++#define IOH_WRITE16(val, addr) iowrite16((val), (void __iomem *)(addr)) ++/*! @ingroup Global ++@def IOH_LOG ++@brief Macro for writing 32 bit data to an io/mem address ++*/ ++#define IOH_WRITE32(val, addr) iowrite32((val), (void __iomem *)(addr)) ++ ++/*! @ingroup Global ++@def IOH_READ8 ++@brief Macro for reading 8 bit data from an io/mem address ++*/ ++#define IOH_READ8(addr) ioread8((void __iomem *)(addr)) ++/*! @ingroup Global ++@def IOH_READ16 ++@brief Macro for reading 16 bit data from an io/mem address ++*/ ++#define IOH_READ16(addr) ioread16((void __iomem *)(addr)) ++/*! @ingroup Global ++@def IOH_READ32 ++@brief Macro for reading 32 bit data from an io/mem address ++*/ ++#define IOH_READ32(addr) ioread32((void __iomem *)(addr)) ++/*! @ingroup Global ++@def IOH_WRITE32_F ++@brief Macro for writing 32 bit data to an io/mem address ++*/ ++#define IOH_WRITE32_F(val, addr) do \ ++ { IOH_WRITE32((val), (addr)); (void)IOH_READ32((addr)); } while (0); ++ ++/*! @ingroup Global ++@def IOH_WRITE_BYTE ++@brief Macro for writing 1 byte data to an io/mem address ++*/ ++#define IOH_WRITE_BYTE IOH_WRITE8 ++/*! @ingroup Global ++@def IOH_WRITE_WORD ++@brief Macro for writing 1 word data to an io/mem address ++*/ ++#define IOH_WRITE_WORD IOH_WRITE16 ++/*! @ingroup Global ++@def IOH_WRITE_LONG ++@brief Macro for writing long data to an io/mem address ++*/ ++#define IOH_WRITE_LONG IOH_WRITE32 ++ ++/*! @ingroup Global ++@def IOH_READ_BYTE ++@brief Macro for reading 1 byte data from an io/mem address ++*/ ++#define IOH_READ_BYTE IOH_READ8 ++/*! @ingroup Global ++@def IOH_READ_WORD ++@brief Macro for reading 1 word data from an io/mem address ++*/ ++#define IOH_READ_WORD IOH_READ16 ++/*! @ingroup Global ++@def IOH_READ_LONG ++@brief Macro for reading long data from an io/mem address ++*/ ++#define IOH_READ_LONG IOH_READ32 ++ ++/* Bit Manipulation Macros */ ++ ++/*! @ingroup Global ++@def IOH_READ_LONG ++@brief macro to set a specified bit(mask) at the ++ specified address ++*/ ++#define IOH_SET_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) |\ ++ (bitmask)), (addr)) ++ ++/*! @ingroup Global ++@def IOH_READ_LONG ++@brief macro to clear a specified bit(mask) at the specified address ++*/ ++#define IOH_CLR_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) &\ ++ ~(bitmask)), (addr)) ++ ++/*! @ingroup Global ++@def IOH_READ_LONG ++@brief macro to set a specified bitmask for a variable ++*/ ++#define IOH_SET_BITMSK(var, bitmask) ((var) |= (bitmask)) ++ ++/*! @ingroup Global ++@def IOH_READ_LONG ++@brief macro to clear a specified bitmask for a variable ++*/ ++#define IOH_CLR_BITMSK(var, bitmask) ((var) &= (~(bitmask))) ++ ++/*! @ingroup Global ++@def IOH_READ_LONG ++@brief macro to set a specified bit for a variable ++*/ ++#define IOH_SET_BIT(var, bit) ((var) |= (1<<(bit))) ++ ++/*! @ingroup Global ++@def IOH_READ_LONG ++@brief macro to clear a specified bit for a variable ++*/ ++#define IOH_CLR_BIT(var, bit) ((var) &= ~(1<<(bit))) ++ ++#endif +diff -urN linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_debug.h topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_debug.h +--- linux-2.6.33-rc3/drivers/char/pch_ieee1588/pch_debug.h 1970-01-01 09:00:00.000000000 +0900 ++++ topcliff-2.6.33-rc3/drivers/char/pch_ieee1588/pch_debug.h 2010-03-09 05:37:47.000000000 +0900 +@@ -0,0 +1,60 @@ ++/*! ++ * @file ioh_debug.h ++ * @brief Provides the macro definitions used for debugging. ++ * @version 1.0.0.0 ++ * @section ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; version 2 of the License. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * History: ++ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD. ++ * All rights reserved. ++ * ++ * created: ++ * WIPRO 03/07/2009 ++ * modified: ++ * WIPRO 05/08/2009 ++ * ++ */ ++ ++#ifndef __IOH_DEBUG_H__ ++#define __IOH_DEBUG_H__ ++ ++#ifdef MODULE ++#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n",\ ++ THIS_MODULE->name, ##args) ++#else ++#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n" ,\ ++ __FILE__, ##args) ++#endif ++ ++ ++#ifdef DEBUG ++ #define IOH_DEBUG(fmt, args...) IOH_LOG(KERN_DEBUG, fmt, ##args) ++#else ++ #define IOH_DEBUG(fmt, args...) ++#endif ++ ++#ifdef IOH_TRACE_ENABLED ++ #define IOH_TRACE IOH_DEBUG ++#else ++ #define IOH_TRACE(fmt, args...) ++#endif ++ ++#define IOH_TRACE_ENTER IOH_TRACE("Enter %s", __func__) ++#define IOH_TRACE_EXIT IOH_TRACE("Exit %s", __func__) ++ ++ ++#endif |