generic-poky/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-ieee1588.p...

7946 lines
252 KiB
Diff

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, &regval);
+
+ *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, &regval);
+ 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, &regval);
+ /* 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, &reg_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(&reg_low);
+ IOH_LOG(KERN_ERR, "Frequency Scaling Value: %lx\n", reg_low);
+
+ /* PPS Comapre Register */
+ reg_low = 0;
+ ioh_1588_pps_get(&reg_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(&reg_low, &reg_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(&reg_low, &reg_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(&reg_low, &reg_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(&reg_low, &reg_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(&reg_low, &reg_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(&reg_low, &reg_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(&reg_low, &reg_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, &reg_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