From ff9dc943441511ca7c68f2f5657a0c6658ebc10a Mon Sep 17 00:00:00 2001 From: Silicom Ltd Date: Thu, 5 Sep 2019 09:56:13 +0000 Subject: [PATCH] Upstream release 1.0.13 --- Makefile | 170 ++ bits.h | 48 + bp_cmd.h | 675 +++++ bp_mod.h | 1088 ++++++++ bp_msg.h | 330 +++ bprd_ioctl.h | 176 ++ bprd_mod.c | 6656 +++++++++++++++++++++++++++++++++++++++++++++++++ bprd_mod.h | 132 + bprd_util.c | 3541 ++++++++++++++++++++++++++ bprd_util.h | 194 ++ bprdctl_start | 23 + bprdctl_stop | 7 + bypass.h | 237 ++ common.mk | 335 +++ libbp_rd.h | 585 +++++ readme.txt | 100 + release.txt | 46 + 17 files changed, 14343 insertions(+) create mode 100755 Makefile create mode 100755 bits.h create mode 100755 bp_cmd.h create mode 100755 bp_mod.h create mode 100755 bp_msg.h create mode 100755 bprd_ioctl.h create mode 100755 bprd_mod.c create mode 100755 bprd_mod.h create mode 100755 bprd_util.c create mode 100755 bprd_util.h create mode 100755 bprdctl_start create mode 100755 bprdctl_stop create mode 100755 bypass.h create mode 100755 common.mk create mode 100755 libbp_rd.h create mode 100755 readme.txt create mode 100755 release.txt diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..3cbd90b --- /dev/null +++ b/Makefile @@ -0,0 +1,170 @@ +################################################################################ +# +# Intel(R) 10GbE PCI Express Linux Network Driver +# Copyright(c) 1999 - 2017 Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Linux NICS +# e1000-devel Mailing List +# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 +# Silicom, Ltd +################################################################################ + +MOD_VER=1.0.13 + +PRDPATH_UTIL=/bin +TARGET_UTIL=bprdctl_util +OBJS_UTIL = bprd_util.o + +ifneq ($(KERNELRELEASE),) +# kbuild part of makefile +# +# Makefile for the Intel(R) 10GbE PCI Express Linux Network Driver +# + +obj-$(CONFIG_BPRDCTL_MOD) += bprdctl_mod.o + +define bprdctl_mod-y + bprd_mod.o +endef +bprdctl_mod-y := $(strip ${bprdctl_mod-y}) + + +else # ifneq($(KERNELRELEASE),) +# normal makefile + +DRIVER := bprdctl_mod + +ifeq (,$(wildcard common.mk)) + $(error Cannot find common.mk build rules) +else + include common.mk +endif + +# Check that kernel version is at least 2.6.0, since we don't support 2.4.x +# kernels with the BPRDCTL driver. We can't use minimum_kver_check since SLES 10 +# SP4's Make has a bug which causes $(eval) inside an ifeq conditional to error +# out. This was fixed in Make 3.81, but SLES 10 SP4 does not have a fix for +# this yet. +ifeq (0,$(shell [ ${KVER_CODE} -lt $(call get_kvercode,2,6,0) ]; echo "$?")) + $(warning *** Aborting the build.) + $(error This driver is not supported on kernel versions older than 2.6.0) +endif + +###################### +# Kernel Build Macro # +###################### + +# customized kernelbuild function +# +# ${1} is the kernel build target +# ${2} may contain extra rules to pass to kernelbuild macro +# +# We customize the kernelbuild target in order to provide our hack to disable +# CONFIG_PTP_1588_CLOCK support should -DNO_PTP_SUPPORT be defined in the extra +# cflags given on the command line. +devkernelbuild = $(call kernelbuild,$(if $(filter -DNO_PTP_SUPPORT,${EXTRA_CFLAGS}),CONFIG_PTP_1588_CLOCK=n) ${2},${1}) + +############### +# Build rules # +############### + +# Standard compilation, with regular output +default: $(TARGET_UTIL) + @+$(call devkernelbuild,modules) + +# Noisy output, for extra debugging +noisy: + @+$(call devkernelbuild,modules,V=1) + +# Silence any output generated +silent: + @+$(call devkernelbuild,modules,>/dev/null) + +# Enable higher warning level +checkwarnings: clean + @+$(call devkernelbuild,modules,W=1) + +# Run sparse static analyzer +sparse: clean + @+$(call devkernelbuild,modules,C=2 CF="-D__CHECK_ENDIAN__ -Wbitwise -Wcontext") + +# Run coccicheck static analyzer +ccc: clean + @+$(call devkernelbuild,modules,coccicheck MODE=report)) + + +# Clean the module subdirectories +clean: + @+$(call devkernelbuild,clean) + @-rm -rf *.ko + rm -rf $(OBJS_UTIL) $(TARGET_UTIL) + +# Install the modules +install: default + @echo "Installing modules..." + @+$(call devkernelbuild,modules_install) + @echo "Running depmod..." + @$(call cmd_depmod) + mkdir -p $(INSTALL_MOD_PATH)$(PRDPATH_UTIL) + install $(TARGET_UTIL) $(INSTALL_MOD_PATH)$(PRDPATH_UTIL) + install bprdctl_start $(INSTALL_MOD_PATH)$(PRDPATH_UTIL) + install bprdctl_stop $(INSTALL_MOD_PATH)$(PRDPATH_UTIL) + +$(TARGET_UTIL): $(OBJS_UTIL) + $(CC) $(OBJS_UTIL) -g -Wall -o $(TARGET_UTIL) + +uninstall: + rm -f ${INSTALL_MOD_PATH}/lib/modules/${KVER}/${INSTALL_MOD_DIR}/${DRIVER}.ko; + $(call cmd_depmod) + if [ -e $(INSTALL_MOD_PATH)$(PRDPATH_UTIL)/$(TARGET_UTIL) ] ; then \ + rm -f $(INSTALL_MOD_PATH)$(PRDPATH_UTIL)/$(TARGET_UTIL) ; \ + fi + if [ -e $(INSTALL_MOD_PATH)$(PRDPATH_UTIL)/bprdctl_start ] ; then \ + rm -f $(INSTALL_MOD_PATH)$(PRDPATH_UTIL)/bprdctl_start ; \ + fi + if [ -e $(INSTALL_MOD_PATH)$(PRDPATH_UTIL)/bprdctl_stop ] ; then \ + rm -f $(INSTALL_MOD_PATH)$(PRDPATH_UTIL)/bprdctl_stop ; \ + fi + +######## +# Help # +######## +help: + @echo 'Cleaning targets:' + @echo ' clean - Clean files generated by kernel module build' + @echo 'Build targets:' + @echo ' default - Build module(s) with standard verbosity' + @echo ' noisy - Build module(s) with V=1 verbosity -- very noisy' + @echo ' silent - Build module(s), squelching all output' + @echo 'Static Analysis:' + @echo ' checkwarnings - Clean, then build module(s) with W=1 warnings enabled' + @echo ' sparse - Clean, then check module(s) using sparse' + @echo ' ccc - Clean, then check module(s) using coccicheck' + @echo 'Other targets:' + @echo ' install - Build then install the module(s)' + @echo ' uninstall - Uninstall the module(s)' + @echo ' help - Display this help message' + @echo 'Variables:' + @echo ' LINUX_VERSION - Debug tool to force kernel LINUX_VERSION_CODE. Use at your own risk.' + @echo ' W=N - Kernel variable for setting warning levels' + @echo ' V=N - Kernel variable for setting output verbosity' + @echo ' INSTALL_MOD_PATH - Add prefix for the module installation path' + @echo ' Other variables may be available for tuning make process, see' + @echo ' Kernel Kbuild documentation for more information' + +.PHONY: default noisy clean silent sparse ccc install uninstall help + +endif # ifneq($(KERNELRELEASE),) diff --git a/bits.h b/bits.h new file mode 100755 index 0000000..693c5e6 --- /dev/null +++ b/bits.h @@ -0,0 +1,48 @@ + +#ifndef BITS_H +#define BITS_H + + + +/******************************************************************************/ +/* Bit Mask definitions */ +/******************************************************************************/ + +#define BIT_NONE 0x00 +#define BIT_0 0x01 +#define BIT_1 0x02 +#define BIT_2 0x04 +#define BIT_3 0x08 +#define BIT_4 0x10 +#define BIT_5 0x20 +#define BIT_6 0x40 +#define BIT_7 0x80 +#define BIT_8 0x0100 +#define BIT_9 0x0200 +#define BIT_10 0x0400 +#define BIT_11 0x0800 +#define BIT_12 0x1000 +#define BIT_13 0x2000 +#define BIT_14 0x4000 +#define BIT_15 0x8000 +#define BIT_16 0x010000 +#define BIT_17 0x020000 +#define BIT_18 0x040000 +#define BIT_19 0x080000 +#define BIT_20 0x100000 +#define BIT_21 0x200000 +#define BIT_22 0x400000 +#define BIT_23 0x800000 +#define BIT_24 0x01000000 +#define BIT_25 0x02000000 +#define BIT_26 0x04000000 +#define BIT_27 0x08000000 +#define BIT_28 0x10000000 +#define BIT_29 0x20000000 +#define BIT_30 0x40000000 +#define BIT_31 0x80000000 + + + +#endif /* BITS_H */ + diff --git a/bp_cmd.h b/bp_cmd.h new file mode 100755 index 0000000..caa3ef2 --- /dev/null +++ b/bp_cmd.h @@ -0,0 +1,675 @@ +#ifndef __BP_CMD_H__ +#define __BP_CMD_H__ + +//#define FW_HEADER_DEF 1 + +#ifndef FW_HEADER_DEF + typedef unsigned int U32_T; /* 32-bit unsigned */ + typedef unsigned short int U16_T; /* 16-bit unsigned */ + typedef unsigned char U8_T; /* 8-bit unsigned */ +#endif + typedef U8_T byte; + + +#ifndef FW_HEADER_DEF + #pragma pack(push) /* push current alignment to stack */ + #pragma pack(1) /* set alignment to 1 byte boundary */ +#endif + + +/******************************************************\ +* * +* COMMUNICATION PROTOCOL SPECIFICATION * +* * +* * +* * +\******************************************************/ + +/* + * BP cmd IDs + */ +#define CMD_GET_BYPASS_CAPS 1 +#define CMD_GET_WD_SET_CAPS 2 +#define CMD_SET_BYPASS 3 +#define CMD_GET_BYPASS 4 +#define CMD_GET_BYPASS_CHANGE 5 +#define CMD_SET_BYPASS_WD 6 +#define CMD_GET_BYPASS_WD 7 +#define CMD_GET_WD_EXPIRE_TIME 8 +#define CMD_RESET_BYPASS_WD_TIMER 9 +#define CMD_SET_DIS_BYPASS 10 +#define CMD_GET_DIS_BYPASS 11 +#define CMD_SET_BYPASS_PWOFF 12 +#define CMD_GET_BYPASS_PWOFF 13 +#define CMD_SET_BYPASS_PWUP 14 +#define CMD_GET_BYPASS_PWUP 15 +#define CMD_SET_STD_NIC 16 +#define CMD_GET_STD_NIC 17 +#define CMD_SET_TAP 18 +#define CMD_GET_TAP 19 +#define CMD_GET_TAP_CHANGE 20 +#define CMD_SET_DIS_TAP 21 +#define CMD_GET_DIS_TAP 22 +#define CMD_SET_TAP_PWUP 23 +#define CMD_GET_TAP_PWUP 24 +#define CMD_SET_WD_EXP_MODE 25 +#define CMD_GET_WD_EXP_MODE 26 +#define CMD_SET_DISC 27 +#define CMD_GET_DISC 28 +#define CMD_GET_DISC_CHANGE 29 +#define CMD_SET_DIS_DISC 30 +#define CMD_GET_DIS_DISC 31 +#define CMD_SET_DISC_PWUP 32 +#define CMD_GET_DISC_PWUP 33 +#define CMD_SET_DISC_PWOFF 34 +#define CMD_GET_DISC_PWOFF 35 +#define CMD_GET_BYPASS_CAPS_EX 36 +#define CMD_SET_HOST_PWOFF_MODE 37 +#define CMD_GET_HOST_PWOFF_MODE 38 +#define CMD_SET_HOST_PWUP_MODE 39 +#define CMD_GET_HOST_PWUP_MODE 40 +#define CMD_SET_DISC_PORT 41 +#define CMD_GET_DISC_PORT 42 +#define CMD_SET_DISC_PORT_PWUP 43 +#define CMD_GET_DISC_PORT_PWUP 44 +#define CMD_SET_WD_RST_RESTORE_MODE 45 +#define CMD_GET_WD_RST_RESTORE_MODE 46 +#define CMD_SET_TPL 47 +#define CMD_GET_TPL 48 +#define CMD_SET_TX 49 +#define CMD_GET_TX 50 + + +#define CMD_GET_BYPASS_INFO 100 +#define CMD_GET_BP_WAIT_AT_PWUP 101 +#define CMD_SET_BP_WAIT_AT_PWUP 102 +#define CMD_GET_BP_HW_RESET 103 +#define CMD_SET_BP_HW_RESET 104 +#define CMD_SET_BP_MANUF 105 +//#define CMD_RESERVED 131-132 +#define CMD_GET_DEV_INFO 133 +//#define CMD_RESERVED 132-139 + + +typedef U8_T cmd_id_t; + + + +/* + * BP cmd response codes + */ +#define BP_ERR_OK 1 +#define BP_ERR_NOT_CAP 2 +#define BP_ERR_DEV_BUSY 3 +#define BP_ERR_INVAL_DEV_NUM 4 +#define BP_ERR_INVAL_STATE 5 +#define BP_ERR_INVAL_PARAM 6 +#define BP_ERR_UNSUPPORTED_PARAM 7 +#define BP_ERR_INVAL_CMD 8 +#define BP_ERR_UNSUPPORTED_CMD 9 +#define BP_ERR_INTERNAL 10 +#define BP_ERR_UNKNOWN 11 + +typedef U8_T cmd_rsp_id_t; + +typedef U8_T cmd_bp_board_t; + + + +/* + * BP device info + */ +typedef struct _cmd_bp_info_t{ + cmd_bp_board_t dev_id; + byte fw_ver; +}cmd_bp_info_t; + + +/* + * Disc port + */ +typedef struct _disc_port_t{ + U8_T mode; + U8_T port_num; +}disc_port_t; + + +/* + * Tx disable + */ +typedef struct _tx_dis_t{ + U8_T mode; + U8_T port_num; +}tx_dis_t; + + +/* + * Device info + */ +typedef union _cmd_dev_info_t{ + U8_T info_id; + struct { + U8_T dev_id; + U8_T dev_rev; + U8_T eeprom_ver; + U8_T eeprom_rev; + }dev_ver; + U8_T bds_rev[4]; + U8_T fw_ver[4]; + U8_T hw_ver[4]; + U32_T fw_build; + union { + U8_T part0[4]; + U8_T part1[2]; + }mac_addr; + union { + U8_T sn0[4]; + U8_T sn1[4]; + U8_T sn2[4]; + U8_T sn3[4]; + }sn; +}cmd_dev_info_t; + + +/* + * BP command device number + */ +#define DEV_NUM_MAX 4 +typedef U8_T cmd_dev_num_t; + + +/* + * BP command data lenth type + */ +typedef U8_T cmd_data_len_t; + + +/* + * BP command data structure + */ +typedef union _cmd_data_t{ +#if 0 + /* + * CMD_GET_BYPASS_CAPS + */ + /* + * CMD_GET_BYPASS_CAPS_EX (1st double word) + */ +#define BP_CAP BIT0 +#define BP_STATUS_CAP BIT1 +#define BP_STATUS_CHANGE_CAP BIT2 +#define SW_CTL_CAP BIT3 +#define BP_DIS_CAP BIT4 +#define BP_DIS_STATUS_CAP BIT5 +#define STD_NIC_CAP BIT6 +#define BP_PWOFF_ON_CAP BIT7 +#define BP_PWOFF_OFF_CAP BIT8 +#define BP_PWOFF_CTL_CAP BIT9 +#define BP_PWUP_ON_CAP BIT10 +#define BP_PWUP_OFF_CAP BIT11 +#define BP_PWUP_CTL_CAP BIT12 +#define WD_CTL_CAP BIT13 +#define WD_STATUS_CAP BIT14 +#define WD_TIMEOUT_CAP BIT15 +#define TX_CTL_CAP BIT16 +#define TX_STATUS_CAP BIT17 +#define TAP_CAP BIT18 +#define TAP_STATUS_CAP BIT19 +#define TAP_STATUS_CHANGE_CAP BIT20 +#define TAP_DIS_CAP BIT21 +#define TAP_DIS_STATUS_CAP BIT22 +#define TAP_PWUP_ON_CAP BIT23 +#define TAP_PWUP_OFF_CAP BIT24 +#define TAP_PWUP_CTL_CAP BIT25 +#define NIC_CAP_NEG BIT26 +#define TPL_CAP BIT27 +#define DISC_CAP BIT28 +#define DISC_DIS_CAP BIT29 +#define DISC_PWUP_CTL_CAP BIT30 +#define BP_CAPS_EX_CAP BIT31 +#endif + U32_T bypass_caps; + + + /* + * CMD_GET_BYPASS_CAPS_EX (2nd double word) + */ +#if 0 +#define DISC_PWOFF_CTL_CAP BIT0 +#define BP_HOST_PWOFF_CTL_CAP BIT1 +#define BP_HOST_PWUP_CTL_CAP BIT2 +#define DISC_HOST_PWOFF_CTL_CAP BIT3 +#define DISC_HOST_PWUP_CTL_CAP BIT4 +#define NORMAL_HOST_PWOFF_CTL_CAP BIT5 +#define NORMAL_HOST_PWUP_CTL_CAP BIT6 +#define TAP_HOST_PWOFF_CTL_CAP BIT7 +#define TAP_HOST_PWUP_CTL_CAP BIT8 +#define DISC_PORT_CAP BIT9 +#define DISC_PORT_PWUP_CTL_CAP BIT10 +#endif + + U32_T bypass_caps_ex; + + + /* + * CMD_GET_WD_SET_CAPS + */ + + /* -------------------------------------------------------------------------------------- + * Bit feature description Products + * --------------------------------------------------------------------------------------- + * 0-3 WD_MIN_TIME The interface WD minimal time period in PXG2/4BP - 5 (500mS) + * 100mS units All the other + * products - 1(100mS) + * --------------------------------------------------------------------------------------- + * 4 WD_STEP_TIME The steps of the WD timer in PXG2/4BP - 0 + * 0 - for linear steps (WD_MIN_TIME * X) All the other + * 1 - for multiply by 2 from previous step products - 1 + * (WD_MIN_TIME * 2^X) + * --------------------------------------------------------------------------------------- + * 5-8 WD_STEP_COUNT Number of register bits available for PXG2/4BP -7 + * configuring the WD timer. From that the All the other + * number of steps the WD timer will have is products - 4 + * 2^X (X number of bits available for + * defining the value) + * --------------------------------------------------------------------------------------- + * 9-31 RESERVED Reserved, should be ignored. + * -------------------------------------------------------------------------------------*/ + + U32_T wd_set_caps; + + + /* + * CMD_SET_BYPASS + */ + /* + * CMD_GET_BYPASS + */ +/* #define BYPASS_OFF 0 */ +/* #define BYPASS_ON 1 */ + + U8_T bypass_mode; + + + /* + * CMD_GET_BYPASS_CHANGE + */ +#define BYPASS_NOT_CHANGED 0 +#define BYPASS_CHANGED 1 + + U8_T bypass_change; + + + /* + * CMD_SET_BYPASS_WD + */ + /* + * CMD_GET_BYPASS_WD + */ + + U32_T timeout; + U32_T timeout_set; + + + /* + * CMD_GET_WD_EXPIRE_TIME + */ + + U32_T time_left; + + + /* + * CMD_SET_DIS_BYPASS + */ + /* + * CMD_GET_DIS_BYPASS + */ +#define DIS_BYPASS_ENABLE 0 +#define DIS_BYPASS_DISABLE 1 + + U8_T dis_bypass; + + + /* + * CMD_SET_BYPASS_PWOFF + */ + /* + * CMD_GET_BYPASS_PWOFF + */ +#define BYPASS_PWOFF_DIS 0 +#define BYPASS_PWOFF_EN 1 + + U8_T bypass_pwoff; + + + /* + * CMD_SET_BYPASS_PWUP + */ + /* + * CMD_GET_BYPASS_PWUP + */ +#define BYPASS_PWUP_DIS 0 +#define BYPASS_PWUP_EN 1 + + U8_T bypass_pwup; + + + /* + * CMD_SET_HOST_PWOFF_MODE + */ + /* + * CMD_GET_HOST_PWOFF_MODE + */ +#define HOST_PWOFF_MODE_BYPASS 0 +#define HOST_PWOFF_MODE_TAP 1 +#define HOST_PWOFF_MODE_DISC 2 +#define HOST_PWOFF_MODE_NORMAL 3 + + U8_T host_pwoff_mode; + + + /* + * CMD_SET_HOST_PWUP_MODE + */ + /* + * CMD_GET_HOST_PWUP_MODE + */ +#define HOST_PWUP_MODE_BYPASS 0 +#define HOST_PWUP_MODE_TAP 1 +#define HOST_PWUP_MODE_DISC 2 +#define HOST_PWUP_MODE_NORMAL 3 + + U8_T host_pwup_mode; + + + /* + * CMD_SET_STD_NIC + */ + /* + * CMD_GET_STD_NIC + */ +#define STD_NIC_DIS 0 +#define STD_NIC_EN 1 + + U8_T std_nic; + + + /* + * CMD_SET_TAP + */ + /* + * CMD_GET_TAP + */ +/* #define TAP_OFF 0 */ +/* #define TAP_ON 1 */ + + U8_T tap_mode; + + + /* + * CMD_GET_TAP_CHANGE + */ +#define TAP_NOT_CHANGED 0 +#define TAP_CHANGED 1 + + U8_T tap_change; + + + /* + * CMD_SET_DIS_TAP + */ + /* + * CMD_GET_DIS_TAP + */ +#define DIS_TAP_ENABLE 0 +#define DIS_TAP_DISABLE 1 + + U8_T dis_tap; + + + /* + * CMD_SET_TAP_PWUP + */ + /* + * CMD_GET_TAP_PWUP + */ +#define TAP_PWUP_DIS 0 +#define TAP_PWUP_EN 1 + + U8_T tap_pwup; + + + /* + * CMD_SET_WD_EXP_MODE + */ + /* + * CMD_GET_WD_EXP_MODE + */ +#define WD_EXP_MODE_BYPASS 0 +#define WD_EXP_MODE_TAP 1 +#define WD_EXP_MODE_DISC 2 +#define WD_EXP_MODE_NORMAL 3 + + U8_T wd_exp_mode; + + + /* + * CMD_SET_WD_RST_RESTORE_MODE + */ + /* + * CMD_GET_WD_RST_RESTORE_MODE + */ +#define WD_RST_RESTORE_MODE_BYPASS 0 +#define WD_RST_RESTORE_MODE_TAP 1 +#define WD_RST_RESTORE_MODE_DISC 2 +#define WD_RST_RESTORE_MODE_NORMAL 3 +#define WD_RST_RESTORE_MODE_LAST_STATE 4 +#define WD_RST_RESTORE_MODE_STAY_OFF 5 + + U8_T wd_rst_restore_mode; + + + /* + * CMD_SET_DISC + */ + /* + * CMD_GET_DISC + */ +/* #define DISC_OFF 0 */ +/* #define DISC_ON 1 */ + + U8_T disc_mode; + + + /* + * CMD_GET_DISC_CHANGE + */ +#define DISC_NOT_CHANGED 0 +#define DISC_CHANGED 1 + + U8_T disc_change; + + + /* + * CMD_SET_DIS_DISC + */ + /* + * CMD_GET_DIS_DISC + */ +#define DIS_DISC_ENABLE 0 +#define DIS_DISC_DISABLE 1 + + U8_T dis_disc; + + + /* + * CMD_SET_DISC_PWUP + */ + /* + * CMD_GET_DISC_PWUP + */ +#define DISC_PWUP_DIS 0 +#define DISC_PWUP_EN 1 + + U8_T disc_pwup; + + + /* + * CMD_SET_DISC_PWOFF + */ + /* + * CMD_GET_DISC_PWOFF + */ +#define DISC_PWOFF_DIS 0 +#define DISC_PWOFF_EN 1 + + U8_T disc_pwoff; + + + /* + * CMD_SET_DISC_PORT + */ + /* + * CMD_GET_DISC_PORT + */ +#define DISC_PORT_OFF 0 +#define DISC_PORT_ON 1 + + disc_port_t disc_port; + + + /* + * CMD_SET_DISC_PORT_PWUP + */ + /* + * CMD_GET_DISC_PORT_PWUP + */ +#define DISC_PORT_PWUP_DIS 0 +#define DISC_PORT_PWUP_EN 1 + + disc_port_t disc_port_pwup; + + + /* + * CMD_SET_TPL + */ + /* + * CMD_GET_TPL + */ +#define TPL_OFF 0 +#define TPL_ON 1 + + U8_T tpl_mode; + + + /* + * CMD_SET_TX + */ + /* + * CMD_GET_TX + */ +#define TX_OFF 0 +#define TX_ON 1 + + tx_dis_t tx_dis; + + + /* + * CMD_GET_BYPASS_INFO + */ + cmd_bp_info_t bypass_info; + + + /* + * CMD_GET_DEV_INFO + */ +#define DEV_INFO_DEV_VER 0 +#define DEV_INFO_FW_VER 1 +#define DEV_INFO_MAC_PART0 2 +#define DEV_INFO_MAC_PART1 3 +#define DEV_INFO_SN_PART0 4 +#define DEV_INFO_SN_PART1 5 +#define DEV_INFO_SN_PART2 6 +#define DEV_INFO_SN_PART3 7 +#define DEV_INFO_FW_BUILD 8 +#define DEV_INFO_BDS_REV 9 +#define DEV_INFO_HW_REV 10 + + cmd_dev_info_t dev_info; + + + /* + * CMD_GET_BP_WAIT_AT_PWUP + */ + /* + * CMD_SET_BP_WAIT_AT_PWUP + */ +/* #define BP_WAIT_AT_PWUP_DIS 0 */ +/* #define BP_WAIT_AT_PWUP_EN 1 */ + U8_T bp_wait_at_pwup; + + + /* + * CMD_GET_BP_HW_RESET + */ + /* + * CMD_SET_BP_HW_RESET + */ +/* #define BP_HW_RESET_DIS 0 */ +/* #define BP_HW_RESET_EN 1 */ + + U8_T bp_hw_reset; + +}cmd_data_t; + + +/******************************************************\ +* * +* * +* * +\******************************************************/ +#define BP_CMD_PACKET_SIZE ( sizeof(cmd_dev_num_t) \ + + sizeof(cmd_id_t) \ + + sizeof(cmd_data_len_t) \ + + sizeof(cmd_data_t) ) + +typedef union _bp_cmd_t +{ + byte cmd_bytes[BP_CMD_PACKET_SIZE]; // For Byte Access + + struct { + cmd_dev_num_t cmd_dev_num; + cmd_id_t cmd_id; + cmd_data_len_t cmd_data_len; + cmd_data_t cmd_data; + }cmd; + +}bp_cmd_t; + + +/******************************************************\ +* * +* * +* * +\******************************************************/ +#define BP_RSP_PACKET_SIZE ( sizeof(cmd_rsp_id_t) \ + + sizeof(cmd_data_len_t) \ + + sizeof(cmd_data_t) ) + +typedef union _bp_cmd_rsp_t +{ + byte cmd_bytes[BP_RSP_PACKET_SIZE]; // For Byte Access + + struct { + cmd_rsp_id_t rsp_id; + cmd_data_len_t rsp_data_len; + cmd_data_t rsp_data; + }rsp; + +}bp_cmd_rsp_t; + +#ifndef FW_HEADER_DEF + #pragma pack(pop) /* push current alignment to stack */ +#endif + +#endif /* End of __BP_CMD_H__ */ diff --git a/bp_mod.h b/bp_mod.h new file mode 100755 index 0000000..f4d1ac5 --- /dev/null +++ b/bp_mod.h @@ -0,0 +1,1088 @@ +/************************************************************************** + +Copyright (c) 2006-2013, Silicom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Silicom nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#ifndef BP_MOD_H +#define BP_MOD_H +#include "bits.h" + +#ifndef KERNEL_VERSION + #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) ) + #define msleep(x) do { if(in_interrupt()) { \ + /* Don't mdelay in interrupt context! */ \ + BUG(); \ + } else { \ + set_current_state(TASK_UNINTERRUPTIBLE); \ + schedule_timeout((x * HZ)/1000 + 2); \ + } } while(0) +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) + #define EXPORT_SYMBOL_NOVERS EXPORT_SYMBOL +#endif + +#define BP_PROC_DIR "bypass" + + +#define GPIO6_SET_ENTRY_SD "gpio6_set" +#define GPIO6_CLEAR_ENTRY_SD "gpio6_clear" + +#define GPIO7_SET_ENTRY_SD "gpio7_set" +#define GPIO7_CLEAR_ENTRY_SD "gpio7_clear" + +#define PULSE_SET_ENTRY_SD "pulse_set" +#define ZERO_SET_ENTRY_SD "zero_set" +#define PULSE_GET1_ENTRY_SD "pulse_get1" +#define PULSE_GET2_ENTRY_SD "pulse_get2" + +#define CMND_ON_ENTRY_SD "cmnd_on" +#define CMND_OFF_ENTRY_SD "cmnd_off" +#define RESET_CONT_ENTRY_SD "reset_cont" + +/*COMMANDS*/ +#define BYPASS_INFO_ENTRY_SD "bypass_info" + +#define BYPASS_SLAVE_ENTRY_SD "bypass_slave" +#define BYPASS_CAPS_ENTRY_SD "bypass_caps" +#define WD_SET_CAPS_ENTRY_SD "wd_set_caps" +#define BYPASS_ENTRY_SD "bypass" +#define BYPASS_CHANGE_ENTRY_SD "bypass_change" +#define BYPASS_WD_ENTRY_SD "bypass_wd" +#define WD_EXPIRE_TIME_ENTRY_SD "wd_expire_time" +#define RESET_BYPASS_WD_ENTRY_SD "reset_bypass_wd" +#define DIS_BYPASS_ENTRY_SD "dis_bypass" +#define BYPASS_PWUP_ENTRY_SD "bypass_pwup" +#define BYPASS_PWOFF_ENTRY_SD "bypass_pwoff" +#define STD_NIC_ENTRY_SD "std_nic" +#define STD_NIC_ENTRY_SD "std_nic" +#define TAP_ENTRY_SD "tap" +#define TAP_CHANGE_ENTRY_SD "tap_change" +#define DIS_TAP_ENTRY_SD "dis_tap" +#define TAP_PWUP_ENTRY_SD "tap_pwup" +#define TWO_PORT_LINK_ENTRY_SD "two_port_link" +#define WD_EXP_MODE_ENTRY_SD "wd_exp_mode" +#define WD_AUTORESET_ENTRY_SD "wd_autoreset" +#define TPL_ENTRY_SD "tpl" +#define WAIT_AT_PWUP_ENTRY_SD "wait_at_pwup" +#define HW_RESET_ENTRY_SD "hw_reset" +#define DISC_ENTRY_SD "disc" +#define DISC_CHANGE_ENTRY_SD "disc_change" +#define DIS_DISC_ENTRY_SD "dis_disc" +#define DISC_PWUP_ENTRY_SD "disc_pwup" + + + + + +#ifndef jiffies_to_msecs + #define jiffies_to_msecs(x) _kc_jiffies_to_msecs(x) +static inline unsigned int jiffies_to_msecs(const unsigned long j) +{ +#if HZ <= 1000 && !(1000 % HZ) + return(1000 / HZ) * j; +#elif HZ > 1000 && !(HZ % 1000) + return(j + (HZ / 1000) - 1)/(HZ / 1000); +#else + return(j * 1000) / HZ; +#endif +} +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) + + #define pci_get_class pci_find_class + #define pci_get_subsys pci_find_subsys + #define pci_get_device pci_find_device + +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)) + #define MODULE_VERSION(_version) +#endif + + +#define SILICOM_VID 0x1374 +#define SILICOM_SVID 0x1374 + +#define SILICOM_PXG2BPFI_SSID 0x0026 +#define SILICOM_PXG2BPFILX_SSID 0x0027 +#define SILICOM_PXGBPI_SSID 0x0028 +#define SILICOM_PXGBPIG_SSID 0x0029 +#define SILICOM_PXG2TBFI_SSID 0x002a +#define SILICOM_PXG4BPI_SSID 0x002c +#define SILICOM_PXG4BPFI_SSID 0x002d +#define SILICOM_PXG4BPFILX_SSID 0x002e +#define SILICOM_PXG2BPFIL_SSID 0x002F +#define SILICOM_PXG2BPFILLX_SSID 0x0030 +#define SILICOM_PEG4BPI_SSID 0x0031 +#define SILICOM_PEG2BPI_SSID 0x0037 +#define SILICOM_PEG4BPIN_SSID 0x0038 +#define SILICOM_PEG2BPFI_SSID 0x0039 +#define SILICOM_PEG2BPFILX_SSID 0x003A +#define SILICOM_PMCXG2BPFI_SSID 0x003B +#define NOKIA_PMCXG2BPFIN_SSID 0x0510 +#define NOKIA_PMCXG2BPIN_SSID 0x0513 +#define NOKIA_PMCXG4BPIN_SSID 0x0514 +#define NOKIA_PMCXG2BPFIN_SVID 0x13B8 +#define NOKIA_PMCXG2BPIN2_SSID 0x0515 +#define NOKIA_PMCXG4BPIN2_SSID 0x0516 +#define SILICOM_PMCX2BPI_SSID 0x041 +#define SILICOM_PMCX4BPI_SSID 0x042 +#define SILICOM_PXG2BISC1_SSID 0x003d +#define SILICOM_PEG2TBFI_SSID 0x003E +#define SILICOM_PXG2TBI_SSID 0x003f +#define SILICOM_PXG4BPFID_SSID 0x0043 +#define SILICOM_PEG4BPFI_SSID 0x0040 +#define SILICOM_PEG4BPIPT_SSID 0x0044 +#define SILICOM_PXG6BPI_SSID 0x0045 +#define SILICOM_PEG4BPIL_SSID 0x0046 +#define SILICOM_PEG2BPI5_SSID 0x0052 +#define SILICOM_PEG6BPI_SSID 0x0053 +#define SILICOM_PEG4BPFI5_SSID 0x0050 +#define SILICOM_PEG4BPFI5LX_SSID 0x0051 +#define SILICOM_PEG2BISC6_SSID 0x54 + +#define SILICOM_PEG6BPIFC_SSID 0x55 + + + +#define SILICOM_PEG2BPFI5_SSID 0x0056 +#define SILICOM_PEG2BPFI5LX_SSID 0x0057 + + +#define SILICOM_PXEG4BPFI_SSID 0x0058 + + + + + +#define SILICOM_PEG2BPFID_SSID 0x0047 +#define SILICOM_PEG2BPFIDLX_SSID 0x004C +#define SILICOM_MEG2BPFILN_SSID 0x0048 +#define SILICOM_MEG2BPFINX_SSID 0x0049 +#define SILICOM_PEG4BPFILX_SSID 0x004A +#define SILICOM_MHIO8AD_SSID 0x004F + +#define SILICOM_MEG2BPFILXLN_SSID 0x004b +#define SILICOM_PEG2BPIX1_SSID 0x004d +#define SILICOM_MEG2BPFILXNX_SSID 0x004e + + +#define SILICOM_PE10G2BPISR_SSID 0x0102 +#define SILICOM_PE10G2BPILR_SSID 0x0103 +#define SILICOM_PE10G2BPICX4_SSID 0x0101 + +#define SILICOM_XE10G2BPILR_SSID 0x0163 +#define SILICOM_XE10G2BPISR_SSID 0x0162 +#define SILICOM_XE10G2BPICX4_SSID 0x0161 +#define SILICOM_XE10G2BPIT_SSID 0x0160 + +#define SILICOM_PE10GDBISR_SSID 0x0181 +#define SILICOM_PE10GDBILR_SSID 0x0182 + + + + +#define SILICOM_PE210G2DBi9SR_SSID 0x0188 +#define SILICOM_PE210G2DBi9SRRB_SSID 0x0188 +#define SILICOM_PE210G2DBi9LR_SSID 0x0189 +#define SILICOM_PE210G2DBi9LRRB_SSID 0x0189 +#define SILICOM_PE310G4DBi940SR_SSID 0x018C +#define SILICOM_PE310G4DBi940LR_SSID 0x018D +#define SILICOM_PE310G4DBi940T_SSID 0x018e + +#define SILICOM_PE310G4DBi9T_SSID 0x18e + + + + + +#define SILICOM_PE310G4BPi9T_SSID 0x130 +#define SILICOM_PE310G4BPi9SR_SSID 0x132 +#define SILICOM_PE310G4BPi9LR_SSID 0x133 + +#define SILICOM_PE310G4BPi9SRD_SSID 0x134 +#define SILICOM_PE310G4BPi9LRD_SSID 0x135 + + + + + +#define SILICOM_M6E310G4BPi9SR_SSID 0x0492 +#define SILICOM_M6E310G4BPi9LR_SSID 0x0493 + + + + +#define NOKIA_XE10G2BPIXR_SVID 0x13B8 +#define NOKIA_XE10G2BPIXR_SSID 0x051C + + +#define INTEL_PEG4BPII_PID 0x10A0 +#define INTEL_PEG4BPFII_PID 0x10A1 +#define INTEL_PEG4BPII_SSID 0x11A0 +#define INTEL_PEG4BPFII_SSID 0x11A1 + +#define INTEL_PEG4BPIIO_SSID 0x10A0 +#define INTEL_PEG4BPIIO_PID 0x105e + + +#define BROADCOM_VID 0x14e4 +#define BROADCOM_PE10G2_PID 0x164e + +#define SILICOM_PE10G2BPTCX4_SSID 0x0141 +#define SILICOM_PE10G2BPTSR_SSID 0x0142 +#define SILICOM_PE10G2BPTLR_SSID 0x0143 +#define SILICOM_PE10G2BPTT_SSID 0x0140 + + +#define SILICOM_PEG4BPI6_SSID 0x0320 +#define SILICOM_PEG4BPFI6_SSID 0x0321 +#define SILICOM_PEG4BPFI6LX_SSID 0x0322 +#define SILICOM_PEG4BPFI6ZX_SSID 0x0323 + + +#define SILICOM_PEG2BPI6_SSID 0x0300 +#define SILICOM_PEG2BPFI6_SSID 0x0301 +#define SILICOM_PEG2BPFI6LX_SSID 0x0302 +#define SILICOM_PEG2BPFI6ZX_SSID 0x0303 +#define SILICOM_PEG2BPFI6FLXM_SSID 0x0304 + +#define SILICOM_PEG2DBI6_SSID 0x0308 +#define SILICOM_PEG2DBFI6_SSID 0x0309 +#define SILICOM_PEG2DBFI6LX_SSID 0x030A +#define SILICOM_PEG2DBFI6ZX_SSID 0x030B + + +#define SILICOM_MEG2BPI6_SSID 0x0310 +#define SILICOM_XEG2BPI6_SSID 0x0318 +#define SILICOM_PEG4BPI6FC_SSID 0x0328 +#define SILICOM_PEG4BPFI6FC_SSID 0x0329 +#define SILICOM_PEG4BPFI6FCLX_SSID 0x032A +#define SILICOM_PEG4BPFI6FCZX_SSID 0x032B + +#define SILICOM_PEG6BPI6_SSID 0x0340 +#define SILICOM_PE2G6BPI6_SSID 0x0341 + +#define SILICOM_PEG2BPI6SC6_SSID 0x0360 + +#define SILICOM_MEG2BPI6_SSID 0x0310 +#define SILICOM_XEG2BPI6_SSID 0x0318 +#define SILICOM_MEG4BPI6_SSID 0x0330 + + +#define SILICOM_PE2G4BPi80L_SSID 0x0380 + +#define SILICOM_M6E2G8BPi80A_SSID 0x0474 + +#define SILICOM_PE2G4BPi35_SSID 0x03d8 + +#define SILICOM_PE2G4BPFi80_SSID 0x0381 +#define SILICOM_PE2G4BPFi80LX_SSID 0x0382 +#define SILICOM_PE2G4BPFi80ZX_SSID 0x0383 + +#define SILICOM_PE2G4BPi80_SSID 0x0388 + +#define SILICOM_PE2G2BPi80_SSID 0x0390 +#define SILICOM_PE2G2BPFi80_SSID 0x0391 +#define SILICOM_PE2G2BPFi80LX_SSID 0x0392 +#define SILICOM_PE2G2BPFi80ZX_SSID 0x0393 + +#define SILICOM_PE2G4BPi35L_SSID 0x03D0 +#define SILICOM_PE2G4BPFi35_SSID 0x03D1 +#define SILICOM_PE2G4BPFi35CS_SSID 0x0b80 +#define SILICOM_PE2G4BPFi35LX_SSID 0x03D2 +#define SILICOM_PE2G4BPFi35ZX_SSID 0x03D3 + +#define SILICOM_M1E2G4BPi35_SSID 0x04D0 +#define SILICOM_M1E2G4BPFi35_SSID 0x04D1 +#define SILICOM_M1E2G4BPFi35LX_SSID 0x04D2 +#define SILICOM_M1E2G4BPFi35ZX_SSID 0x04D3 + +#define SILICOM_M1E2G4BPi35JP_SSID 0x1800 +#define SILICOM_M1E2G4BPi35JP1_SSID 0x1801 + + + +#define SILICOM_PE2G2BPi35_SSID 0x03c0 +#define SILICOM_PAC1200BPi35_SSID 0x03cc +#define SILICOM_PE2G2BPFi35_SSID 0x03C1 +#define SILICOM_PE2G2BPFi35LX_SSID 0x03C2 +#define SILICOM_PE2G2BPFi35ZX_SSID 0x03C3 + + + +#define SILICOM_PE2G6BPi35_SSID 0x03E0 +#define SILICOM_PE2G6BPi35CX_SSID 0x0AA0 + + + + + + + + +#define INTEL_PE210G2SPI9_SSID 0x00C + +#define SILICOM_M1EG2BPI6_SSID 0x400 + +#define SILICOM_M1EG2BPFI6_SSID 0x0401 +#define SILICOM_M1EG2BPFI6LX_SSID 0x0402 +#define SILICOM_M1EG2BPFI6ZX_SSID 0x0403 + +#define SILICOM_M1EG4BPI6_SSID 0x0420 + +#define SILICOM_M1EG4BPFI6_SSID 0x0421 +#define SILICOM_M1EG4BPFI6LX_SSID 0x0422 +#define SILICOM_M1EG4BPFI6ZX_SSID 0x0423 + +#define SILICOM_M1EG6BPI6_SSID 0x0440 + +#define SILICOM_M1E2G4BPi80_SSID 0x0460 +#define SILICOM_M1E2G4BPFi80_SSID 0x0461 +#define SILICOM_M1E2G4BPFi80LX_SSID 0x0462 +#define SILICOM_M1E2G4BPFi80ZX_SSID 0x0463 + +#define SILICOM_M6E2G8BPi80_SSID 0x0470 +#define SILICOM_PE210G2BPi40_SSID 0x01a0 +#define SILICOM_M1E210G2BPI40T_SSID 0x0480 +#define SILICOM_PE310G4BPi40_SSID 0x01a4 + +#define PEG540_IF_SERIES(pid) \ + ((pid==SILICOM_PE210G2BPi40_SSID) || \ + (pid==SILICOM_PE310G4BPi40_SSID) || \ + (pid==SILICOM_M1E210G2BPI40T_SSID)) + + + + + +#define OLD_IF_SERIES(pid) \ + ((pid==SILICOM_PXG2BPFI_SSID)|| \ + (pid==SILICOM_PXG2BPFILX_SSID)) + +#define P2BPFI_IF_SERIES(pid) \ + ((pid==SILICOM_PXG2BPFI_SSID)|| \ + (pid==SILICOM_PXG2BPFILX_SSID)|| \ + (pid==SILICOM_PEG2BPFI_SSID)|| \ + (pid==SILICOM_PEG2BPFID_SSID)|| \ + (pid==SILICOM_PEG2BPFIDLX_SSID)|| \ + (pid==SILICOM_MEG2BPFILN_SSID)|| \ + (pid==SILICOM_MEG2BPFINX_SSID)|| \ + (pid==SILICOM_PEG4BPFILX_SSID)|| \ + (pid==SILICOM_PEG4BPFI_SSID)|| \ + (pid==SILICOM_PXEG4BPFI_SSID)|| \ + (pid==SILICOM_PXG4BPFID_SSID)|| \ + (pid==SILICOM_PEG2TBFI_SSID)|| \ + (pid==SILICOM_PE10G2BPISR_SSID)|| \ + (pid==SILICOM_PE10G2BPILR_SSID)|| \ + (pid==SILICOM_PEG2BPFILX_SSID)|| \ + (pid==SILICOM_PMCXG2BPFI_SSID) || \ + (pid==SILICOM_MHIO8AD_SSID) || \ + (pid==SILICOM_PEG4BPFI5LX_SSID) || \ + (pid==SILICOM_PEG4BPFI5_SSID) || \ + (pid==SILICOM_PEG4BPFI6FC_SSID) || \ + (pid==SILICOM_PEG4BPFI6FCLX_SSID) || \ + (pid==SILICOM_PEG4BPFI6FCZX_SSID) || \ + (pid==NOKIA_PMCXG2BPFIN_SSID)|| \ + (pid==SILICOM_MEG2BPFILXLN_SSID)|| \ + (pid==SILICOM_MEG2BPFILXNX_SSID)|| \ + (pid==SILICOM_XE10G2BPIT_SSID)|| \ + (pid==SILICOM_XE10G2BPICX4_SSID)|| \ + (pid==SILICOM_XE10G2BPISR_SSID)|| \ + (pid==NOKIA_XE10G2BPIXR_SSID)|| \ + (pid==SILICOM_PE10GDBISR_SSID)|| \ + (pid==SILICOM_PE10GDBILR_SSID)|| \ + (pid==SILICOM_XE10G2BPILR_SSID)) + + +#define INTEL_IF_SERIES(pid) \ + ((pid==INTEL_PEG4BPII_SSID)|| \ + (pid==INTEL_PEG4BPIIO_SSID)|| \ + (pid==INTEL_PEG4BPFII_SSID)) + +#define NOKIA_SERIES(pid) \ + ((pid==NOKIA_PMCXG2BPIN_SSID)|| \ + (pid==NOKIA_PMCXG4BPIN_SSID)|| \ + (pid==SILICOM_PMCX4BPI_SSID)|| \ + (pid==NOKIA_PMCXG2BPFIN_SSID)|| \ + (pid==SILICOM_PMCXG2BPFI_SSID)|| \ + (pid==NOKIA_PMCXG2BPIN2_SSID)|| \ + (pid==NOKIA_PMCXG4BPIN2_SSID)|| \ + (pid==SILICOM_PMCX2BPI_SSID)) + +#define DISCF_IF_SERIES(pid) \ + (pid==SILICOM_PEG2TBFI_SSID) + +#define PEGF_IF_SERIES(pid) \ + ((pid==SILICOM_PEG2BPFI_SSID)|| \ + (pid==SILICOM_PEG2BPFID_SSID)|| \ + (pid==SILICOM_PEG2BPFIDLX_SSID)|| \ + (pid==SILICOM_PEG2BPFILX_SSID)|| \ + (pid==SILICOM_PEG4BPFI_SSID)|| \ + (pid==SILICOM_PXEG4BPFI_SSID)|| \ + (pid==SILICOM_MEG2BPFILN_SSID)|| \ + (pid==SILICOM_MEG2BPFINX_SSID)|| \ + (pid==SILICOM_PEG4BPFILX_SSID)|| \ + (pid==SILICOM_PEG2TBFI_SSID)|| \ + (pid==SILICOM_MEG2BPFILXLN_SSID)|| \ + (pid==SILICOM_MEG2BPFILXNX_SSID)) + + +#define TPL_IF_SERIES(pid) \ + ((pid==SILICOM_PXG2BPFIL_SSID)|| \ + (pid==SILICOM_PXG2BPFILLX_SSID)|| \ + (pid==SILICOM_PXG2TBFI_SSID)|| \ + (pid==SILICOM_PXG4BPFID_SSID)|| \ + (pid==SILICOM_PXG4BPFI_SSID)) + + +#define BP10G_IF_SERIES(pid) \ + ((pid==SILICOM_PE10G2BPISR_SSID)|| \ + (pid==SILICOM_PE10G2BPICX4_SSID)|| \ + (pid==SILICOM_PE10G2BPILR_SSID)|| \ + (pid==SILICOM_XE10G2BPIT_SSID)|| \ + (pid==SILICOM_XE10G2BPICX4_SSID)|| \ + (pid==SILICOM_XE10G2BPISR_SSID)|| \ + (pid==NOKIA_XE10G2BPIXR_SSID)|| \ + (pid==SILICOM_PE10GDBISR_SSID)|| \ + (pid==SILICOM_PE10GDBILR_SSID)|| \ + (pid==SILICOM_XE10G2BPILR_SSID)) + +#define BP10GB_IF_SERIES(pid) \ + ((pid==SILICOM_PE10G2BPTCX4_SSID)|| \ + (pid==SILICOM_PE10G2BPTSR_SSID)|| \ + (pid==SILICOM_PE10G2BPTLR_SSID)|| \ + (pid==SILICOM_PE10G2BPTT_SSID)) + + + +#define BP10G_CX4_SERIES(pid) \ + (pid==SILICOM_PE10G2BPICX4_SSID) + +#define BP10GB_CX4_SERIES(pid) \ + (pid==SILICOM_PE10G2BPTCX4_SSID) + + + + + + + +#define SILICOM_M2EG2BPFI6_SSID 0x0401 +#define SILICOM_M2EG2BPFI6LX_SSID 0x0402 +#define SILICOM_M2EG2BPFI6ZX_SSID 0x0403 +#define SILICOM_M2EG4BPI6_SSID 0x0420 + +#define SILICOM_M2EG4BPFI6_SSID 0x0421 +#define SILICOM_M2EG4BPFI6LX_SSID 0x0422 +#define SILICOM_M2EG4BPFI6ZX_SSID 0x0423 + +#define SILICOM_M2EG6BPI6_SSID 0x0440 + + + + + +#define SILICOM_M1E10G2BPI9CX4_SSID 0x481 +#define SILICOM_M1E10G2BPI9SR_SSID 0x482 +#define SILICOM_M1E10G2BPI9LR_SSID 0x483 +//#define SILICOM_M1E10G2BPI9T_SSID 0x480 + +#define SILICOM_M2E10G2BPI9CX4_SSID 0x481 +#define SILICOM_M2E10G2BPI9SR_SSID 0x482 +#define SILICOM_M2E10G2BPI9LR_SSID 0x483 +#define SILICOM_M2E10G2BPI9T_SSID 0x480 + + +#define SILICOM_PE210G2BPI9CX4_SSID 0x121 +#define SILICOM_PE210G2BPI9SR_SSID 0x122 +#define SILICOM_PE210G2BPI9LR_SSID 0x123 +#define SILICOM_PE210G2BPI9LRD_SSID 0x125 +#define SILICOM_PE210G2BPI9SRD_SSID 0x124 +#define SILICOM_PE210G2BPI9T_SSID 0x120 + +#define SILICOM_M1E210G2BPI9SRDJP_SSID 0x1E00 +#define SILICOM_M1E210G2BPI9SRDJP1_SSID 0x1E10 +#define SILICOM_M1E210G2BPI9LRDJP_SSID 0x1F00 +#define SILICOM_M1E210G2BPI9LRDJP1_SSID 0x1F10 + +#define SILICOM_PE310G4BPI71SRD_SSID 0x0502 +#define SILICOM_PE310G4BPI71LRD_SSID 0x0503 +#define SILICOM_PE340G2BPI71QS4_SSID 0x0512 +#define SILICOM_PE340G2BPI71QL4_SSID 0x0513 + + +#define BP40_IF_SERIES(pid) \ +((pid==SILICOM_PE310G4BPI71SRD_SSID)|| \ +(pid== SILICOM_PE310G4BPI71LRD_SSID)|| \ +(pid==SILICOM_PE340G2BPI71QS4_SSID)|| \ +(pid==SILICOM_PE340G2BPI71QL4_SSID)) + + +#define DBI_IF_SERIES(pid) \ +((pid==SILICOM_PE10GDBISR_SSID)|| \ + (pid==SILICOM_PE10GDBILR_SSID)|| \ + (pid==SILICOM_XE10G2BPILR_SSID)|| \ + (pid==SILICOM_PE210G2DBi9LR_SSID)) + + +#define PEGF5_IF_SERIES(pid) \ +((pid==SILICOM_PEG2BPFI5_SSID)|| \ + (pid==SILICOM_PEG2BPFI5LX_SSID)|| \ + (pid==SILICOM_PEG4BPFI6_SSID)|| \ + (pid==SILICOM_PE2G6BPI6_SSID)|| \ + (pid==SILICOM_PEG4BPFI6LX_SSID)|| \ + (pid==SILICOM_PEG4BPFI6ZX_SSID)|| \ + (pid==SILICOM_PEG2BPFI6_SSID)|| \ + (pid==SILICOM_PEG2BPFI6LX_SSID)|| \ + (pid==SILICOM_PEG2BPFI6ZX_SSID)|| \ + (pid==SILICOM_PEG2BPFI6FLXM_SSID)|| \ + (pid==SILICOM_PEG2DBFI6_SSID)|| \ + (pid==SILICOM_PEG2DBFI6LX_SSID)|| \ + (pid==SILICOM_PEG2DBFI6ZX_SSID)|| \ + (pid==SILICOM_PEG4BPI6FC_SSID)|| \ + (pid==SILICOM_PEG4BPFI6FCLX_SSID)|| \ + (pid==SILICOM_PEG4BPI6FC_SSID)|| \ + (pid==SILICOM_M1EG2BPFI6_SSID)|| \ + (pid==SILICOM_M1EG2BPFI6LX_SSID)|| \ + (pid==SILICOM_M1EG2BPFI6ZX_SSID)|| \ + (pid==SILICOM_M1EG4BPFI6_SSID)|| \ + (pid==SILICOM_M1EG4BPFI6LX_SSID)|| \ + (pid==SILICOM_M1EG4BPFI6ZX_SSID)|| \ + (pid==SILICOM_M2EG2BPFI6_SSID)|| \ + (pid==SILICOM_M2EG2BPFI6LX_SSID)|| \ + (pid==SILICOM_M2EG2BPFI6ZX_SSID)|| \ + (pid==SILICOM_M2EG4BPFI6_SSID)|| \ + (pid==SILICOM_M2EG4BPFI6LX_SSID)|| \ + (pid==SILICOM_M2EG4BPFI6ZX_SSID)|| \ + (pid==SILICOM_PEG4BPFI6FCZX_SSID)) + + + + +#define PEG5_IF_SERIES(pid) \ +((pid==SILICOM_PEG4BPI6_SSID)|| \ +(pid==SILICOM_PEG2BPI6_SSID)|| \ +(pid==SILICOM_PEG2BPI6SC6_SSID)|| \ +(pid==SILICOM_PEG4BPI6FC_SSID)|| \ +(pid==SILICOM_PEG6BPI6_SSID)|| \ +(pid==SILICOM_MEG2BPI6_SSID)|| \ +(pid==SILICOM_XEG2BPI6_SSID)|| \ +(pid==SILICOM_MEG4BPI6_SSID)|| \ +(pid==SILICOM_M1EG2BPI6_SSID)|| \ +(pid==SILICOM_M1EG4BPI6_SSID)|| \ +(pid==SILICOM_M1EG6BPI6_SSID)|| \ +(pid==SILICOM_PEG6BPI_SSID)|| \ +(pid==SILICOM_PEG4BPIL_SSID)|| \ +(pid==SILICOM_PEG2BISC6_SSID)|| \ +(pid==SILICOM_PE2G2BPi35_SSID)|| \ +(pid==SILICOM_PAC1200BPi35_SSID)|| \ +(pid==SILICOM_PE2G4BPi35_SSID)|| \ +(pid==SILICOM_PE2G4BPi35L_SSID)|| \ +(pid==SILICOM_M1E2G4BPi35_SSID)|| \ +(pid==SILICOM_M1E2G4BPi35JP_SSID)|| \ +(pid==SILICOM_M1E2G4BPi35JP1_SSID)|| \ +(pid==SILICOM_PE2G6BPi35_SSID)|| \ +(pid==SILICOM_PEG2BPI5_SSID)) + + +#define PEG80_IF_SERIES(pid) \ +((pid==SILICOM_M1E2G4BPi80_SSID)|| \ +(pid==SILICOM_M6E2G8BPi80_SSID)|| \ +(pid==SILICOM_PE2G4BPi80L_SSID)|| \ +(pid==SILICOM_M6E2G8BPi80A_SSID)|| \ +(pid==SILICOM_PE2G2BPi35_SSID)|| \ +(pid==SILICOM_PAC1200BPi35_SSID)|| \ +(pid==SILICOM_PE2G4BPi35_SSID)|| \ +(pid==SILICOM_PE2G4BPi35L_SSID)|| \ +(pid==SILICOM_M1E2G4BPi35_SSID)|| \ +(pid==SILICOM_M1E2G4BPi35JP_SSID)|| \ +(pid==SILICOM_M1E2G4BPi35JP1_SSID)|| \ +(pid==SILICOM_PE2G6BPi35_SSID)|| \ +(pid==SILICOM_PE2G2BPi80_SSID)|| \ +(pid==SILICOM_PE2G4BPi80_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80LX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80LX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35LX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35ZX_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi35_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi35LX_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi35ZX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35CS_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35LX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35ZX_SSID)) + + +#define PEGF80_IF_SERIES(pid) \ +((pid==SILICOM_PE2G4BPFi80_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80LX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi80_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi80LX_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80LX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi80ZX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35LX_SSID)|| \ +(pid==SILICOM_PE2G2BPFi35ZX_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi35_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi35LX_SSID)|| \ +(pid==SILICOM_M1E2G4BPFi35ZX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35CS_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35LX_SSID)|| \ +(pid==SILICOM_PE2G4BPFi35ZX_SSID)) + + +#define BP10G9_IF_SERIES(pid) \ +((pid==INTEL_PE210G2SPI9_SSID)|| \ +(pid==SILICOM_M1E10G2BPI9CX4_SSID)|| \ +(pid==SILICOM_M1E10G2BPI9SR_SSID)|| \ +(pid==SILICOM_M1E10G2BPI9LR_SSID)|| \ +(pid==SILICOM_M2E10G2BPI9CX4_SSID)|| \ +(pid==SILICOM_M2E10G2BPI9SR_SSID)|| \ +(pid==SILICOM_M2E10G2BPI9LR_SSID)|| \ +(pid==SILICOM_M2E10G2BPI9T_SSID)|| \ +(pid==SILICOM_PE210G2BPI9CX4_SSID)|| \ +(pid==SILICOM_PE210G2BPI9SR_SSID)|| \ +(pid==SILICOM_PE210G2BPI9LR_SSID)|| \ +(pid==SILICOM_PE210G2BPI9LRD_SSID)|| \ +(pid==SILICOM_PE210G2BPI9SRD_SSID)|| \ +(pid==SILICOM_PE210G2DBi9SR_SSID)|| \ +(pid==SILICOM_PE210G2DBi9SRRB_SSID)|| \ +(pid==SILICOM_PE210G2DBi9LR_SSID)|| \ +(pid==SILICOM_PE210G2DBi9LRRB_SSID)|| \ +(pid==SILICOM_PE310G4DBi940SR_SSID)|| \ +(pid==SILICOM_PE310G4DBi940LR_SSID)|| \ +(pid==SILICOM_PE310G4DBi940T_SSID)|| \ +(pid==SILICOM_PE310G4DBi9T_SSID)|| \ +(pid==SILICOM_PE310G4BPi9T_SSID)|| \ +(pid==SILICOM_PE310G4BPi9SR_SSID)|| \ +(pid==SILICOM_PE310G4BPi9SRD_SSID)|| \ +(pid==SILICOM_M6E310G4BPi9SR_SSID)|| \ +(pid==SILICOM_M6E310G4BPi9LR_SSID)|| \ +(pid==SILICOM_PE310G4BPi9LR_SSID)|| \ +(pid==SILICOM_PE310G4BPi9LRD_SSID)|| \ +(pid==SILICOM_M1E210G2BPI9SRDJP_SSID)|| \ +(pid==SILICOM_M1E210G2BPI9SRDJP1_SSID)|| \ +(pid==SILICOM_M1E210G2BPI9LRDJP_SSID)|| \ +(pid==SILICOM_M1E210G2BPI9LRDJP1_SSID)|| \ +(pid==SILICOM_PE210G2BPI9T_SSID)) + +#define BP71_IF_SERIES(pid) \ +((pid==SILICOM_PEG2BPI_SSID)|| \ +(pid==SILICOM_PEG2BPIX1_SSID)|| \ +(pid==SILICOM_PEG4BPIN_SSID)|| \ +(pid==SILICOM_PEG2BPFILX_SSID)|| \ +(pid==SILICOM_PEG4BPFI_SSID)|| \ +(pid==SILICOM_PEG2TBFI_SSID)|| \ +(pid==SILICOM_PEG4BPIPT_SSID)|| \ +(pid==SILICOM_PEG2BPFID_SSID)|| \ +(pid==SILICOM_PEG2BPFIDLX_SSID)|| \ +(pid==SILICOM_MEG2BPFILN_SSID)|| \ +(pid==SILICOM_MEG2BPFINX_SSID)|| \ +(pid==SILICOM_PEG4BPFILX_SSID)|| \ +(pid==SILICOM_MEG2BPFILXLN_SSID)||\ +(pid==SILICOM_PXEG4BPFI_SSID)) + + + + +/*******************************************************/ +/* 1G INTERFACE ****************************************/ +/*******************************************************/ + +/* Intel Registers */ +#define BPCTLI_CTRL 0x00000 +#define BPCTLI_LEDCTL 0x00E00 +#define BPCTLI_CTRL_SWDPIO0 0x00400000 +#define BPCTLI_CTRL_SWDPIN0 0x00040000 + +#define BPCTLI_DCA_ID 0x5B70 + + +#define BPCTLI_CTRL_EXT 0x00018 /* Extended Device Control - RW */ +#define BPCTLI_STATUS 0x00008 /* Device Status - RO */ + +#define BPCTLI_EERD 0x14 +#define BPCTLI_EEWR 0x102c + +/* HW related */ +#define BPCTLI_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Defineable Pin 6 */ +#define BPCTLI_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */ +#define BPCTLI_CTRL_SDP0_DATA 0x00040000 /* SWDPIN 0 value */ +#define BPCTLI_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */ +#define BPCTLI_CTRL_EXT_SDP7_DIR 0x00000800 /* Direction of SDP7 0=in 1=out */ +#define BPCTLI_CTRL_SDP0_DIR 0x00400000 /* SDP0 Input or output */ +#define BPCTLI_CTRL_SWDPIN0 0x00040000 +#define BPCTLI_CTRL_SWDPIN1 0x00080000 +#define BPCTLI_CTRL_SDP1_DIR 0x00800000 + +#define BPCTLI_STATUS_LU 0x00000002 /* Link up.0=no,1=link */ + + +#define BPCTLI_CTRL_SDP0_SHIFT 18 +#define BPCTLI_CTRL_EXT_SDP6_SHIFT 6 + +#define BPCTLI_STATUS_TBIMODE 0x00000020 +#define BPCTLI_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000 +#define BPCTLI_CTRL_EXT_LINK_MODE_MASK 0x00C00000 + +#define BPCTLI_LEDCTL_MODE_LED_ON 0xE +#define BPCTLI_LEDCTL_MODE_LED_OFF 0xF + +#define BPCTLI_LEDCTL_LED0_MODE_MASK 0x0000000F +#define BPCTLI_LEDCTL_LED0_MODE_SHIFT 0 +#define BPCTLI_LEDCTL_LED0_BLINK_RATE 0x0000020 +#define BPCTLI_LEDCTL_LED0_IVRT 0x00000040 +#define BPCTLI_LEDCTL_LED0_BLINK 0x00000080 + + +#define BPCTLI_CTRL_EXT_MCLK_DIR BPCTLI_CTRL_EXT_SDP7_DIR +#define BPCTLI_CTRL_EXT_MCLK_DATA BPCTLI_CTRL_EXT_SDP7_DATA +#define BPCTLI_CTRL_EXT_MDIO_DIR BPCTLI_CTRL_EXT_SDP6_DIR +#define BPCTLI_CTRL_EXT_MDIO_DATA BPCTLI_CTRL_EXT_SDP6_DATA + +#define BPCTLI_CTRL_EXT_MCLK_DIR5 BPCTLI_CTRL_SDP1_DIR +#define BPCTLI_CTRL_EXT_MCLK_DATA5 BPCTLI_CTRL_SWDPIN1 +#define BPCTLI_CTRL_EXT_MCLK_DIR80 BPCTLI_CTRL_EXT_SDP6_DIR +#define BPCTLI_CTRL_EXT_MCLK_DATA80 BPCTLI_CTRL_EXT_SDP6_DATA +#define BPCTLI_CTRL_EXT_MDIO_DIR5 BPCTLI_CTRL_SWDPIO0 +#define BPCTLI_CTRL_EXT_MDIO_DATA5 BPCTLI_CTRL_SWDPIN0 +#define BPCTLI_CTRL_EXT_MDIO_DIR80 BPCTLI_CTRL_SWDPIO0 +#define BPCTLI_CTRL_EXT_MDIO_DATA80 BPCTLI_CTRL_SWDPIN0 + + + +#define BPCTL_WRITE_REG(a, reg, value) \ + (writel((value), (void *)(((a)->mem_map) + BPCTLI_##reg))) + +#define BPCTL_READ_REG(a, reg) ( \ + readl((void *)((a)->mem_map) + BPCTLI_##reg)) + + +#define BPCTL_WRITE_FLUSH(a) BPCTL_READ_REG(a, STATUS) + +#define BPCTL_BP_WRITE_REG(a, reg, value) ({ \ + BPCTL_WRITE_REG(a, reg, value); \ + BPCTL_WRITE_FLUSH(a);}) + +/**************************************************************/ +/************** 82575 Interface********************************/ +/**************************************************************/ + +#define BPCTLI_MII_CR_POWER_DOWN 0x0800 +#define BPCTLI_PHY_CONTROL 0x00 /* Control Register */ +#define BPCTLI_MDIC 0x00020 /* MDI Control - RW */ +#define BPCTLI_IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ +#define BPCTLI_MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ + +#define BPCTLI_MDIC_DATA_MASK 0x0000FFFF +#define BPCTLI_MDIC_REG_MASK 0x001F0000 +#define BPCTLI_MDIC_REG_SHIFT 16 +#define BPCTLI_MDIC_PHY_MASK 0x03E00000 +#define BPCTLI_MDIC_PHY_SHIFT 21 +#define BPCTLI_MDIC_OP_WRITE 0x04000000 +#define BPCTLI_MDIC_OP_READ 0x08000000 +#define BPCTLI_MDIC_READY 0x10000000 +#define BPCTLI_MDIC_INT_EN 0x20000000 +#define BPCTLI_MDIC_ERROR 0x40000000 + + +#define BPCTLI_SWFW_PHY0_SM 0x02 +#define BPCTLI_SWFW_PHY1_SM 0x04 + +#define BPCTLI_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */ + +#define BPCTLI_SWSM 0x05B50 /* SW Semaphore */ +#define BPCTLI_FWSM 0x05B54 /* FW Semaphore */ + +#define BPCTLI_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ +#define BPCTLI_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ +#define BPCTLI_MAX_PHY_MULTI_PAGE_REG 0xF +#define BPCTLI_GEN_POLL_TIMEOUT 640 + +/********************************************************/ + + + + +/********************************************************/ +/* 10G INTERFACE ****************************************/ +/********************************************************/ + +#define BP10G_I2CCTL 0x28 + +/* I2CCTL Bit Masks */ +#define BP10G_I2C_CLK_IN 0x00000001 +#define BP10G_I2C_CLK_OUT 0x00000002 +#define BP10G_I2C_DATA_IN 0x00000004 +#define BP10G_I2C_DATA_OUT 0x00000008 + + +#define BP10G_ESDP 0x20 +#define BP10G_DCA_ID 0x11070 + +#define BP10G_SDP0_DIR 0x100 +#define BP10G_SDP1_DIR 0x200 +#define BP10G_SDP3_DIR 0x800 +#define BP10G_SDP4_DIR BIT_12 +#define BP10G_SDP5_DIR 0x2000 +#define BP10G_SDP0_DATA 0x001 +#define BP10G_SDP1_DATA 0x002 +#define BP10G_SDP3_DATA 0x008 +#define BP10G_SDP4_DATA 0x010 +#define BP10G_SDP5_DATA 0x020 + +#define BP10G_SDP2_DIR 0x400 +#define BP10G_SDP2_DATA 0x4 + + +#define BP10G_EODSDP 0x28 + +#define BP10G_SDP6_DATA_IN 0x001 +#define BP10G_SDP6_DATA_OUT 0x002 + +#define BP10G_SDP7_DATA_IN 0x004 +#define BP10G_SDP7_DATA_OUT 0x008 + +#define BP10G_MCLK_DATA_OUT BP10G_SDP7_DATA_OUT +#define BP10G_MDIO_DATA_OUT BP10G_SDP6_DATA_OUT +#define BP10G_MDIO_DATA_IN BP10G_SDP6_DATA_IN + +#define BP10G_MDIO_DATA /*BP10G_SDP5_DATA*/ BP10G_SDP3_DATA +#define BP10G_MDIO_DIR /*BP10G_SDP5_DIR*/ BP10G_SDP3_DATA + +/*#define BP10G_MCLK_DATA_OUT9 BP10G_I2C_CLK_OUT +#define BP10G_MDIO_DATA_OUT9 BP10G_I2C_DATA_OUT*/ + + +/*#define BP10G_MCLK_DATA_OUT9*/ /*BP10G_I2C_DATA_OUT*/ +#define BP10G_MDIO_DATA_OUT9 BP10G_I2C_DATA_OUT /*BP10G_I2C_CLK_OUT*/ + +/* VIA EOSDP ! */ +#define BP10G_MCLK_DATA_OUT9 BP10G_SDP4_DATA +#define BP10G_MCLK_DIR_OUT9 BP10G_SDP4_DIR + + +/*#define BP10G_MDIO_DATA_IN9 BP10G_I2C_DATA_IN*/ + +#define BP10G_MDIO_DATA_IN9 BP10G_I2C_DATA_IN /*BP10G_I2C_CLK_IN*/ + +#define BP10G_LEDCTL 0x00200 + +/* LEDCTL Bit Masks */ +#define BP10G_LED_IVRT_BASE 0x00000040 +#define BP10G_LED_BLINK_BASE 0x00000080 +#define BP10G_LED_MODE_MASK_BASE 0x0000000F +#define BP10G_LED_OFFSET(_base, _i) (_base << (8 * (_i))) +#define BP10G_LED_MODE_SHIFT(_i) (8*(_i)) +#define BP10G_LED_IVRT(_i) BP10G_LED_OFFSET(BP10G_LED_IVRT_BASE, _i) +#define BP10G_LED_BLINK(_i) BP10G_LED_OFFSET(BP10G_LED_BLINK_BASE, _i) +#define BP10G_LED_MODE_MASK(_i) BP10G_LED_OFFSET(BP10G_LED_MODE_MASK_BASE, _i) + +/* LED modes */ +#define BP10G_LED_LINK_UP 0x0 +#define BP10G_LED_LINK_10G 0x1 +#define BP10G_LED_MAC 0x2 +#define BP10G_LED_FILTER 0x3 +#define BP10G_LED_LINK_ACTIVE 0x4 +#define BP10G_LED_LINK_1G 0x5 +#define BP10G_LED_ON 0xE +#define BP10G_LED_OFF 0xF + +#define BP10G_STATUS 0x00008 +#define BP540_MDIO_DATA /*BP10G_SDP5_DATA*/ BP10G_SDP0_DATA +#define BP540_MDIO_DIR /*BP10G_SDP5_DIR*/ BP10G_SDP0_DIR +#define BP540_MCLK_DATA BP10G_SDP2_DATA +#define BP540_MCLK_DIR BP10G_SDP2_DIR + + + +#define BP10G_WRITE_REG(a, reg, value) \ + (writel((value), (void *)(((a)->mem_map) + BP10G_##reg))) + +#define BP10G_READ_REG(a, reg) ( \ + readl((void *)((a)->mem_map) + BP10G_##reg)) + +/*****BROADCOM*******************************************/ + +#define BP10GB_MISC_REG_GPIO 0xa490 +#define BP10GB_GPIO3_P0 BIT_3 +#define BP10GB_GPIO3_P1 BIT_7 + +#define BP10GB_GPIO3_SET_P0 BIT_11 +#define BP10GB_GPIO3_CLR_P0 BIT_19 +#define BP10GB_GPIO3_OE_P0 BIT_27 + +#define BP10GB_GPIO3_SET_P1 BIT_15 +#define BP10GB_GPIO3_CLR_P1 BIT_23 +#define BP10GB_GPIO3_OE_P1 BIT_31 + +#define BP10GB_GPIO0_P1 0x10 +#define BP10GB_GPIO0_P0 0x1 +#define BP10GB_GPIO0_CLR_P0 0x10000 +#define BP10GB_GPIO0_CLR_P1 0x100000 +#define BP10GB_GPIO0_SET_P0 0x100 +#define BP10GB_GPIO0_SET_P1 0x1000 + + + +#define BP10GB_GPIO0_OE_P1 0x10000000 +#define BP10GB_GPIO0_OE_P0 0x1000000 + +#define BP10GB_MISC_REG_SPIO 0xa4fc +#define BP10GB_GPIO4_OE BIT_28 +#define BP10GB_GPIO5_OE BIT_29 +#define BP10GB_GPIO4_CLR BIT_20 +#define BP10GB_GPIO5_CLR BIT_21 +#define BP10GB_GPIO4_SET BIT_12 +#define BP10GB_GPIO5_SET BIT_13 +#define BP10GB_GPIO4 BIT_4 +#define BP10GB_GPIO5 BIT_5 + + + +#define BP10GB_MCLK_DIR BP10GB_GPIO5_OE +#define BP10GB_MDIO_DIR BP10GB_GPIO4_OE + +#define BP10GB_MCLK_DATA BP10GB_GPIO5 +#define BP10GB_MDIO_DATA BP10GB_GPIO4 + +#define BP10GB_MCLK_SET BP10GB_GPIO5_SET +#define BP10GB_MDIO_SET BP10GB_GPIO4_SET + +#define BP10GB_MCLK_CLR BP10GB_GPIO5_CLR +#define BP10GB_MDIO_CLR BP10GB_GPIO4_CLR + + +/* toggle LED 4 times per second = 2 "blinks" per second */ +#define BPVM_ID_INTERVAL (HZ/4) + +/* bit defines for adapter->led_status */ +#define BPVM_LED_ON 0 + +/*#define BPCTLI_LEDCTL_MODE_LED_ON 0xE +#define BPCTLI_LEDCTL_MODE_LED_OFF 0xF*/ + +#define BPCTLI_EEPROM_ID_LED_SETTINGS 0x0004 +#define ID_LED_RESERVED_0000 0x0000 +#define ID_LED_RESERVED_FFFF 0xFFFF +#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \ + (ID_LED_OFF1_OFF2 << 8) | \ + (ID_LED_DEF1_DEF2 << 4) | \ + (ID_LED_DEF1_DEF2)) +#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \ + (ID_LED_DEF1_OFF2 << 8) | \ + (ID_LED_DEF1_ON2 << 4) | \ + (ID_LED_DEF1_DEF2)) +#define ID_LED_DEF1_DEF2 0x1 +#define ID_LED_DEF1_ON2 0x2 +#define ID_LED_DEF1_OFF2 0x3 +#define ID_LED_ON1_DEF2 0x4 +#define ID_LED_ON1_ON2 0x5 +#define ID_LED_ON1_OFF2 0x6 +#define ID_LED_OFF1_DEF2 0x7 +#define ID_LED_OFF1_ON2 0x8 +#define ID_LED_OFF1_OFF2 0x9 + +#define BPCTL_SUCCESS 0 +#define BPCTL_NVM_POLL_READ 0 +#define BPCTL_NVM_RW_ADDR_SHIFT 2 +#define BPCTL_ERR_NVM 1 +#define BPCTL_NVM_RW_REG_DATA 16 +#define BPCTL_NVM_RW_REG_DONE 2 + +#define BPCTL_NVM_RW_REG_START 1 + +#define BP40G_I2CCMD 0x000881E0 +#define BP40G_I2CSEL 0x000881C0 +#define BP40G_I2CPARAMS 0x000881AC + +#define BP40G_CLK_DATA_OUT BIT_9 +#define BP40G_MDIO_DATA_OUT BIT_10 +#define BP40G_MDIO_DIR_OUTN BIT_11 +#define BP40G_MDIO_DATA_IN BIT_12 +#define BP40G_CLK_DIR_OUTN BIT_13 + +#define BP40G_GPIO_SET 0x00088184 +#define BP40G_GPIO_STAT 0x0008817C + +#define BP40GB_GPIO_OE BIT_4 +#define BP40GB_GPIO_SDP_MODE_MASK (BIT_7 | BIT_8 | BIT_9) + +#define TIME_CLK 10 //40 //20 //10 +#define TIME_DET //10 // 5 + + +#define BP10GB_WRITE_REG(a, reg, value) \ + (writel((value), (void *)(((a)->mem_map) + BP10GB_##reg))) + +#define BP10GB_READ_REG(a, reg) ( \ + readl((void *)((a)->mem_map) + BP10GB_##reg)) + +#define BP10G_WRITE_FLUSH(a) BP10G_READ_REG(a, STATUS) + +#define BP40G_READ_REG(a, reg) ( \ + readl((void *)((a)->mem_map) + BP40G_##reg+0x4*((a)->func))) + +#define BP40G_WRITE_REG(a, reg, value) \ + (writel((value), (void *)(((a)->mem_map) + BP40G_##reg+0x4*((a)->func)))) + +#define BP40G_READ_GPIO_CTL(a, n) ( \ + readl((void *)((a)->mem_map) + 0x88100+0x4*n)) + +#define BP40G_WRITE_GPIO_CTL(a, n, value) \ + (writel((value), (void *)(((a)->mem_map) + 0x88100+0x4*n))) + +#define BP40G_WR_REG(a, reg, value) \ + (writel((value), (void *)(((a)->mem_map) + BP40G_##reg))) + +#define BP40G_RD_REG(a, reg) ( \ + readl((void *)((a)->mem_map) + BP40G_##reg)) + + +#endif diff --git a/bp_msg.h b/bp_msg.h new file mode 100755 index 0000000..90780bb --- /dev/null +++ b/bp_msg.h @@ -0,0 +1,330 @@ +/************************************************************************** + +Copyright (c) 2006-2013, Silicom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Silicom nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#ifndef _BP_MSG_H +#define _BP_MSG_H + +#define HELP_ENTRY "help" +#define INFO_ENTRY "info" + +#define IS_BYPASS_ENTRY "is_bypass" +#define GET_BYPASS_SLAVE_ENTRY "get_bypass_slave" +#define GET_BYPASS_CAPS_ENTRY "get_bypass_caps" +#define GET_WD_SET_CAPS_ENTRY "get_wd_set_caps" +#define SET_BYPASS_ENTRY "set_bypass" +#define GET_BYPASS_ENTRY "get_bypass" +#define GET_WD_EXPIRE_ENTRY "get_wd_expire" +#define GET_BYPASS_CHANGE_ENTRY "get_bypass_change" +#define SET_DIS_BYPASS_ENTRY "set_dis_bypass" +#define GET_DIS_BYPASS_ENTRY "get_dis_bypass" +#define SET_BYPASS_PWOFF_ENTRY "set_bypass_pwoff" +#define GET_BYPASS_PWOFF_ENTRY "get_bypass_pwoff" +#define SET_BYPASS_PWUP_ENTRY "set_bypass_pwup" +#define GET_BYPASS_PWUP_ENTRY "get_bypass_pwup" +#define SET_STD_NIC_ENTRY "set_std_nic" +#define GET_STD_NIC_ENTRY "get_std_nic" +#define SET_BYPASS_WD_ENTRY "set_bypass_wd" +#define GET_BYPASS_WD_ENTRY "get_bypass_wd" +#define GET_WD_EXPIRE_TIME_ENTRY "get_wd_time_expire" +#define RESET_BYPASS_WD_TIMER_ENTRY "reset_bypass_wd" +#define SET_TX_ENTRY "set_tx" +#define GET_TX_ENTRY "get_tx" +#define BYPASS_ENABLE "on" +#define BYPASS_DISABLE "off" +#define TAP_MODE "tap" +#define BYPASS_MODE "bypass" +#define DISC_MODE "disc" +#define SET_TAP_ENTRY "set_tap" +#define GET_TAP_ENTRY "get_tap" +#define SET_FORCE_LINK_ENTRY "set_force_link_on" +#define GET_FORCE_LINK_ENTRY "get_force_link_on" +#define SET_BP_MANUF_ENTRY "set_bp_manuf" + + +#define SET_HW_RESET_ENTRY "set_hw_reset" +#define GET_HW_RESET_ENTRY "get_hw_reset" + +#define SET_WAIT_AT_PWUP_ENTRY "set_wait_at_pwup" +#define GET_WAIT_AT_PWUP_ENTRY "get_wait_at_pwup" + + +#define GET_TAP_CHANGE_ENTRY "get_tap_change" +#define SET_DIS_TAP_ENTRY "set_dis_tap" +#define GET_DIS_TAP_ENTRY "get_dis_tap" +#define SET_TAP_PWUP_ENTRY "set_tap_pwup" +#define GET_TAP_PWUP_ENTRY "get_tap_pwup" +#define SET_DISC_ENTRY "set_disc" +#define GET_DISC_ENTRY "get_disc" +#define GET_DISC_CHANGE_ENTRY "get_disc_change" +#define SET_DIS_DISC_ENTRY "set_dis_disc" +#define GET_DIS_DISC_ENTRY "get_dis_disc" +#define SET_DISC_PWUP_ENTRY "set_disc_pwup" +#define GET_DISC_PWUP_ENTRY "get_disc_pwup" +#define SET_WD_EXP_MODE_ENTRY "set_wd_exp_mode" +#define GET_WD_EXP_MODE_ENTRY "get_wd_exp_mode" +#define SET_WD_AUTORESET_ENTRY "set_wd_autoreset" +#define GET_WD_AUTORESET_ENTRY "get_wd_autoreset" +#define GET_BYPASS_INFO_ENTRY "get_bypass_info" + +#ifdef BP_SELF_TEST +#define SET_BP_SELF_TEST_ENTRY "set_bst" +#define GET_BP_SELF_TEST_ENTRY "get_bst" +#endif + +#define IF_NAME "eth" + +/********MESSAGES*************/ +#define NO_BPT_DEV_MSG "No Bypass/TAP control devices were found\n" +#define NOT_SUPP_MSG "The interface is not capable of the operation.\n" +#define NOT_SUPP_BP_MSG "The interface doesn't support Bypass.\n" +#define NOT_SUPP_BPT_MSG "The interface doesn't support Bypass/TAP.\n" +#define SLAVE_IF_MSG "The interface is a slave interface.\n" +#define MASTER_IF_MSG "The interface is a control interface.\n" +#define NOT_SUPP_BPT_SLAVE_MSG "The interface is a slave interface or doesn't support Bypass/TAP.\n" +#define NOT_SUPP_BP_SLAVE_MSG "The interface is a slave interface or doesn't support Bypass.\n" +#define NOT_SUPP_BP_SLAVE_UN_MSG "The interface is a slave interface or doesn't support Bypass or Bypass state is unknown.\n" +#define NOT_SUPP_TAP_SLAVE_MSG "The interface is a slave interface or doesn't support TAP.\n" +#define NOT_SUPP_SLAVE_MSG "The interface is a slave interface or doesn't support this feature.\n" +#define BP_PAIR_MSG "%s is a slave port.\n" +#define SUCCESS_MSG "completed successfully.\n" +#define BP_MODE_MSG "The interface is in the Bypass mode.\n" +#define NON_BP_MODE_MSG "The interface is in the non-Bypass mode.\n" +#define TAP_MODE_MSG "The interface is in the TAP mode.\n" +#define DISC_MODE_MSG "The interface is in the Disconnect mode.\n" +#define DISC_PORT_MODE_MSG "The interface is in the Disconnect Port mode.\n" + +#define NON_TAP_MODE_MSG "The interface is in the non-TAP mode.\n" +#define NON_DISC_MODE_MSG "The interface is in the non-Disconnect mode.\n" +#define NON_DISC_PORT_MODE_MSG "The interface is in the non-Disconnect Port mode.\n" +#define NORMAL_MODE_MSG "The interface is in the Normal mode.\n" +#define TAP_BP_MODE_EN_MSG "Bypass/TAP mode is enabled.\n" +#define NORMAL_MODE_LAST_MSG "There was no change to bypass/tap/disc from last read of the status.\n" +#define NON_BYPASS_MODE_LAST_MSG "There was no change to bypass from last read of the status.\n" +#define NON_TAP_MODE_LAST_MSG "There was no change to tap from last read of the status.\n" +#define NON_DISC_MODE_LAST_MSG "There was no change to disconnect from last read of the status.\n" + +#define TAP_MODE_LAST_MSG "There was a change to TAP state or it's now in TAP state.\n" +//#define NON_TAP_MODE_LAST_MSG "There was a change to non-TAP state or it's now in non-TAP state.\n" + +#define DISC_MODE_LAST_MSG "There was a change to Disconnect state or it's now in Disconnect state.\n" +//#define NON_DISC_MODE_LAST_MSG "There was a change to non-Disconnect state or it's now in non-Disconnect state.\n" +#define BP_MODE_LAST_MSG "There was a change to Bypass state or it's now in Bypass state.\n" +#define BP_MODE_EN_MSG "Bypass mode is enabled.\n" +#define BP_MODE_DIS_MSG "Bypass mode is disabled.\n" +#define TAP_MODE_EN_MSG "TAP mode is enabled.\n" +#define TAP_MODE_DIS_MSG "TAP mode is disabled.\n" +#define DISC_MODE_EN_MSG "Disconnect mode is enabled.\n" +#define DISC_MODE_DIS_MSG "Disconnect mode is disabled.\n" +#define BP_DIS_PWOFF_MSG "The interface is in the non-Bypass mode at power off state.\n" +#define BP_EN_PWOFF_MSG "The interface is in the Bypass mode at power off state.\n" +#define BP_DIS_PWUP_MSG "The interface is in the non-Bypass mode at power up state.\n" +#define BP_EN_PWUP_MSG "The interface is in the Bypass mode at power up state.\n" +#define TAP_EN_PWUP_MSG "The interface is in the TAP mode at power up state.\n" +#define TAP_DIS_PWUP_MSG "The interface is in the non-TAP mode at power up state.\n" +#define DISC_EN_PWUP_MSG "The interface is in the Disconnect mode at power up state.\n" +#define DISC_DIS_PWUP_MSG "The interface is in the non-Disconnect mode at power up state.\n" +#define DISC_PORT_EN_PWUP_MSG "The interface is in the Disconnect Port mode at power up state.\n" +#define DISC_PORT_DIS_PWUP_MSG "The interface is in the non-Disconnect Port mode at power up state.\n" + +#define WDT_STATE_MSG "WDT is enabled with %d ms timeout value.\n" +#define WD_DIS_MSG "WDT is disabled.\n" +#define NOT_WD_DIS_MSG "WDT is disabled or WDT state is unknown.\n" +#define WD_STATE_EXT_MSG "WDT is enabled with %d ms timeout value.\n" +#define WD_TIME_LEFT_MSG "WDT is enabled; %d ms time left till WDT expired.\n" +#define WD_STATE_UNKNOWN_MSG "WDT state is unknown.\n" +#define NOT_NET_DEV_MSG "%s does not appear to be a Silicom Bypass device. Must be "IF_NAME".\n" +#define NOT_WDT_SLAVE_MSG "The interface is a slave interface or WDT state is unknown.\n" +#define WDT_EXP_MSG "WDT has expired.\n" +#define STD_NIC_MODE_MSG "The interface is in Standard NIC mode.\n" +#define NON_STD_NIC_MODE_MSG "The interface is not in Standard NIC mode.\n" +#define TX_EN_MSG "Transmit is enable.\n" +#define TX_DIS_MSG "Transmit is disable.\n" +#define TPL_EN_MSG "TPL is enable.\n" +#define TPL_DIS_MSG "TPL is disable.\n" +#define TAP_WD_EXP_MODE_MSG "When WDT timeout occurs, the interface will be in the TAP mode.\n" +#define BYPASS_WD_EXP_MODE_MSG "When WDT timeout occurs, the interface will be in the Bypass mode.\n" +#define BP_WAIT_AT_PWUP_EN_MSG "wait_at_pwup is enable.\n" +#define BP_WAIT_AT_PWUP_DIS_MSG "wait_at_pwup is disable.\n" +#define BP_HW_RESET_EN_MSG "hw_reset is enable.\n" +#define BP_HW_RESET_DIS_MSG "hw_reset is disable.\n" +#define FORCE_LINK_EN_MSG "Force link is enable.\n" +#define FORCE_LINK_DIS_MSG "Force link is disable.\n" + +#define DISC_WD_EXP_MODE_MSG "When WDT timeout occurs, the interface will be in the Disconnect mode.\n" +#define NOT_DEV_MSG "No such device.\n" +#define GET_BPSLAVE_FAIL_MSG "Get Bypass slave failed.\n" +#define SET_BP_FAIL_MSG "Set Bypass failed.\n" +#define GET_BP_FAIL_MSG "Get Bypass failed.\n" +#define GET_BP_CHANGE_FAIL_MSG "Get Bypass change failed.\n" +#define SET_DIS_BP_FAIL_MSG "Set disable Bypass failed.\n" +#define GET_DIS_BP_FAIL_MSG "Get disable Bypass failed.\n" +#define SET_BP_PWOFF_FAIL_MSG "Set Bypass/Normal mode on Power Off failed.\n" +#define GET_BP_PWOFF_FAIL_MSG "Get Bypass/Normal mode on Power Off failed.\n" +#define SET_BP_PWUP_FAIL_MSG "Set Bypass/Normal mode on Power Up failed.\n" +#define GET_BP_PWUP_FAIL_MSG "Get Bypass/Normal mode on Power Up failed.\n" +#define SET_BP_WD_FAIL_MSG "Set Bypass WD failed.\n" +#define GET_BP_WD_FAIL_MSG "Get Bypass WD failed.\n" +#define RESET_BP_WD_FAIL_MSG "Reset Bypass WD failed\n" +#define SET_STD_NIC_FAIL_MSG "Set Standard NIC mode failed\n" +#define GET_TAP_PWUP_FAIL_MSG "Get TAP mode on power up failed\n" +#define GET_TAP_FAIL_MSG "Get TAP mode failed\n" +#define GET_TAP_CHANGE_FAIL_MSG "Get TAP change failed.\n" +#define GET_DIS_TAP_FAIL_MSG "Get disable TAP failed.\n" + +#define GET_DISC_PWUP_FAIL_MSG "Get Disconnect mode on power up failed\n" +#define GET_DISC_FAIL_MSG "Get Disconnect mode failed\n" + +#define GET_DISC_PORT_PWUP_FAIL_MSG "Get Disconnect Port mode on power up failed\n" +#define GET_DISC_PORT_FAIL_MSG "Get Disconnect Port mode failed\n" + +#define GET_DISC_CHANGE_FAIL_MSG "Get Disconnect change failed.\n" +#define GET_DIS_DISC_FAIL_MSG "Get disable Disconnect failed.\n" + +#define WD_AUTORESET_STATE_MSG "WDT autoreset is enabled with %d ms period.\n" +#define WD_AUTORESET_DIS_MSG "WDT autoreset is disabled.\n" + +#ifdef BP_SELF_TEST +#define BP_SELF_TEST_MSG "Bypass Self Test is enabled with %d ms period.\n" +#define BP_SELF_TEST_DIS_MSG "Bypass Self Test is disabled.\n" +#endif + + +#define NOT_SUPP_TXCTL_MSG "The interface doesn't support TX Control feature.\n" +#define NOT_SUPP_TXCTL_SLAVE_MSG "The interface is a slave interface.\n" +#define NO_TXCTL_DEV_MSG "No TX control devices were found\n" +#define TXCTL_FAIL_MSG "Set Transmit mode failed.\n" +#define TXCTL_OK_MSG "Set Transmit mode completed successfully.\n" +#define GET_DEV_NUM_FAIL_MSG "Get TX Control devices number failed\n" +#define GET_TXCTL_FAIL_MSG "Get Transmit mode failed.\n" + +#define NO_BPCTL_DEV_MSG "No Bypass-SD/TAP-SD control devices were found\n" +#define NOT_SUPP_BPCTL_MSG "The interface is not Bypass-SD/TAP-SD device.\n" +#define NO_BP_DEV_MSG "No Bypass-SD control devices were found\n" + + + + +#define BP_CAP_MSG "\nBP_CAP The interface is Bypass/TAP capable in general.\n" +#define BP_STATUS_CAP_MSG "\nBP_STATUS_CAP The interface can report of the current Bypass mode.\n" +#define BP_STATUS_CHANGE_CAP_MSG "\nBP_STATUS_CHANGE_CAP The interface can report on a change to bypass mode\n" \ + " from the last time the mode was defined\n" +#define SW_CTL_CAP_MSG "\nSW_CTL_CAP The interface is Software controlled capable for\n" \ + " bypass/non bypass/TAP/non TAP modes.\n" +#define BP_DIS_CAP_MSG "\nBP_DIS_CAP The interface is capable of disabling the Bypass mode\n" \ + " at all times. This mode will retain its mode even\n" \ + " during power loss and also after power recovery. This\n" \ + " will overcome on any bypass operation due to watchdog\n" \ + " timeout or set bypass command.\n" +#define BP_DIS_STATUS_CAP_MSG "\nBP_DIS_STATUS_CAP The interface can report of the current DIS_BP_CAP.\n" +#define STD_NIC_CAP_MSG "\nSTD_NIC_CAP The interface is capable to be configured to operate\n" \ + " as standard, non Bypass, NIC interface (have direct\n" \ + " connection to interfaces at all power modes).\n" +#define BP_PWOFF_ON_CAP_MSG "\nBP_PWOFF_ON_CAP The interface can be in Bypass mode at power off state.\n" +#define BP_PWOFF_OFF_CAP_MSG "\nBP_PWOFF_OFF_CAP The interface can disconnect the Bypass mode at\n" \ + " power off state without effecting all the other\n" \ + " states of operation.\n" +#define BP_PWOFF_CTL_CAP_MSG "\nBP_PWOFF_CTL_CAP The behavior of the Bypass mode at Power-off state\n" \ + " can be controlled by software without effecting any\n" \ + " other state.\n" +#define BP_PWUP_ON_CAP_MSG "\nBP_PWUP_ON_CAP The interface can be in Bypass mode when power is\n" \ + " turned on (until the system take control of the\n" \ + " bypass functionality).\n" +#define BP_PWUP_OFF_CAP_MSG "\nBP_PWUP_OFF_CAP The interface can disconnect from Bypass mode when\n" \ + " power is turned on (until the system take control\n" \ + " of the bypass functionality).\n" +#define BP_PWUP_CTL_CAP_MSG "\nBP_PWUP_CTL_CAP The behavior of the Bypass mode at Power-up can be\n" \ + " controlled by software\n" +#define WD_CTL_CAP_MSG "\nWD_CTL_CAP The interface has watchdog capabilities to turn to\n" \ + " Bypass mode when not reset for defined period of time.\n" +#define WD_STATUS_CAP_MSG "\nWD_STATUS_CAP The interface can report on the watchdog status\n" \ + " (active/inactive)\n" +#define WD_TIMEOUT_CAP_MSG "\nWD_TIMEOUT_CAP The interface can report the time left till watchdog\n" \ + " triggers to Bypass mode.\n" + +#define WD_MIN_TIME_MSG "\nWD_MIN_TIME = %d The interface WD minimal time period (ms).\n\n" +#define WD_STEP_TIME_MSG "\nWD_STEP_TIME = %d The steps of the WD timer in\n" \ + " 0 - for linear steps (WD_MIN_TIME * X)\n" \ + " 1 - for multiply by 2 from previous step (WD_MIN_TIME * 2^X).\n" +#define WD_STEP_COUNT_MSG "\nWD_STEP_COUNT_MSG = %d Number of bits available for defining the number of WDT steps.\n" \ + " From that the number of steps the WDT will have is 2^Y\n" \ + " (Y number of bits available for defining the value).\n\n" + +#define TX_CTL_CAP_MSG "\nTX_CTL_CAP The interface is capable to control PHY transmitter on and off.\n" +#define TX_STATUS_CAP_MSG "\nTX_STATUS_CAP The interface can report the status of the PHY transmitter.\n" +#define TAP_CAP_MSG "\nTAP_CAP The interface is TAP capable in general.\n" +#define TAP_STATUS_CAP_MSG "\nTAP_STATUS_CAP The interface can report of the current TAP mode.\n" +#define TAP_STATUS_CHANGE_CAP_MSG "\nTAP_STATUS_CHANGE_CAP The interface can report on a change to TAP mode\n" \ + " from the last time the mode was defined\n" +#define TAP_DIS_CAP_MSG "\nTAP_DIS_CAP The interface is capable of disabling the TAP mode\n" \ + " at all times. This mode will retain its mode even\n" \ + " during power loss and also after power recovery. This\n" \ + " will overcome on any TAP operation due to watchdog\n" \ + " timeout or set TAP command.\n" +#define TAP_DIS_STATUS_CAP_MSG "\nTAP_DIS_STATUS_CAP The interface can report of the current DIS_TAP_CAP.\n" +#define TAP_PWUP_ON_CAP_MSG "\nTAP_PWUP_ON_CAP The interface can be in TAP mode when power is\n" \ + " turned on (until the system take control of the\n" \ + " TAP functionality).\n" +#define TAP_PWUP_OFF_CAP_MSG "\nTAP_PWUP_OFF_CAP The interface can disconnect from TAP mode when\n" \ + " power is turned on (until the system take control\n" \ + " of the TAP functionality).\n" +#define TAP_PWUP_CTL_CAP_MSG "\nTAP_PWUP_CTL_CAP The behavior of the TAP mode at Power-up can be\n" \ + " controlled by software\n" +#define NIC_CAP_NEG_MSG "\nNIC_CAP_NEG The interface is NIC capable in general - \n" \ + " negative polarity (0 - NIC capable)\n" + +#define TPL_CAP_MSG "\nTPL_CAP The interface is TPL capable in general.\n" +#define DISC_CAP_MSG "\nDISC_CAP The interface is Disconnect capable in general.\n" +#define DISC_STATUS_CAP_MSG "\nDISC_STATUS_CAP The interface can report of the current Disconnect mode.\n" +#if 0 +#define DISC_STATUS_CHANGE_CAP_MSG "\nDISC_STATUS_CHANGE_CAP The interface can report on a change to Disconnect \n" \ + " mode from the last time the mode was defined\n" +#endif +#define DISC_DIS_CAP_MSG "\nDISC_DIS_CAP The interface is capable of disabling the Disconnect mode\n" \ + " at all times. This mode will retain its mode even\n" \ + " during power loss and also after power recovery. This\n" \ + " will overcome on any Disconnect operation due to watchdog\n" \ + " timeout or set Disconnect command.\n" +#if 0 +#define DISC_DIS_STATUS_CAP_MSG "\nDISC_DIS_STATUS_CAP The interface can report of the current DIS_DISC_CAP.\n" +#define DISC_PWUP_ON_CAP_MSG "\nDISC_PWUP_ON_CAP The interface can be in Disconnect mode when power is\n" \ + " turned on (until the system take control of the\n" \ + " Disconnect functionality).\n" +#define DISC_PWUP_OFF_CAP_MSG "\nDISC_PWUP_OFF_CAP The interface can disconnect from Disconnect mode when\n" \ + " power is turned on (until the system take control\n" \ + " of the Disconnect functionality).\n" +#endif +#define DISC_PWUP_CTL_CAP_MSG "\nDISC_PWUP_CTL_CAP The behavior of the Disconnect mode at Power-up can be\n" \ + " controlled by software\n" + + +#endif diff --git a/bprd_ioctl.h b/bprd_ioctl.h new file mode 100755 index 0000000..682e876 --- /dev/null +++ b/bprd_ioctl.h @@ -0,0 +1,176 @@ +/************************************************************************** + +Copyright (c) 2006-2013, Silicom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Silicom nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#ifndef BPRD_IOCTL_H +#define BPRD_IOCTL_H + +#define BP_CAP 0x01 //BIT_0 +#define BP_STATUS_CAP 0x02 //BIT_1 +#define BP_STATUS_CHANGE_CAP 0x04 //BIT_2 +#define SW_CTL_CAP 0x08 //BIT_3 +#define BP_DIS_CAP 0x10 //BIT_4 +#define BP_DIS_STATUS_CAP 0x20 //BIT_5 +#define STD_NIC_CAP 0x40 //BIT_6 +#define BP_PWOFF_ON_CAP 0x80 //BIT_7 +#define BP_PWOFF_OFF_CAP 0x0100 //BIT_8 +#define BP_PWOFF_CTL_CAP 0x0200 //BIT_9 +#define BP_PWUP_ON_CAP 0x0400 //BIT_10 +#define BP_PWUP_OFF_CAP 0x0800 //BIT_11 +#define BP_PWUP_CTL_CAP 0x1000 //BIT_12 +#define WD_CTL_CAP 0x2000 //BIT_13 +#define WD_STATUS_CAP 0x4000 //BIT_14 +#define WD_TIMEOUT_CAP 0x8000 //BIT_15 +#define TX_CTL_CAP 0x10000 //BIT_16 +#define TX_STATUS_CAP 0x20000 //BIT_17 +#define TAP_CAP 0x40000 //BIT_18 +#define TAP_STATUS_CAP 0x80000 //BIT_19 +#define TAP_STATUS_CHANGE_CAP 0x100000 //BIT_20 +#define TAP_DIS_CAP 0x200000 //BIT_21 +#define TAP_DIS_STATUS_CAP 0x400000 //BIT_22 +#define TAP_PWUP_ON_CAP 0x800000 //BIT_23 +#define TAP_PWUP_OFF_CAP 0x1000000 //BIT 24 +#define TAP_PWUP_CTL_CAP 0x2000000 //BIT 25 +#define NIC_CAP_NEG 0x4000000 //BIT 26 +#define TPL_CAP 0x8000000 //BIT 27 +#define DISC_CAP 0x10000000 //BIT 28 +#define DISC_DIS_CAP 0x20000000 //BIT 29 +#define DISC_PWUP_CTL_CAP 0x40000000 //BIT 30 + +#define TPL2_CAP_EX 0x01 +#define DISC_PORT_CAP_EX 0x02 + + + + +#define WD_MIN_TIME_MASK(val) (val & 0xf) +#define WD_STEP_COUNT_MASK(val) ((val & 0xf) << 5) +#define WDT_STEP_TIME 0x10 //BIT_4 + +#define WD_MIN_TIME_GET(desc) (desc & 0xf) +#define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf + + +typedef enum { + IF_SCAN , + GET_DEV_NUM , + IS_BYPASS , + GET_BYPASS_SLAVE , + GET_BYPASS_CAPS , + GET_WD_SET_CAPS , + SET_BYPASS , + GET_BYPASS , + GET_BYPASS_CHANGE , + SET_BYPASS_WD , + GET_BYPASS_WD , + GET_WD_EXPIRE_TIME , + RESET_BYPASS_WD_TIMER, + SET_DIS_BYPASS , + GET_DIS_BYPASS , + SET_BYPASS_PWOFF , + GET_BYPASS_PWOFF , + SET_BYPASS_PWUP , + GET_BYPASS_PWUP , + SET_STD_NIC , + GET_STD_NIC , + SET_TX, + GET_TX, + SET_TAP , + GET_TAP , + GET_TAP_CHANGE , + SET_DIS_TAP , + GET_DIS_TAP , + SET_TAP_PWUP , + GET_TAP_PWUP , + SET_WD_EXP_MODE, + GET_WD_EXP_MODE, + SET_WD_AUTORESET, + GET_WD_AUTORESET, + SET_TPL, + GET_TPL, + SET_DISC , + GET_DISC , + GET_DISC_CHANGE , + SET_DIS_DISC , + GET_DIS_DISC , + SET_DISC_PWUP , + GET_DISC_PWUP , + GET_BYPASS_INFO=100, + GET_BP_WAIT_AT_PWUP, + SET_BP_WAIT_AT_PWUP, + GET_BP_HW_RESET, + SET_BP_HW_RESET, + SET_BP_BLINK, + SET_DISC_PORT, + GET_DISC_PORT, + SET_DISC_PORT_PWUP, + GET_DISC_PORT_PWUP, + SET_BP_FORCE_LINK, + GET_BP_FORCE_LINK, + SET_BP_MANUF, + GET_WD_EXPIRE, +#ifdef BP_SELF_TEST + SET_BP_SELF_TEST=200, + GET_BP_SELF_TEST, +#endif + EXCLUSIVE_LOCK, + DROP_EXCLUSIVE, + + } CMND_TYPE_SD ; + +/* +* The major device number. We can't rely on dynamic +* registration any more, because ioctls need to know +* it. +*/ + + +#define MAGIC_NUM 'J' + +/* for passing single values */ +struct bpctl_cmd { + int status; + int data[8]; + int in_param[8]; + int out_param[8]; +}; + + +#define IOCTL_TX_MSG(cmd) _IOWR(MAGIC_NUM, cmd, struct bpctl_cmd) + +#define DEVICE_NODE "/dev/bprdctl0" +#define DEVICE_NAME "bprdctl" + + +#endif + + diff --git a/bprd_mod.c b/bprd_mod.c new file mode 100755 index 0000000..207ade5 --- /dev/null +++ b/bprd_mod.c @@ -0,0 +1,6656 @@ +/************************************************************************** + +Copyright (c) 2005-2015, Silicom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Silicom nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)) + #include +#endif +#if defined(CONFIG_SMP) && ! defined(__SMP__) + #define __SMP__ +#endif + + + +#include /* We're doing kernel work */ +#include /* Specifically, a module */ +#include +#include +#include +#include +#include +#include +#ifdef BP_SELF_TEST + #include +#endif + +#include /* for get_user and put_user */ +#include +#include +#include +#include +#include +#include +#include + + +#include "bprd_ioctl.h" +#include "bprd_mod.h" +#include "bypass.h" +#include "libbp_rd.h" +#include "bp_cmd.h" + + +#define SUCCESS 0 +#define BP_MOD_VER VER_STR_SET +#define BP_MOD_DESCR "Silicom Bypass-RD Control driver" + +static int Device_Open = 0; +static int major_num=0; +spinlock_t bypass_wr_lock; + +MODULE_AUTHOR("Anna Lukin, annal@silicom.co.il"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION(BP_MOD_DESCR); +MODULE_VERSION(BP_MOD_VER); + +enum ies_port_state { + /* NOTE! Order is important. See the table in ies_port_set_state. */ + + /* The port is in working order (symbol lock, alignment done) and + * ready to receive a frame. + */ + IES_PORT_STATE_UP = 0, + + /* Deprecated. Use ''IES_PORT_MODE_ADMIN_DOWN'' instead. */ + IES_PORT_STATE_ADMIN_DOWN, + + /* Deprecated. Use ''IES_PORT_MODE_ADMIN_PWRDOWN'' instead. */ + IES_PORT_STATE_ADMIN_PWRDOWN, + + /* Deprecated. Use ''IES_PORT_MODE_BIST'' instead. */ + IES_PORT_STATE_BIST, + + /* The SERDES transmits remote fault constantly and the receiver is + * disabled. + */ + IES_PORT_STATE_REMOTE_FAULT, + + /* Indicates the absence of any signal on any lane. */ + IES_PORT_STATE_DOWN, + + /* Some lanes have either signal or partial synchronization. */ + IES_PORT_STATE_PARTIALLY_UP, + + /* Indicates continuous reception of a local fault condition. A remote + * fault is automatically sent continuously. + */ + IES_PORT_STATE_LOCAL_FAULT, + + /* Indicates that DFE tuning is still in progress. */ + IES_PORT_STATE_DFE_TUNING +}; + +enum ies_port_mode { + /* NOTE! Order is important. See the table in ies_port_set_state. */ + + /* The port is in working order (symbol lock, alignment done) and + * ready to receive a frame. + */ + IES_PORT_MODE_UP = IES_PORT_STATE_UP, + + /* The port is administratively set down with the SERDES + * transmitting an idle pattern but the receiver disabled. + */ + IES_PORT_MODE_ADMIN_DOWN = IES_PORT_STATE_ADMIN_DOWN, + + /* The port is administratively set down with the SERDES + * shut down and no signal transmitted. + */ + IES_PORT_MODE_ADMIN_PWRDOWN = IES_PORT_STATE_ADMIN_PWRDOWN, + + /* The receiver is expecting a Built In Self Test sequence. The subMode + * argument to ies_port_set_state or ies_set_port_state_v2 is used to + * specify the test pattern. + */ + IES_PORT_MODE_BIST = IES_PORT_STATE_BIST, + + /* The SERDES transmits remote fault constantly and the receiver is + * disabled. + */ + IES_PORT_MODE_REMOTE_FAULT = IES_PORT_STATE_REMOTE_FAULT, + + /* Indicates continuous reception of a local fault condition. A remote + * fault is automatically sent continuously. + */ + IES_PORT_MODE_LOCAL_FAULT = IES_PORT_STATE_LOCAL_FAULT +}; + +#define IES10K_EPL_BASE (0x0E0000) + +/* MAC and Reconciliation Sublayer configuration */ +#define IES10K_MAC_CFG(index1, index0, word) \ + (0x000400 * (index1) + 0x000080 * (index0) + \ + (word) + 0x000010 + IES10K_EPL_BASE) +#define IES10K_MAC_CFG_WIDTH 7 +#define IES10K_MAC_CFG_ENTRIES_0 4 +#define IES10K_MAC_CFG_ENTRIES_1 9 + +#define IES10K_MAC_CFG_L_TXANTIBUBBLEWATERMARK 0 +#define IES10K_MAC_CFG_H_TXANTIBUBBLEWATERMARK 5 +#define IES10K_MAC_CFG_L_TXRATEFIFOWATERMARK 6 +#define IES10K_MAC_CFG_H_TXRATEFIFOWATERMARK 9 +#define IES10K_MAC_CFG_L_TXRATEFIFOFASTINC 10 +#define IES10K_MAC_CFG_H_TXRATEFIFOFASTINC 17 +#define IES10K_MAC_CFG_L_TXRATEFIFOSLOWINC 18 +#define IES10K_MAC_CFG_H_TXRATEFIFOSLOWINC 25 +#define IES10K_MAC_CFG_L_TXIDLEMINIFGBYTES 26 +#define IES10K_MAC_CFG_H_TXIDLEMINIFGBYTES 31 +#define IES10K_MAC_CFG_L_TXCLOCKCOMPENSATIONTIMEOUT 32 +#define IES10K_MAC_CFG_H_TXCLOCKCOMPENSATIONTIMEOUT 47 +#define IES10K_MAC_CFG_B_TXCLOCKCOMPENSATIONENABLE 48 +#define IES10K_MAC_CFG_L_TXFAULTMODE 49 +#define IES10K_MAC_CFG_H_TXFAULTMODE 51 +#define IES10K_MAC_CFG_L_TXPCACTTIMESCALE 52 +#define IES10K_MAC_CFG_H_TXPCACTTIMESCALE 55 +#define IES10K_MAC_CFG_L_TXPCACTTIMEOUT 56 +#define IES10K_MAC_CFG_H_TXPCACTTIMEOUT 63 +#define IES10K_MAC_CFG_L_TXDRAINMODE 64 +#define IES10K_MAC_CFG_H_TXDRAINMODE 65 +#define IES10K_MAC_CFG_L_TXMINCOLUMNS 66 +#define IES10K_MAC_CFG_H_TXMINCOLUMNS 71 +#define IES10K_MAC_CFG_B_TXLPIDLEREQUEST 108 +#define IES10K_MAC_CFG_B_TXLPIAUTOMATIC 109 +#define IES10K_MAC_CFG_L_TXLPITIMEOUT 110 +#define IES10K_MAC_CFG_H_TXLPITIMEOUT 117 +#define IES10K_MAC_CFG_L_TXLPITIMESCALE 118 +#define IES10K_MAC_CFG_H_TXLPITIMESCALE 119 +#define IES10K_MAC_CFG_L_TXLPIHOLDTIMEOUT 120 +#define IES10K_MAC_CFG_H_TXLPIHOLDTIMEOUT 127 +#define IES10K_MAC_CFG_L_TXLPIHOLDTIMESCALE 128 +#define IES10K_MAC_CFG_H_TXLPIHOLDTIMESCALE 129 +#define IES10K_MAC_CFG_L_TXFCSMODE 130 +#define IES10K_MAC_CFG_H_TXFCSMODE 132 +#define IES10K_MAC_CFG_B_TXIDLEENABLEDIC 134 +#define IES10K_MAC_CFG_L_RXMINFRAMELENGTH 136 +#define IES10K_MAC_CFG_H_RXMINFRAMELENGTH 143 +#define IES10K_MAC_CFG_L_RXMAXFRAMELENGTH 144 +#define IES10K_MAC_CFG_H_RXMAXFRAMELENGTH 159 +#define IES10K_MAC_CFG_B_IEEE1588ENABLE 168 +#define IES10K_MAC_CFG_B_PREAMBLEMODE 170 +#define IES10K_MAC_CFG_B_RXDRAIN 173 +#define IES10K_MAC_CFG_B_RXIGNOREIFGERRORS 180 + + +#define DBI410_IF_SERIES(pid) \ + ((pid==0x01B0)|| \ + (pid==0x01B1)|| \ + (pid==0x01B2)|| \ + (pid==0x01B3)|| \ + (pid==0x01B4)) + +#define DBI410T_IF_SERIES(pid) \ + (pid==0x01B0) + +#define DBI240_IF_SERIES(pid) \ + ((pid==0x01B8)|| \ + (pid==0x01B9)|| \ + (pid==0x01BC)|| \ + (pid==0x01BA)) + + +#define DBI100H_IF_SERIES(pid) \ + ((pid==0x01C0)|| \ + (pid==0x01C2)) + +#define DBI100L_IF_SERIES(pid) \ + (pid==0x01C1) + +#define DBI25_IF_SERIES(pid) \ + (pid==0x01C8) + +#define DBI410_IF_SERIES(pid) \ + ((pid==0x01B0)|| \ + (pid==0x01B1)|| \ + (pid==0x01B2)|| \ + (pid==0x01B3)|| \ + (pid==0x01B4)) + +#define BPCTL_WRITE_REG(a, reg, value) \ + (writel((value), (void *)(((a)->mem_map) + reg*4))) + +#define BPCTL_READ_REG(a, reg) ( \ + readl((void *)((a)->mem_map) + reg*4)) + +inline static u32 ies_bitfield_get32_multi32(const u32 *array, int hi_bit, int lo_bit) +{ + u32 result = 0; + int result_pos = 0; + int word = lo_bit / 32; + int rel_lo_bit = lo_bit % 32; + int rel_hi_bit = rel_lo_bit + (hi_bit - lo_bit); + u32 mask = (2 << (hi_bit - lo_bit)) - 1; + + do { + result |= (array[word++] >> rel_lo_bit) << result_pos; + result_pos += (32 - rel_lo_bit); + rel_hi_bit -= 32; + rel_lo_bit = 0; + } while (rel_hi_bit >= 0); + + return result & mask; +} + + +inline static void ies_bitfield_set32_multi32(u32 *array, int hi_bit, int lo_bit, + u32 value) +{ + int value_pos = 0; + int word = lo_bit / 32; + int rel_lo_bit = lo_bit % 32; + int rel_hi_bit = rel_lo_bit + (hi_bit - lo_bit); + + do { + u32 mask; + + mask = (rel_hi_bit < 31 ? (2 << rel_hi_bit) : 0) - 1; + mask >>= rel_lo_bit; + mask <<= rel_lo_bit; + array[word] = ((array[word] & ~mask) | + (((value >> value_pos) << rel_lo_bit) & mask)); + value_pos += (32 - rel_lo_bit); + rel_hi_bit -= 32; + rel_lo_bit = 0; + ++word; + } while (rel_hi_bit >= 0); +} + + +/* Get a named field of 2-32 bits within an array of 32-bit values. */ +#define IES_ARRAY_GET_FIELD(array, regname, fieldname) \ + ies_bitfield_get32_multi32(array, regname ## _H_ ## fieldname, \ + regname ## _L_ ## fieldname) + +/* Set a named field of 2-32 bits within an array of 32-bit values. */ +#define IES_ARRAY_SET_FIELD(array, regname, fieldname, fieldvalue) \ + ies_bitfield_set32_multi32(array, regname ## _H_ ## fieldname, \ + regname ## _L_ ## fieldname, fieldvalue) + +inline static int convert_adminmode_txlinkfault(int mode) +{ + int link_fault; + + /* Program the output pattern based on the TxFaultMode */ + switch (mode) { + case IES_PORT_MODE_ADMIN_DOWN: + link_fault = 1; + break; + + case IES_PORT_MODE_LOCAL_FAULT: + link_fault = 2; + break; + + case IES_PORT_MODE_REMOTE_FAULT: + link_fault = 3; + break; + + default: + link_fault = 0; + break; + } + + return link_fault; +} + + +#define lock_bpctl() \ +if (down_interruptible(&bpctl_sema)) { \ + return -ERESTARTSYS; \ +} \ + +#define unlock_bpctl() \ + up(&bpctl_sema); + +static int bp_shutdown = 0; +/* Media Types */ +typedef enum { + bp_copper = 0, + bp_fiber, + bp_cx4, + bp_none, +} bp_media_type; + +struct pfs_unit_rd { + struct proc_dir_entry *proc_entry; + char proc_name[32]; +} ; + +typedef struct _bpctl_dev_mng { + char *name; + char *desc; + struct pci_dev *pdev; /* PCI device */ + struct net_device *ndev; /* net device */ + unsigned long mem_map; + uint8_t bus; + uint8_t slot; + uint8_t func; + uint8_t bus_p; + uint8_t slot_p; + uint8_t func_p; + u_int32_t device; + u_int32_t vendor; + u_int32_t subvendor; + u_int32_t subdevice; + int ifindex; + spinlock_t bypass_wr_lock; + int port_num; + int sw_num; + struct mutex i2c_bus_lock; + int mutex_owner_module; + +/* #endif */ + +} bpctl_dev_mng_t; + +#ifdef BP_PROC_SUPPORT +struct pfs_unit_rd { + struct proc_dir_entry *proc_entry; + char proc_name[32]; +} ; + +struct bypass_pfs_rd { + char dir_name[32]; + struct proc_dir_entry *bypass_entry; + struct pfs_unit_rd bypass_info; + struct pfs_unit_rd bypass_slave; + struct pfs_unit_rd bypass_caps; + struct pfs_unit_rd wd_set_caps; + struct pfs_unit_rd bypass; + struct pfs_unit_rd bypass_change; + struct pfs_unit_rd bypass_wd; + struct pfs_unit_rd wd_expire_time; + struct pfs_unit_rd reset_bypass_wd; + struct pfs_unit_rd dis_bypass; + struct pfs_unit_rd bypass_pwup; + struct pfs_unit_rd bypass_pwoff; + struct pfs_unit_rd std_nic; + struct pfs_unit_rd tap; + struct pfs_unit_rd dis_tap; + struct pfs_unit_rd tap_pwup; + struct pfs_unit_rd tap_change; + struct pfs_unit_rd wd_exp_mode; + struct pfs_unit_rd wd_autoreset; + struct pfs_unit_rd tpl; + +}; +#endif + + +typedef struct _bpctl_dev { + char *name; + char *desc; + struct pci_dev *pdev; /* PCI device */ + struct net_device *ndev; /* net device */ + bpctl_dev_mng_t *pbpctl_dev_c; + struct pci_dev *pdev_mng; + struct pci_dev *pdev_pf_master; + struct pci_dev *pdev_pf_slave; + unsigned long mem_map; + uint8_t bus; + uint8_t slot; + uint8_t func; + uint8_t bus_p; + uint8_t slot_p; + uint8_t func_p; + u_int32_t device; + u_int32_t vendor; + u_int32_t subvendor; + u_int32_t subdevice; + int ifindex; + uint32_t bp_caps; + uint32_t bp_caps_ex; + uint8_t bp_fw_ver; + int bp_ext_ver; + int wdt_status; + unsigned long bypass_wdt_on_time; + uint32_t bypass_timer_interval; + struct timer_list bp_timer; + uint32_t reset_time; + uint8_t bp_status_un; + atomic_t wdt_busy; + bp_media_type media_type; + int bp_master_flag; + int bp_tpl_flag; + struct timer_list bp_tpl_timer; + int tpl_wait; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) + const struct net_device_ops *old_ops; + struct net_device_ops new_ops; +#endif + int bp_self_test_flag; + char *bp_tx_data; + uint8_t rb_oem; + uint8_t oem_data[20]; + uint32_t ledctl_default; + uint32_t ledctl_mode1; + uint32_t ledctl_mode2; + uint32_t led_status; +//#endif + struct timer_list blink_timer; + struct timer_list wait_timer; +#ifdef BP_PROC_SUPPORT + struct bypass_pfs_rd bypass_pfs_set; + char proc_dir[128]; +#endif + int port_num; + int epl_num; + int epl; + int lane_num; + int sw_num; +/* #endif */ + +} bpctl_dev_t; + +inline static int iespl_read_mult_u32(bpctl_dev_mng_t *interface, u32 addr, int n, u32 *val) +{ + u32 value; + int i; + + for (i = 0; i < n; i++) { + value = BPCTL_READ_REG(interface, (addr + i)); + val[i] = value; + } + + return 0; +} + +inline static int iespl_write_mult_u32(bpctl_dev_mng_t *interface, u32 addr, int n, u32 *val) +{ + int i; + + for (i = 0; i < n; i++) { + BPCTL_WRITE_REG(interface, (addr + i), val[i]); + } + + return 0; +} + +static bpctl_dev_t *bpctl_dev_arr; +static bpctl_dev_mng_t *bpctl_dev_mng_arr; + +static int device_num=0; +static int mng_device_num=0; + +static struct semaphore bpctl_sema; + + + +static int usec_delay_bp1(unsigned long x); +static void usec_delay_bp(unsigned long x); +static void msec_delay_bp(unsigned long x); + +static int get_dev_idx_bsf(int bus, int slot, int func); + +static int get_dev_mng_idx_bsf(int bus, int slot, int func); + +static int get_dev_idx(int ifindex); +static void if_scan_init(void); + +static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev); +static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev); + + +#ifdef BP_PROC_SUPPORT +int bypass_proc_create_dev_rd(bpctl_dev_t * pbp_device_block); +int bypass_proc_remove_dev_rd(bpctl_dev_t * pbp_device_block); + +int bp_proc_create(void); +#endif + +int get_tx_rd_fn(bpctl_dev_t *pbpctl_dev); +int set_tx_rd_fn(bpctl_dev_t *pbpctl_dev, int tx_state); + +int is_bypass_rd_fn(bpctl_dev_t *pbpctl_dev); +int get_bypass_caps_rd_fn(bpctl_dev_t *pbpctl_dev); +int get_wd_expire_rd_fn (bpctl_dev_t *pbpctl_dev); + +int wdt_on(bpctl_dev_t *pbpctl_dev, unsigned int timeout); + +static int TAKE_PLAT_I2C_BUS_LOCK_IDX(struct file * file, int dev_idx){ + int rc; + rc = mutex_lock_interruptible(&bpctl_dev_mng_arr[dev_idx].i2c_bus_lock); + bpctl_dev_mng_arr[dev_idx].mutex_owner_module = 0; + file->private_data = &bpctl_dev_mng_arr[dev_idx].i2c_bus_lock; + return(rc) ? -ERESTARTSYS: 0; +} + +static void DROP_PLAT_I2C_BUS_LOCK_IDX(struct file * file, int dev_idx){ + mutex_unlock(&bpctl_dev_mng_arr[dev_idx].i2c_bus_lock); + file->private_data = NULL; +} + +static void TAKE_PLAT_I2C_BUS_LOCK(bpctl_dev_mng_t *pbpctl_dev_c) { + int rc= mutex_lock_interruptible( &pbpctl_dev_c->i2c_bus_lock); + pbpctl_dev_c->mutex_owner_module = (rc) ? 1 :0; +} + +static void DROP_PLAT_I2C_BUS_LOCK(bpctl_dev_mng_t *pbpctl_dev_c){ + pbpctl_dev_c->mutex_owner_module = 0; + mutex_unlock( &pbpctl_dev_c->i2c_bus_lock); +} + + +int usec_delay_bp1(unsigned long x) { + struct timeval tv, tv_end; + do_gettimeofday(&tv); + udelay(x); + do_gettimeofday(&tv_end); + if (tv_end.tv_usec>tv.tv_usec) { + if ((tv_end.tv_usec-tv.tv_usec)<(x)) + return 0; + } + else if ((~tv.tv_usec+tv_end.tv_usec)<(x)) + return 0; + return 1; + +} +void usec_delay_bp(unsigned long x) { +#if 1 + int i=2; + while (i--) { + if (usec_delay_bp1(x)) + return; + } +#else + udelay(x); +#endif +} + + +void msec_delay_bp(unsigned long x){ +#ifdef BP_NDELAY_MODE + return; +#else + int i; + if (in_interrupt()) { + for (i = 0; i < 1000; i++) { + usec_delay_bp(x) ; + } + } + else { + msleep(x); + } +#endif +} + +#define FM_SET_FIELD(lvalue, regname, fieldname, fieldvalue) \ + (lvalue ^= ( ( (lvalue >> regname ## _l_ ## fieldname) ^ fieldvalue ) & \ + ( ( 2 << (regname ## _h_ ## fieldname - regname ## _l_ ## fieldname) ) - 1 ) ) \ + << regname ## _l_ ## fieldname) + +#define FM_GET_FIELD(rvalue, regname, fieldname) \ + ( (rvalue >> regname ## _l_ ## fieldname) & \ + ( ( 2 << (regname ## _h_ ## fieldname - regname ## _l_ ## fieldname) ) - 1 ) ) + +#define FM_GET_BIT(rvalue, regname, bitname) \ + ( (rvalue >> regname ## _b_ ## bitname) & 1 ) + +#define FM_SET_BIT(lvalue, regname, bitname, bitvalue) \ + ( lvalue = ( lvalue & ~(1 << regname ## _b_ ## bitname) ) | \ + ( (bitvalue & 1) << regname ## _b_ ## bitname ) ) + + +#define FM10000_I2C_DATA(index) ((0x000001) * ((index) - 0) + (0x000C1C)) +#define FM10000_I2C_CTRL 0x000C20 +#define FM10000_GPIO_CFG 0x000C15 +#define FM10000_GPIO_DATA 0x000C16 + +#define FM10000_I2C_CTRL_l_Addr 0 +#define FM10000_I2C_CTRL_h_Addr 7 +#define FM10000_I2C_CTRL_l_Command 8 +#define FM10000_I2C_CTRL_h_Command 9 +#define FM10000_I2C_CTRL_l_LengthW 10 +#define FM10000_I2C_CTRL_h_LengthW 13 +#define FM10000_I2C_CTRL_l_LengthR 14 +#define FM10000_I2C_CTRL_h_LengthR 17 +#define FM10000_I2C_CTRL_l_LengthSent 18 +#define FM10000_I2C_CTRL_h_LengthSent 21 +#define FM10000_I2C_CTRL_l_CommandCompleted 22 +#define FM10000_I2C_CTRL_h_CommandCompleted 25 +#define FM10000_I2C_CTRL_b_InterruptPending 26 + + + + +static int I2cWriteRead(bpctl_dev_mng_t *pbpctl_dev_c, + unsigned int device, + unsigned char *data, + unsigned int wl, + unsigned int rl) +{ + uint32_t regValue; + unsigned int i; + unsigned int j; + + uint i2c_try = 40; + uint32_t tmp; + + + /*printk("I2cWriteRead device=0x%x wl=%d rl=%d\n", + device, wl, rl);*/ + + if (rl > 12) + { + return -1; + } + + if (wl > 12) + { + return -1; + } + + if (data == NULL) + { + return -1; + } + if (!pbpctl_dev_c) + return -1; + + for (i = 0 ; i < (wl+3)/4 ; i++) + { + regValue = 0; + for (j = 0 ; j < 4 ; j++) + { + if ((i*4 + j) < wl) + { + regValue |= (data[i*4 + j] << ((3 - j)*8)); + } + } + BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_I2C_DATA(i), regValue); + + /*printk("WRITEDATA#%d : 0x%08x\n",i, regValue); */ + } + + regValue = 0; + FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Addr, (device << 1)); + FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 0); + FM_SET_FIELD(regValue, FM10000_I2C_CTRL, LengthW, wl); + FM_SET_FIELD(regValue, FM10000_I2C_CTRL, LengthR, rl); + +/* printk("WRITE: eg 0x%08x Cmd %d wl %d rl %d " + "Comp %x LenSent %d intr %d\n", + regValue, + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, Command), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthW), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthR), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthSent), + FM_GET_BIT(regValue, FM10000_I2C_CTRL, InterruptPending));*/ + + BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_I2C_CTRL, regValue); + + tmp = BPCTL_READ_REG(pbpctl_dev_c, FM10000_I2C_CTRL); + + /*printk("READ: reg 0x%08x Cmd %d wl %d rl %d " + "Comp %x LenSent %d intr %d\n", tmp, + FM_GET_FIELD(tmp, FM10000_I2C_CTRL, Command), + FM_GET_FIELD(tmp, FM10000_I2C_CTRL, LengthW), + FM_GET_FIELD(tmp, FM10000_I2C_CTRL, LengthR), + FM_GET_FIELD(tmp, FM10000_I2C_CTRL, CommandCompleted), + FM_GET_FIELD(tmp, FM10000_I2C_CTRL, LengthSent), + FM_GET_BIT(tmp, FM10000_I2C_CTRL, InterruptPending));*/ + + /* Now change command to start the transaction */ + if (rl == 0) + { + /* Write only allow write of 0 length */ + FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 1); + } + else if ((wl > 0) && (rl > 0)) + { + /* Write Read */ + FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 2); + } + else + { + /* Read */ + FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 3); + } + + /*printk("WRITE2: reg 0x%08x Cmd %d wl %d rl %d " + "Comp %x LenSent %d intr %d\n", regValue, + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, Command), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthW), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthR), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthSent), + FM_GET_BIT(regValue, FM10000_I2C_CTRL, InterruptPending));*/ + + BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_I2C_CTRL, regValue); + + regValue = BPCTL_READ_REG(pbpctl_dev_c, FM10000_I2C_CTRL); + + /*printk("READ2: reg 0x%08x Cmd %d wl %d rl %d " + "Comp %x LenSent %d intr %d\n", regValue, + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, Command), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthW), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthR), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted), + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthSent), + FM_GET_BIT(regValue, FM10000_I2C_CTRL, InterruptPending));*/ + + /* Poll to check for command done */ + do + { + msec_delay_bp(1); + + regValue = BPCTL_READ_REG(pbpctl_dev_c, FM10000_I2C_CTRL); + + } while ((FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted) == 0)&&(i2c_try--)); + + if (FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted) != 1) + { + /*printk("Dev=0x%02x: I2C Command completed with error 0x%x. " + "I2C_CTRL(0x%x)=0x%x\n", + device, + FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted), + FM10000_I2C_CTRL, + regValue);*/ + return -1; + } + + for (i = 0 ; i < (rl+3)/4 ; i++) + { + regValue = BPCTL_READ_REG(pbpctl_dev_c, FM10000_I2C_DATA(i)); + + + for (j = 0 ; j < 4 ; j++) + { + if ((i*4 + j) < rl) + { + data[i*4 + j] = (regValue >> ((3 - j)*8)) & 0xFF; + } + } + } + return 0; +} /* end I2cWriteRead */ + + +static int WriteBypass(bpctl_dev_mng_t *pbpctl_dev_c, + unsigned int device, + unsigned char *data, + unsigned int wl, + unsigned int rl) +{ + int status; + + if (!pbpctl_dev_c) + return -1; +#if 0 + { + int num, i; + num = rl?rl:wl; + printk("data "); + for (i = 0; i < num; i++){ + printk("%x ", data[i]); + } + printk("\n"); + } +#endif + + status = I2cWriteRead(pbpctl_dev_c, device, data, wl, rl); + + + return status; + +} /* end WriteSfppPhy */ + +int fmPlatformFm10000BypassWriteRead(bpctl_dev_mng_t *pbpctl_dev_c, + unsigned int device, + unsigned char *data, + unsigned int wl, + unsigned int rl) + +{ + int status = 0; + unsigned char mux_pin = 2; + + if (!pbpctl_dev_c) + return -1; + + + TAKE_PLAT_I2C_BUS_LOCK(pbpctl_dev_c); + + if (!DBI410T_IF_SERIES(pbpctl_dev_c->subdevice)) { + if (DBI410_IF_SERIES(pbpctl_dev_c->subdevice)) + status = I2cWriteRead(pbpctl_dev_c, 0x75, &mux_pin, 1, 0); + else + status = I2cWriteRead(pbpctl_dev_c, 0x70, &mux_pin, 1, 0); + } + if (status == 0) + status = WriteBypass(pbpctl_dev_c, device, data, wl, rl); + + DROP_PLAT_I2C_BUS_LOCK(pbpctl_dev_c); + return status; + +} /* end fmPlatformPhyEnable1000BaseTAutoNeg */ + + +/*static bpctl_dev_t *bpctl_dev_a; +static bpctl_dev_t *bpctl_dev_b;*/ + + + +static int bp_get_dev_idx_bsf(struct net_device *dev, int *index) +{ + struct ethtool_drvinfo drvinfo = {0}; + char *buf; + int bus, slot, func; + + if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) + dev->ethtool_ops->get_drvinfo(dev, &drvinfo); + else + return -EOPNOTSUPP; + + if (!drvinfo.bus_info) + return -ENODATA; + if (!strcmp(drvinfo.bus_info, "N/A")) + return -ENODATA; + + buf = strchr(drvinfo.bus_info, ':'); + if (!buf) + return -EINVAL; + buf++; + if (sscanf(buf, "%x:%x.%x", &bus, &slot, &func) != 3) + return -EINVAL; + + *index = get_dev_idx_bsf(bus, slot, func); + return 0; +} + + +static int bp_get_dev_mng_idx_bsf(struct net_device *dev, int *index) +{ + struct ethtool_drvinfo drvinfo = {0}; + char *buf; + int bus, slot, func; + + if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) + dev->ethtool_ops->get_drvinfo(dev, &drvinfo); + else + return -EOPNOTSUPP; + + if (!drvinfo.bus_info) + return -ENODATA; + if (!strcmp(drvinfo.bus_info, "N/A")) + return -ENODATA; + + buf = strchr(drvinfo.bus_info, ':'); + if (!buf) + return -EINVAL; + buf++; + if (sscanf(buf, "%x:%x.%x", &bus, &slot, &func) != 3) + return -EINVAL; + + *index = get_dev_mng_idx_bsf(bus, slot, func); + return 0; +} + + +static bpctl_dev_mng_t *get_mng_port_rd_fn(bpctl_dev_t *pbpctl_dev) { + int idx_dev=0; + + if (pbpctl_dev==NULL) + return NULL; + + for (idx_dev = 0; ((bpctl_dev_mng_arr[idx_dev].pdev != NULL)&&(idx_dev < mng_device_num)); idx_dev++) { + if (DBI410_IF_SERIES(pbpctl_dev->subdevice)) { + if ((bpctl_dev_mng_arr[idx_dev].bus == pbpctl_dev->bus) && + (bpctl_dev_mng_arr[idx_dev].slot == pbpctl_dev->slot) && + (bpctl_dev_mng_arr[idx_dev].func == 0)) { + + return(&(bpctl_dev_mng_arr[idx_dev])); + } + } + else { + if (bpctl_dev_mng_arr[idx_dev].pdev == pbpctl_dev->pdev_mng) + return(&(bpctl_dev_mng_arr[idx_dev])); + + } + } + + return NULL; +} + +/* + * This routine tries to find the Master/Slave NICs base on the following + * hardware configuration. + * + * GrandParent--+--Uncle1 + * +--Parent/Uncle--+--Me?(Slave) + * | + * +--Parent/Uncle--+-Me?(Master) + * +--Uncle3 + * Input: + * me - pci_dev pointer to the Broadcom device + * Output: + * pdev_master - pci_dev pointer to Master(NIC Controler1) + * pdev_slave - pci_dev pointer to Slave(NIC Controler2) + */ +static void +rdi_find_master_slave_plx(struct pci_dev *me, + struct pci_dev **pdev_master, + struct pci_dev **pdev_slave) +{ + struct pci_bus *grand_parent, *uncle, *parent; + struct list_head *tmp, *tmp2; + struct pci_dev *pdev; + + *pdev_master = NULL; + *pdev_slave = NULL; + + if ((parent = me->bus) == NULL) { + pr_err("rdi cannot find its parent\n"); + return; + } + + + if ((grand_parent = parent->parent) == NULL) { + + return; + } + + + list_for_each(tmp, &grand_parent->children) { + uncle = list_entry(tmp, struct pci_bus, node); + if (uncle == parent) + continue; + if (uncle) { + list_for_each(tmp2, &uncle->devices) { + pdev = list_entry(tmp2, struct pci_dev, bus_list); + if (pdev == NULL || pdev->bus == NULL) { + pr_err("%s:%d: t not found\n", __FUNCTION__, __LINE__); + continue; + } + + if (pdev->bus->number > me->bus->number) { + *pdev_master = pdev; + *pdev_slave = me; + } + else { + *pdev_master = me; + *pdev_slave = pdev; + } + return; + } + + } + } +} + + + +#if 1 +static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev) { + int idx_dev=0; + + + if ( pbpctl_dev == NULL ) { + return NULL; + } + + + if ((pbpctl_dev->epl_num == 2) || + (pbpctl_dev->epl_num == 4)) { + return pbpctl_dev; + } + for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev != NULL)&&(idx_dev < device_num)); idx_dev++) { + if (DBI410_IF_SERIES(pbpctl_dev->subdevice)) { + if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)&& + (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)&& + ((bpctl_dev_arr[idx_dev].epl_num == 2)&&(pbpctl_dev->epl_num == 1))) { + + return(&(bpctl_dev_arr[idx_dev])); + } + + if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)&& + (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)&& + ((bpctl_dev_arr[idx_dev].epl_num == 4)&&(pbpctl_dev->epl_num == 3))) { + + return(&(bpctl_dev_arr[idx_dev])); + } + } + else { + if ((bpctl_dev_arr[idx_dev].pdev == pbpctl_dev->pdev_pf_slave)&& + ((bpctl_dev_arr[idx_dev].epl_num == 2)&&(pbpctl_dev->epl_num == 1))) { + + return(&(bpctl_dev_arr[idx_dev])); + } + } + } + return NULL; +} + + + +static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev) { + int idx_dev=0; + + + if (pbpctl_dev==NULL) { + return NULL; + } + + + if ((pbpctl_dev->epl_num == 1) || + (pbpctl_dev->epl_num == 3)) { + return pbpctl_dev; + } + for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev != NULL)&&(idx_dev < device_num)); idx_dev++) { + if (DBI410_IF_SERIES(pbpctl_dev->subdevice)) { + if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)&& + (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)&& + ((bpctl_dev_arr[idx_dev].epl_num == 1)&&(pbpctl_dev->epl_num == 2))) { + + return(&(bpctl_dev_arr[idx_dev])); + } + + if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)&& + (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)&& + ((bpctl_dev_arr[idx_dev].epl_num == 3)&&(pbpctl_dev->epl_num == 4))) { + + return(&(bpctl_dev_arr[idx_dev])); + } + } + else { + if ((bpctl_dev_arr[idx_dev].pdev == pbpctl_dev->pdev_pf_master)&& + ((bpctl_dev_arr[idx_dev].epl_num == 1)&&(pbpctl_dev->epl_num == 2))) { + + return(&(bpctl_dev_arr[idx_dev])); + } + } + } + return NULL; +} + +#endif + + + + +static int +bp_reboot_event(struct notifier_block *nb, + unsigned long event, + void *ptr) +{ + bp_shutdown = 1; + return NOTIFY_DONE; +} +static int bp_device_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0)) + struct net_device *dev = ptr; +#else + struct net_device *dev = netdev_notifier_info_to_dev(ptr); +#endif + static bpctl_dev_t *pbpctl_dev, *pbpctl_dev_m, *pbpctl_dev2; + int dev_num = 0; +#if 0 + static bpctl_dev_t *pbpctl_dev_m; + int ret = 0; +#endif + /*printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); + return NOTIFY_DONE;*/ + if (!dev) + return NOTIFY_DONE; + + if (event == NETDEV_REGISTER) { + int idx_dev; + + if (bp_get_dev_idx_bsf(dev, &idx_dev)) + return NOTIFY_DONE; + + if (idx_dev == -1) + return NOTIFY_DONE; + + bpctl_dev_arr[idx_dev].ifindex = dev->ifindex; + bpctl_dev_arr[idx_dev].ndev = dev; + + + if ((!bp_get_dev_mng_idx_bsf(dev, &idx_dev)) && + (idx_dev != -1)) { + bpctl_dev_mng_arr[idx_dev].ifindex = dev->ifindex; + bpctl_dev_mng_arr[idx_dev].ndev = dev; + } + +#ifdef BP_PROC_SUPPORT + bypass_proc_remove_dev_rd(&bpctl_dev_arr[idx_dev]); + bypass_proc_create_dev_rd(&bpctl_dev_arr[idx_dev]); +#endif + return NOTIFY_DONE; + } + if (event == NETDEV_UNREGISTER) { + int idx_dev = 0; + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) + && (idx_dev < device_num)); idx_dev++) { + if (bpctl_dev_arr[idx_dev].ndev == dev) { +#ifdef BP_PROC_SUPPORT + bypass_proc_remove_dev_rd(&bpctl_dev_arr + [idx_dev]); +#endif + bpctl_dev_arr[idx_dev].ndev = NULL; + + return NOTIFY_DONE; + + } + + } + return NOTIFY_DONE; + } + if (event == NETDEV_CHANGENAME) { + int idx_dev = 0; + for (idx_dev = 0; + ((bpctl_dev_arr[idx_dev].pdev != NULL) + && (idx_dev < device_num)); idx_dev++) { + if (bpctl_dev_arr[idx_dev].ndev == dev) { +#ifdef BP_PROC_SUPPORT + bypass_proc_remove_dev_rd(&bpctl_dev_arr + [idx_dev]); + bypass_proc_create_dev_rd(&bpctl_dev_arr + [idx_dev]); +#endif + + return NOTIFY_DONE; + + } + + } + return NOTIFY_DONE; + + } + + switch (event) { + + case NETDEV_CHANGE:{ + + if (((dev_num = get_dev_idx(dev->ifindex)) == -1) || + (!(pbpctl_dev = &bpctl_dev_arr[dev_num]))) + return NOTIFY_DONE; + + if (bp_shutdown == 1) + return NOTIFY_DONE; + if ((is_bypass_rd_fn(pbpctl_dev)) == 1){ + pbpctl_dev_m = pbpctl_dev; + pbpctl_dev2 = get_status_port_fn(pbpctl_dev); + } + else { + pbpctl_dev2 = pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + } + + + if ((!pbpctl_dev_m)||(!pbpctl_dev2)) + return NOTIFY_DONE; + + + if (netif_carrier_ok(dev)) { + if (pbpctl_dev_m->bp_tpl_flag){ + if (get_tx_rd_fn(pbpctl_dev)) { + pbpctl_dev->tpl_wait = 0; + if (!get_tx_rd_fn(pbpctl_dev2)) { + pbpctl_dev2->tpl_wait = 1; + set_tx_rd_fn(pbpctl_dev2, 1); + } + } + } + return NOTIFY_DONE; + } + if (pbpctl_dev_m->bp_tpl_flag){ + if (get_tx_rd_fn(pbpctl_dev)) { + if (get_tx_rd_fn(pbpctl_dev2)) { + set_tx_rd_fn(pbpctl_dev2, 0); + } + + } + } + + return NOTIFY_DONE; + + } + + default: + return NOTIFY_DONE; + + } + return NOTIFY_DONE; + +} + +static struct notifier_block bp_notifier_block = { + .notifier_call = bp_device_event, +}; +static struct notifier_block bp_reboot_block = { + .notifier_call = bp_reboot_event, +}; + + + +static int device_open(struct inode *inode, struct file *file) +{ + + file->private_data = NULL; + +#ifdef DEBUG + printk("device_open(%p)\n", file); +#endif + Device_Open++; +/* +* Initialize the message +*/ + return SUCCESS; +} +static int device_release(struct inode *inode, struct file *file) +{ + int i; + +#ifdef DEBUG + printk("device_release(%p,%p)\n", inode, file); +#endif + Device_Open--; + + if ( file->private_data != NULL ) + { + mutex_unlock((struct mutex *) file->private_data); + for (i=0; i< mng_device_num; i++) { + if (! bpctl_dev_mng_arr[i].mutex_owner_module) { + /*if (bpctl_dev_mng_arr[i].i2c_bus_lock.owner == current )*/ + mutex_unlock(&bpctl_dev_mng_arr[i].i2c_bus_lock); + } + } + } + + return SUCCESS; +} + + +static int get_dev_idx(int ifindex){ + int idx_dev=0; + + for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev!=NULL)&&(idx_dev= 0x020618) + for_each_netdev(&init_net, dev) +#elif (LINUX_VERSION_CODE >= 0x20616) + for_each_netdev(dev) +#else + for (dev = dev_base; dev; dev = dev->next) +#endif + + { + int idx_dev; + + if (bp_get_dev_idx_bsf(dev, &idx_dev)) + continue; + + if (idx_dev == -1) + continue; + + bpctl_dev_arr[idx_dev].ifindex = dev->ifindex; + bpctl_dev_arr[idx_dev].ndev = dev; + } + +} + + + + +static void if_scan_mng_init(void) +{ + struct net_device *dev; + +#if (LINUX_VERSION_CODE >= 0x020618) + for_each_netdev(&init_net, dev) +#elif (LINUX_VERSION_CODE >= 0x20616) + for_each_netdev(dev) +#else + for (dev = dev_base; dev; dev = dev->next) +#endif + + { + int idx_dev; + + if (bp_get_dev_mng_idx_bsf(dev, &idx_dev)) + continue; + + if (idx_dev == -1) + continue; + + bpctl_dev_mng_arr[idx_dev].ifindex = dev->ifindex; + bpctl_dev_mng_arr[idx_dev].ndev = dev; + } + +} + + + + +#define FM10K_UC_ADDR_START 0x000000 /* start of standard regs */ +#define FM10K_WC_ADDR_START 0x100000 /* start of Tx Desc Cache */ +#define FM10K_DBI_ADDR_START 0x200000 /* start of debug registers */ +#define FM10K_UC_ADDR_SIZE (FM10K_WC_ADDR_START - FM10K_UC_ADDR_START) +#define FM10K_WC_ADDR_SIZE (FM10K_DBI_ADDR_START - FM10K_WC_ADDR_START) + +static int bp_cmd_request(bpctl_dev_mng_t *pbpctl_dev_c, bp_cmd_t *bp_cmd_buf, bp_cmd_rsp_t *bp_rsp_buf); + +static int bp_cmd_request(bpctl_dev_mng_t *pbpctl_dev_c, bp_cmd_t *bp_cmd_buf, bp_cmd_rsp_t *bp_rsp_buf) { + int ret_val; + int try_num = 10; + + /* atomic_set(&pbpctl_dev->wdt_busy,1); */ + /* + * Send command + */ + + if (!pbpctl_dev_c) + return -1; + + while (try_num--) { + memset(bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + + usec_delay_bp(CMND_INTERVAL); + + if ((ret_val = fmPlatformFm10000BypassWriteRead(pbpctl_dev_c, + 0x57, + (unsigned char *)bp_cmd_buf, + sizeof(bp_cmd_t), + 0))) { + printk("bp_cmd_request(write): Not supported!\n"); + continue; + // return 0; + } + + usec_delay_bp(CMND_INTERVAL); +#if 1 + /* + * Receive replay + */ + + if ((ret_val = fmPlatformFm10000BypassWriteRead(pbpctl_dev_c, 0x57, + (unsigned char *)bp_rsp_buf, 0, + sizeof(bp_cmd_rsp_t))) < 0) { + printk("bp_cmd_request(read): Not supported!\n"); + continue; + //return 0; + } +#endif + + // if (bp_rsp_buf->rsp.rsp_id != BP_ERR_OK) + // continue; + if (bp_rsp_buf->rsp.rsp_id != BP_ERR_OK) + continue; + +#if 1 + if (bp_rsp_buf->rsp.rsp_id != BP_ERR_OK) + printk("bp_cmd_request(got err code or corrupted data!) (%x %x %x %x %x %x)\n", + bp_rsp_buf->cmd_bytes[0],bp_rsp_buf->cmd_bytes[1],bp_rsp_buf->cmd_bytes[2], + bp_rsp_buf->cmd_bytes[3],bp_rsp_buf->cmd_bytes[4],bp_rsp_buf->cmd_bytes[5]); + +#endif + + break; + } + /*atomic_set(&pbpctl_dev->wdt_busy,0);*/ + + if (!try_num) { + return 0; + } + return 1; +} + + +int is_bypass_port_rd_fn(int port){ + + return(((port == 1)||(port == 3)) ? 1:0); +} + + +int is_bypass_rd_fn(bpctl_dev_t *pbpctl_dev){ + + if (!pbpctl_dev) { + return -1; + } + return(pbpctl_dev->bp_master_flag); + +} + + +int set_bypass_rd_fn (bpctl_dev_t *pbpctl_dev, int bypass_mode){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) { + return ret; + } + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) { + return ret; + } + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) { + return ret; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num= (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_SET_BYPASS; + bp_cmd_buf.cmd.cmd_data.bypass_mode=bypass_mode?1:0; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(LATCH_DELAY); + return ret; +} + + + +int get_wd_expire_rd_fn (bpctl_dev_t *pbpctl_dev){ + + int ret = -1, gpio = 0, port = 0; + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + uint32_t cfg; + + if (!pbpctl_dev) { + return -1; + } + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) { + return ret; + } + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) { + return ret; + } + + gpio = (port == 1)?9:10; + + cfg = BPCTL_READ_REG(pbpctl_dev_c, FM10000_GPIO_CFG); + cfg &= ~(1 << gpio); + BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_CFG, cfg); + cfg = 0; + cfg = BPCTL_READ_REG(pbpctl_dev_c, FM10000_GPIO_DATA); + ret = cfg & (1 << gpio); + + return(ret==0?1:0); +} + +int get_bypass_rd_fn (bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret=-1, port = 0; + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) { + return ret; + } + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) { + return ret; + } + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) { + return ret; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + if (bp_rsp_buf.rsp.rsp_data.bypass_pwoff == BYPASS_PWOFF_EN) { + ret = 1; + } + else if (bp_rsp_buf.rsp.rsp_data.bypass_pwoff == BYPASS_PWOFF_DIS) { + ret = 0; + } + } + } + return ret; +} + + +int get_bypass_change_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1; + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + int port = 0; + + if (!pbpctl_dev) { + return ret; + } + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) { + return ret; + } + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) { + return ret; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;; + + bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_CHANGE; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_data.bypass_change == BYPASS_CHANGED) { + ret = 1; + } + else if (bp_rsp_buf.rsp.rsp_data.bypass_change == BYPASS_NOT_CHANGED) { + ret = 0; + } + } + return ret; +} + + +int set_dis_bypass_rd_fn(bpctl_dev_t *pbpctl_dev, int dis_bypass){ + + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret=-1; + int port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) { + return ret; + } + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) { + return ret; + } + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) { + return ret; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_DIS_BYPASS; + bp_cmd_buf.cmd.cmd_data.dis_bypass = + dis_bypass?DIS_BYPASS_DISABLE:DIS_BYPASS_ENABLE; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(BYPASS_CAP_DELAY); + return ret; +} + + +int get_dis_bypass_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret=-1; + int port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) { + return ret; + } + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) { + return ret; + } + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) { + return ret; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_DIS_BYPASS; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_data.dis_bypass==DIS_BYPASS_DISABLE) { + ret=1; + } + else if (bp_rsp_buf.rsp.rsp_data.dis_bypass==DIS_BYPASS_ENABLE) { + ret=0; + } + } + return ret; +} + + +int set_bypass_pwoff_rd_fn (bpctl_dev_t *pbpctl_dev, int bypass_mode){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port =0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) { + return ret; + } + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) { + return ret; + } + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) { + return ret; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_BYPASS_PWOFF; + bp_cmd_buf.cmd.cmd_data.bypass_pwoff = + bypass_mode?BYPASS_PWOFF_EN:BYPASS_PWOFF_DIS; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(EEPROM_WR_DELAY); + return ret; +} + + +int get_bypass_pwoff_rd_fn(bpctl_dev_t *pbpctl_dev){ + + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) { + return ret; + } + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) { + return ret; + } + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) { + return ret; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_PWOFF; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + if (bp_rsp_buf.rsp.rsp_data.bypass_pwoff == BYPASS_PWOFF_EN) { + ret = 1; + } + else if (bp_rsp_buf.rsp.rsp_data.bypass_pwoff == BYPASS_PWOFF_DIS) { + ret = 0; + } + } + } + + return ret; +} + + +int set_bypass_pwup_rd_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode){ + + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) { + return ret; + } + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) { + return ret; + } + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) { + return ret; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_BYPASS_PWUP; + bp_cmd_buf.cmd.cmd_data.bypass_pwup = + bypass_mode?BYPASS_PWUP_EN:BYPASS_PWUP_DIS; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(EEPROM_WR_DELAY); + return ret; +} + + +int get_bypass_pwup_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) { + return ret; + } + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) { + return ret; + } + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) { + return ret; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_PWUP; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + if (bp_rsp_buf.rsp.rsp_data.bypass_pwup == BYPASS_PWUP_EN) + ret=1; + else if (bp_rsp_buf.rsp.rsp_data.bypass_pwup == BYPASS_PWUP_DIS) + ret=0; + } + } + return ret; +} + + +int set_bypass_wd_rd_fn(bpctl_dev_t *pbpctl_dev, int timeout){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_BYPASS_WD; + bp_cmd_buf.cmd.cmd_data.timeout = htonl(timeout); + + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret = ntohl(bp_rsp_buf.rsp.rsp_data.timeout_set); + } + } + return ret; +} + + +int get_bypass_wd_rd_fn(bpctl_dev_t *pbpctl_dev, int *timeout){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_WD; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + *timeout = ntohl(bp_rsp_buf.rsp.rsp_data.timeout_set); + ret = 0; + } + } + return ret; +} + + +int get_wd_expire_time_rd_fn(bpctl_dev_t *pbpctl_dev, int *time_left){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_WD_EXPIRE_TIME; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + *time_left = ntohl(bp_rsp_buf.rsp.rsp_data.time_left); + if (*time_left == 0) + ret = 0; + else ret = 1; + } + } + return ret; +} + +int reset_bypass_wd_timer_rd_fn(bpctl_dev_t *pbpctl_dev){ + int ret=-1, gpio = 0, port = 0; + uint32_t cfg = 0, data = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + gpio = (port==1)?9:10; + + cfg = BPCTL_READ_REG(pbpctl_dev_c, FM10000_GPIO_CFG); + + cfg |= (1 << gpio); + cfg &= ~( 1 << (gpio + 16) ); + BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_CFG, cfg); + + data = BPCTL_READ_REG(pbpctl_dev_c, FM10000_GPIO_DATA); + data |= (1 << gpio); + BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_DATA, data); + data &= ~(1 << gpio); + BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_DATA, data); + usec_delay_bp(WDT_INTERVAL); + data |= (1 << gpio); + BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_DATA, data); + cfg &= ~(1 << gpio); + BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_CFG, cfg); + + return 1; +} + + +int get_wd_set_caps_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_WD_SET_CAPS; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) + ret=ntohl(bp_rsp_buf.rsp.rsp_data.wd_set_caps); + + } + } + return ret; +} + +int set_std_nic_rd_fn(bpctl_dev_t *pbpctl_dev, int nic_mode){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_SET_STD_NIC; + bp_cmd_buf.cmd.cmd_data.std_nic = + nic_mode?STD_NIC_EN:STD_NIC_DIS; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(BYPASS_CAP_DELAY); + return ret; +} + + +int get_std_nic_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_STD_NIC; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + if (bp_rsp_buf.rsp.rsp_data.std_nic==STD_NIC_EN) + ret=1; + else if (bp_rsp_buf.rsp.rsp_data.std_nic==STD_NIC_DIS) + ret=0; + } + } + return ret; +} + + +int set_disc_rd_fn (bpctl_dev_t *pbpctl_dev, int disc_mode){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_DISC; + bp_cmd_buf.cmd.cmd_data.disc_mode=disc_mode?1:0; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(LATCH_DELAY); + return ret; +} + + +int get_disc_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_DISC; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + if (bp_rsp_buf.rsp.rsp_data.disc_mode==1) + ret=1; + else if (bp_rsp_buf.rsp.rsp_data.disc_mode==0) + ret=0; + } + } + return ret; +} + + +int set_disc_pwup_rd_fn(bpctl_dev_t *pbpctl_dev, int disc_mode){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_DISC_PWUP; + bp_cmd_buf.cmd.cmd_data.disc_pwup = + disc_mode?DISC_PWUP_EN:DISC_PWUP_DIS; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(EEPROM_WR_DELAY); + return ret; +} + + +int get_disc_pwup_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_DISC_PWUP; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + if (bp_rsp_buf.rsp.rsp_data.disc_pwup==DISC_PWUP_EN) + ret=1; + else if (bp_rsp_buf.rsp.rsp_data.disc_pwup==DISC_PWUP_DIS) + ret=0; + } + } + return ret; +} + + +int get_disc_change_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_DISC_CHANGE; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + if (bp_rsp_buf.rsp.rsp_data.disc_change==DISC_CHANGED) + ret=1; + else if (bp_rsp_buf.rsp.rsp_data.disc_change==DISC_NOT_CHANGED) + ret=0; + } + } + return ret; +} + + +int set_dis_disc_rd_fn(bpctl_dev_t *pbpctl_dev, int dis_param){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_DIS_DISC; + bp_cmd_buf.cmd.cmd_data.dis_disc = + dis_param?DIS_DISC_DISABLE:DIS_DISC_ENABLE; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(BYPASS_CAP_DELAY); + return ret; +} + + +int get_dis_disc_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_DIS_DISC; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + if (bp_rsp_buf.rsp.rsp_data.dis_disc == DIS_DISC_DISABLE) + ret=1; + else if (bp_rsp_buf.rsp.rsp_data.dis_disc == DIS_DISC_ENABLE) + ret=0; + } + } + return ret; +} + + +int get_wd_exp_mode_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_WD_EXP_MODE; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=bp_rsp_buf.rsp.rsp_data.wd_exp_mode; + } + } + return ret; +} + + +int set_wd_exp_mode_rd_fn(bpctl_dev_t *pbpctl_dev, int param){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_WD_EXP_MODE; + bp_cmd_buf.cmd.cmd_data.wd_exp_mode = param; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(BYPASS_CAP_DELAY); + return ret; +} + + +int set_tx_rd_fn(bpctl_dev_t *pbpctl_dev, int tx_state){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + + if ((!port) || (port > 4)) + return -1; + + if (DBI240_IF_SERIES(pbpctl_dev_c->subdevice)) { + unsigned int mac_cfg[IES10K_MAC_CFG_WIDTH]; + + memset(mac_cfg, 0, IES10K_MAC_CFG_WIDTH*4); + + if (tx_state) { + iespl_read_mult_u32(pbpctl_dev_c, IES10K_MAC_CFG(pbpctl_dev->epl, pbpctl_dev->lane_num, 0 ), + IES10K_MAC_CFG_WIDTH, mac_cfg); + IES_ARRAY_SET_FIELD(mac_cfg, IES10K_MAC_CFG, TXFAULTMODE, 0); + iespl_write_mult_u32(pbpctl_dev_c, IES10K_MAC_CFG(pbpctl_dev->epl, pbpctl_dev->lane_num, 0 ), IES10K_MAC_CFG_WIDTH, mac_cfg); + } + else { + iespl_read_mult_u32(pbpctl_dev_c, IES10K_MAC_CFG(pbpctl_dev->epl, pbpctl_dev->lane_num, 0 ), + IES10K_MAC_CFG_WIDTH, mac_cfg); + IES_ARRAY_SET_FIELD(mac_cfg, IES10K_MAC_CFG, TXFAULTMODE, + convert_adminmode_txlinkfault(IES_PORT_MODE_LOCAL_FAULT)); + iespl_write_mult_u32(pbpctl_dev_c, IES10K_MAC_CFG(pbpctl_dev->epl, pbpctl_dev->lane_num, 0 ), IES10K_MAC_CFG_WIDTH, mac_cfg); + } + return 0; + } + + if (is_bypass_port_rd_fn(port)) { + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_data.tx_dis.port_num = 0; + } + else { + bp_cmd_buf.cmd.cmd_dev_num = (port == 2)? 0:1; + bp_cmd_buf.cmd.cmd_data.tx_dis.port_num = 1; + } + bp_cmd_buf.cmd.cmd_id = CMD_SET_TX; + bp_cmd_buf.cmd.cmd_data.tx_dis.mode = tx_state?TX_OFF:TX_ON; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + return ret; +} + + +int get_tx_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + + if ((!port) || (port > 4)) + return -1; + + if (DBI240_IF_SERIES(pbpctl_dev_c->subdevice)) { + unsigned int mac_cfg[IES10K_MAC_CFG_WIDTH]; + int tx_fault = 0; + + memset(mac_cfg, 0, IES10K_MAC_CFG_WIDTH*4); + + iespl_read_mult_u32(pbpctl_dev_c, IES10K_MAC_CFG(pbpctl_dev->epl, pbpctl_dev->lane_num, 0 ), + IES10K_MAC_CFG_WIDTH, mac_cfg); + tx_fault = IES_ARRAY_GET_FIELD(mac_cfg, IES10K_MAC_CFG, TXFAULTMODE); + + ret = (tx_fault == 2) ? 0:1; + return ret; + } + + if (is_bypass_port_rd_fn(port)) { + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_data.tx_dis.port_num = 0; + } + else { + bp_cmd_buf.cmd.cmd_dev_num = (port == 2)? 0:1; + bp_cmd_buf.cmd.cmd_data.tx_dis.port_num = 1; + } + + bp_cmd_buf.cmd.cmd_id = CMD_GET_TX; + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + if (bp_rsp_buf.rsp.rsp_data.tx_dis.mode==TX_ON) + ret=0; + else if (bp_rsp_buf.rsp.rsp_data.tx_dis.mode==TX_OFF) + ret=1; + } + else return -1; + } + return ret; +} + +int set_bp_force_link_rd_fn(int dev_num, int tx_state){ + return -1; +} + + +int get_bp_force_link_rd_fn(int dev_num){ + return -1; +} + +int set_bypass_wd_rd_auto(bpctl_dev_t *pbpctl_dev, unsigned int param){ + if (pbpctl_dev->bp_caps&WD_CTL_CAP) { + if (pbpctl_dev->reset_time!=param) { + pbpctl_dev->reset_time=param; + if (param) + mod_timer(&pbpctl_dev->bp_timer, jiffies); + } + return 0; + } + return BP_NOT_CAP; +} + +int get_bypass_wd_rd_auto(bpctl_dev_t *pbpctl_dev){ + + if (pbpctl_dev->bp_caps&WD_CTL_CAP) { + return pbpctl_dev->reset_time; + } + return BP_NOT_CAP; +} + + +int set_wd_autoreset_rd_fn(bpctl_dev_t *pbpctl_dev, int param){ + if (!pbpctl_dev) + return -1; + + return(set_bypass_wd_rd_auto(pbpctl_dev, param)); +} + +int get_wd_autoreset_rd_fn(bpctl_dev_t *pbpctl_dev){ + if (!pbpctl_dev) + return -1; + + return(get_bypass_wd_rd_auto(pbpctl_dev)); +} + + +int get_bypass_caps_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + + if ((!port) || (port > 4)) + return -1; + + if (is_bypass_port_rd_fn(port)) { + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + } + else { + bp_cmd_buf.cmd.cmd_dev_num = (port == 2)? 0:1; + } + + bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_CAPS; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=(ntohl(bp_rsp_buf.rsp.rsp_data.bypass_caps)); + if (!(is_bypass_port_rd_fn(port))){ + int ret1 = 0; + if (ret&TX_CTL_CAP) + ret1 = (TX_CTL_CAP|TX_STATUS_CAP); + return ret1; + + } + if (DBI240_IF_SERIES(pbpctl_dev_c->subdevice)) { + ret |= TX_CTL_CAP; + if (is_bypass_port_rd_fn(port)) + ret |= TPL_CAP; + } + } + } + + return ret; +} + + +int get_bypass_caps_ex_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;; + bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_CAPS_EX; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=ntohl(bp_rsp_buf.rsp.rsp_data.bypass_caps); + } + } + return ret; +} + +int get_bypass_slave_rd_fn(bpctl_dev_t *pbpctl_dev,bpctl_dev_t **pbpctl_dev_out){ + int idx_dev=0; + + if (!pbpctl_dev) + return -1; + + if ((pbpctl_dev->epl_num == 1)||(pbpctl_dev->epl_num == 3)) { + for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev != NULL)&&(idx_devsubdevice)) { + + if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)&& + (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)) { + if ((pbpctl_dev->epl_num == 1) && + (bpctl_dev_arr[idx_dev].epl_num == 2)) { + *pbpctl_dev_out = &bpctl_dev_arr[idx_dev]; + return 1; + } + if ((pbpctl_dev->epl_num == 3) && + (bpctl_dev_arr[idx_dev].epl_num == 4)) { + *pbpctl_dev_out = &bpctl_dev_arr[idx_dev]; + return 1; + } + } + } + else { + if (bpctl_dev_arr[idx_dev].pdev == pbpctl_dev->pdev_pf_slave) { + if ((pbpctl_dev->epl_num == 1) && + (bpctl_dev_arr[idx_dev].epl_num == 2)) { + *pbpctl_dev_out = &bpctl_dev_arr[idx_dev]; + return 1; + } + } + } + } + return -1; + } + else return 0; +} + + +int set_tpl_rd_fn(bpctl_dev_t *pbpctl_dev, int tpl_mode){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + if (DBI240_IF_SERIES(pbpctl_dev_c->subdevice)) { + uint32_t link1, link2; + bpctl_dev_t *pbpctl_dev_m, *pbpctl_dev2; + + pbpctl_dev_m = pbpctl_dev; + pbpctl_dev2 = get_status_port_fn(pbpctl_dev); + + if ((!pbpctl_dev_m)||(!pbpctl_dev2)) + return -1; + + if ((!pbpctl_dev->ndev)||(!pbpctl_dev2->ndev)) + return -1; + + pbpctl_dev->bp_tpl_flag = tpl_mode; + + set_tx_rd_fn(pbpctl_dev2, 1); + set_tx_rd_fn(pbpctl_dev, 1); + + if (!tpl_mode) + return 0; + + link1 = netif_carrier_ok(pbpctl_dev->ndev); + link2 = netif_carrier_ok(pbpctl_dev2->ndev); + + if ((!link1)&&(link2)) + set_tx_rd_fn(pbpctl_dev2, 0); + if ((link1)&&(!link2)) + set_tx_rd_fn(pbpctl_dev, 0); + + mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*HZ); + + return 0; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_TPL; + bp_cmd_buf.cmd.cmd_data.tpl_mode = tpl_mode?TPL_ON:TPL_OFF; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret = 0; + } + } + return ret; +} + + +int get_tpl_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + if (DBI240_IF_SERIES(pbpctl_dev_c->subdevice)) { + return pbpctl_dev->bp_tpl_flag; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_TPL; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_data.tpl_mode == TPL_ON) + ret = 1; + else if (bp_rsp_buf.rsp.rsp_data.tpl_mode == TPL_OFF) + ret = 0; + } + return ret; +} + + +int set_bp_wait_at_pwup_rd_fn(bpctl_dev_t *pbpctl_dev, int bp_wait_at_pwup){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_BP_WAIT_AT_PWUP; + bp_cmd_buf.cmd.cmd_data.bp_wait_at_pwup = bp_wait_at_pwup?1:0; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(EEPROM_WR_DELAY); + return ret; +} + +int get_bp_wait_at_pwup_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_BP_WAIT_AT_PWUP; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_data.bp_wait_at_pwup == 1) + ret = 1; + else if (bp_rsp_buf.rsp.rsp_data.bp_wait_at_pwup == 0) + ret = 0; + } + return ret; +} + + + +int set_bp_hw_reset_rd_fn(bpctl_dev_t *pbpctl_dev, int bp_hw_reset){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_BP_HW_RESET; + bp_cmd_buf.cmd.cmd_data.bp_hw_reset = bp_hw_reset?1:0; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(EEPROM_WR_DELAY); + return ret; +} + + +int get_bp_hw_reset_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_BP_HW_RESET; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_data.bp_hw_reset == 1) + ret = 1; + else if (bp_rsp_buf.rsp.rsp_data.bp_hw_reset == 0) + ret = 0; + } + return ret; +} + +int get_bypass_info_rd_fn(bpctl_dev_t *pbpctl_dev, char *dev_name, unsigned char *add_param){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_INFO; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + strcpy(dev_name, pbpctl_dev->name); + /**add_param = bp_rsp_buf.rsp.rsp_data.bypass_info.fw_ver;*/ + memcpy(add_param,(char *)&(bp_rsp_buf.rsp.rsp_data.bypass_info.fw_ver), 1); + ret=0; + } + return ret; +} + + +int set_bp_manuf_rd_fn(bpctl_dev_t *pbpctl_dev){ + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret = -1, port = 0; + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + + if (!pbpctl_dev) + return ret; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return ret; + + port = pbpctl_dev->epl_num; + + + if (!is_bypass_port_rd_fn(port)) + return ret; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1; + bp_cmd_buf.cmd.cmd_id = CMD_SET_BP_MANUF; + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) { + ret=0; + } + } + msec_delay_bp(BYPASS_CAP_DELAY); + return ret; + +} + +int bypass_fw_ver_rd(bpctl_dev_t *pbpctl_dev){ + bpctl_dev_mng_t *pbpctl_dev_c = NULL; + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret=-1, port = 0; + + if (!pbpctl_dev) + return -1; + + pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c; + if (!pbpctl_dev_c) + return -1; + + port = pbpctl_dev->epl_num; + + + if (!is_bypass_port_rd_fn(port)) + return -1; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + bp_cmd_buf.cmd.cmd_dev_num= (pbpctl_dev->func == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_BYPASS_INFO; + + + if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) { + ret = bp_rsp_buf.rsp.rsp_data.bypass_info.fw_ver; + } + return ret; +} + + + +static int wdt_timer_reload(bpctl_dev_t *pbpctl_dev){ + + if (pbpctl_dev->bp_caps&WD_CTL_CAP) { + reset_bypass_wd_timer_rd_fn(pbpctl_dev); + return 1; + } + else return BP_NOT_CAP; +} + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) +static void wd_reset_timer(unsigned long param){ + bpctl_dev_t *pbpctl_dev= (bpctl_dev_t *) param; +#else +static void wd_reset_timer(struct timer_list *t){ + bpctl_dev_t *pbpctl_dev= from_timer(pbpctl_dev, t, bp_timer); +#endif + + if ((pbpctl_dev->bp_ext_ver>=PXG2BPI_VER)&& + ((atomic_read(&pbpctl_dev->wdt_busy))==1)) { + mod_timer(&pbpctl_dev->bp_timer, jiffies+1); + return; + } + wdt_timer_reload(pbpctl_dev); + + if (pbpctl_dev->reset_time) { + mod_timer(&pbpctl_dev->bp_timer, jiffies+(HZ*pbpctl_dev->reset_time)/1000); + } +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) +static void bp_tpl_timer_fn(unsigned long param){ + bpctl_dev_t *pbpctl_dev=(bpctl_dev_t *) param; +#else +static void bp_tpl_timer_fn(struct timer_list *t){ + bpctl_dev_t *pbpctl_dev=from_timer(pbpctl_dev, t, bp_tpl_timer); +#endif + uint32_t link1, link2; + bpctl_dev_t *pbpctl_dev_b=NULL; + + + if (!(pbpctl_dev_b=get_status_port_fn(pbpctl_dev))) + return; + + + if (!pbpctl_dev->bp_tpl_flag) { + return; + } + + if ((!pbpctl_dev->ndev)||(!pbpctl_dev_b->ndev)) + return; + + link1 = netif_carrier_ok(pbpctl_dev->ndev); + link2 = netif_carrier_ok(pbpctl_dev_b->ndev); + + if (link1) + pbpctl_dev->tpl_wait = 0; + if (link2) + pbpctl_dev_b->tpl_wait = 0; + + if ((link1) && (!link2)) { + if (!get_tx_rd_fn(pbpctl_dev_b)) { + set_tx_rd_fn(pbpctl_dev_b, 1); + mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*2*HZ); + return; + } + } + + if ((link2) && (!link1)) { + if (!get_tx_rd_fn(pbpctl_dev)) { + set_tx_rd_fn(pbpctl_dev, 1); + mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*2*HZ); + return; + } + } + + if ((link1)&&(get_tx_rd_fn(pbpctl_dev))) { + if ((!link2)&&(get_tx_rd_fn(pbpctl_dev_b))) { + if (pbpctl_dev_b->tpl_wait){ + pbpctl_dev_b->tpl_wait = 0; + mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*2*HZ); + return; + } + set_tx_rd_fn(pbpctl_dev,0); + } + else if (!get_tx_rd_fn(pbpctl_dev_b)) { + pbpctl_dev_b->tpl_wait = 1; + set_tx_rd_fn(pbpctl_dev_b,1); + } + } + else if ((!link1)&&(get_tx_rd_fn(pbpctl_dev))) { + if ((link2)&&(get_tx_rd_fn(pbpctl_dev_b))) { + if (pbpctl_dev->tpl_wait){ + pbpctl_dev->tpl_wait = 0; + mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*2*HZ); + return; + } + set_tx_rd_fn(pbpctl_dev_b,0); + } + } + else if ((link1)&&(!get_tx_rd_fn(pbpctl_dev))) { + if ((link2)&&(get_tx_rd_fn(pbpctl_dev_b))) { + pbpctl_dev->tpl_wait = 1; + set_tx_rd_fn(pbpctl_dev,1); + } + } + else if ((!link1)&&(!get_tx_rd_fn(pbpctl_dev))) { + if ((link2)&&(get_tx_rd_fn(pbpctl_dev_b))) { + pbpctl_dev->tpl_wait = 1; + set_tx_rd_fn(pbpctl_dev,1); + } + } + + mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*HZ); +} + + +static void remove_bypass_wd_auto(bpctl_dev_t *pbpctl_dev){ + if (pbpctl_dev->bp_caps&WD_CTL_CAP) { + del_timer_sync(&pbpctl_dev->bp_timer); + } +} + +void remove_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev){ + if ((is_bypass_rd_fn(pbpctl_dev)) && + (DBI240_IF_SERIES(pbpctl_dev->subdevice))) + { + set_tpl_rd_fn(pbpctl_dev, 0); + del_timer_sync(&pbpctl_dev->bp_tpl_timer); + + } + return; +} + + +static int init_bypass_wd_auto(bpctl_dev_t *pbpctl_dev){ + if (pbpctl_dev->bp_caps&WD_CTL_CAP) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) + init_timer(&pbpctl_dev->bp_timer); + pbpctl_dev->bp_timer.function=&wd_reset_timer; + pbpctl_dev->bp_timer.data=(unsigned long)pbpctl_dev; +#else + timer_setup(&pbpctl_dev->bp_timer, wd_reset_timer, 0); +#endif + return 1; + } + return BP_NOT_CAP; +} + + +int init_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev){ + if (!pbpctl_dev) + return BP_NOT_CAP; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) + init_timer(&pbpctl_dev->bp_tpl_timer); + pbpctl_dev->bp_tpl_timer.function=&bp_tpl_timer_fn; + pbpctl_dev->bp_tpl_timer.data=(unsigned long)pbpctl_dev; +#else + timer_setup(&pbpctl_dev->bp_tpl_timer, bp_tpl_timer_fn, 0); +#endif + return BP_OK; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) +static int device_ioctl(struct inode *inode, /* see include/linux/fs.h */ + struct file *file, /* ditto */ + unsigned int ioctl_num, /* number and param for ioctl */ + unsigned long ioctl_param) +#else +static long device_ioctl(struct file *file, /* ditto */ + unsigned int ioctl_num, /* number and param for ioctl */ + unsigned long ioctl_param) + +#endif +{ + struct bpctl_cmd bpctl_cmd; + int dev_idx=0; + bpctl_dev_t *pbpctl_dev_out; + void __user *argp = (void __user *)ioctl_param; + int ret=0; + bpctl_dev_t *pbpctl_dev; + + if (ioctl_num == IOCTL_TX_MSG(EXCLUSIVE_LOCK)) { + dev_idx = get_dev_mng_idx(ioctl_param); + if ( dev_idx < 0 || dev_idx > mng_device_num) { + return -1; + } + TAKE_PLAT_I2C_BUS_LOCK_IDX(file, dev_idx); + return SUCCESS; + } + + if (ioctl_num == IOCTL_TX_MSG(DROP_EXCLUSIVE)) { + dev_idx = get_dev_mng_idx(ioctl_param); + if ( dev_idx < 0 || dev_idx > mng_device_num) { + return -1; + } + DROP_PLAT_I2C_BUS_LOCK_IDX(file, dev_idx); + return SUCCESS; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) + //lock_kernel(); +#endif + lock_bpctl(); + +/* +* Switch according to the ioctl called +*/ + if (ioctl_num==IOCTL_TX_MSG(IF_SCAN)) { + if_scan_init(); + ret=SUCCESS; + goto bp_exit; + } + if (copy_from_user(&bpctl_cmd, argp, sizeof(struct bpctl_cmd))) { + + ret= -EFAULT; + goto bp_exit; + } + + if (ioctl_num==IOCTL_TX_MSG(GET_DEV_NUM)) { + bpctl_cmd.out_param[0]= device_num; + if (copy_to_user(argp,(void *)&bpctl_cmd,sizeof(struct bpctl_cmd))) { + ret=-EFAULT; + goto bp_exit; + } + ret=SUCCESS; + goto bp_exit; + + } + + + if ((bpctl_cmd.in_param[5])|| + (bpctl_cmd.in_param[6])|| + (bpctl_cmd.in_param[7])) + dev_idx=get_dev_idx_bsf(bpctl_cmd.in_param[5], + bpctl_cmd.in_param[6], + bpctl_cmd.in_param[7]); + else if (bpctl_cmd.in_param[1]==0) + dev_idx= bpctl_cmd.in_param[0]; + else dev_idx=get_dev_idx(bpctl_cmd.in_param[1]); + + + if (dev_idx<0||dev_idx>device_num) { + ret= -EOPNOTSUPP; + goto bp_exit; + } + + bpctl_cmd.out_param[0]= bpctl_dev_arr[dev_idx].bus; + bpctl_cmd.out_param[1]= bpctl_dev_arr[dev_idx].slot; + bpctl_cmd.out_param[2]= bpctl_dev_arr[dev_idx].func; + bpctl_cmd.out_param[3]= bpctl_dev_arr[dev_idx].ifindex; + + + if ((dev_idx<0)||(dev_idx>device_num)||(bpctl_dev_arr[dev_idx].pdev==NULL)) { + bpctl_cmd.status=-1; + goto bpcmd_exit; + } + + pbpctl_dev=&bpctl_dev_arr[dev_idx]; + + + + switch (ioctl_num) { + case IOCTL_TX_MSG(SET_BYPASS_PWOFF) : + bpctl_cmd.status= set_bypass_pwoff_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BYPASS_PWOFF) : + bpctl_cmd.status= get_bypass_pwoff_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_BYPASS_PWUP) : + bpctl_cmd.status= set_bypass_pwup_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BYPASS_PWUP) : + bpctl_cmd.status= get_bypass_pwup_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_BYPASS_WD) : + bpctl_cmd.status= set_bypass_wd_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BYPASS_WD) : + bpctl_cmd.status= get_bypass_wd_rd_fn(pbpctl_dev,(int *)&(bpctl_cmd.data[0])); + break; + + case IOCTL_TX_MSG(GET_WD_EXPIRE_TIME) : + bpctl_cmd.status= get_wd_expire_time_rd_fn(pbpctl_dev, (int *)&(bpctl_cmd.data[0])); + break; + + case IOCTL_TX_MSG(RESET_BYPASS_WD_TIMER) : + bpctl_cmd.status= reset_bypass_wd_timer_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(GET_WD_SET_CAPS) : + bpctl_cmd.status= get_wd_set_caps_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_STD_NIC) : + bpctl_cmd.status= set_std_nic_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_STD_NIC) : + bpctl_cmd.status= get_std_nic_rd_fn(pbpctl_dev); + break; +#if 0 + + case IOCTL_TX_MSG(SET_TAP) : + bpctl_cmd.status= set_tap_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_TAP) : + bpctl_cmd.status= get_tap_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(GET_TAP_CHANGE) : + bpctl_cmd.status= get_tap_change_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_DIS_TAP) : + bpctl_cmd.status= set_dis_tap_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_DIS_TAP) : + bpctl_cmd.status= get_dis_tap_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_TAP_PWUP) : + bpctl_cmd.status= set_tap_pwup_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_TAP_PWUP) : + bpctl_cmd.status= get_tap_pwup_rd_fn(pbpctl_dev); + break; +#endif + + case IOCTL_TX_MSG(SET_WD_EXP_MODE): + bpctl_cmd.status= set_wd_exp_mode_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_WD_EXP_MODE): + bpctl_cmd.status= get_wd_exp_mode_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(GET_DIS_BYPASS): + bpctl_cmd.status= get_dis_bypass_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_DIS_BYPASS): + bpctl_cmd.status= set_dis_bypass_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BYPASS_CHANGE): + bpctl_cmd.status= get_bypass_change_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(GET_WD_EXPIRE): + bpctl_cmd.status= get_wd_expire_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(GET_BYPASS): + bpctl_cmd.status= get_bypass_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_BYPASS): + bpctl_cmd.status= set_bypass_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BYPASS_CAPS): + bpctl_cmd.status= get_bypass_caps_rd_fn(pbpctl_dev); + if (copy_to_user(argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) { + ret= -EFAULT; + goto bp_exit; + } + goto bp_exit; + + case IOCTL_TX_MSG(GET_BYPASS_SLAVE): + bpctl_cmd.status = get_bypass_slave_rd_fn(pbpctl_dev, &pbpctl_dev_out); + if (bpctl_cmd.status==1) { + bpctl_cmd.out_param[4]= pbpctl_dev_out->bus; + bpctl_cmd.out_param[5]= pbpctl_dev_out->slot; + bpctl_cmd.out_param[6]= pbpctl_dev_out->func; + bpctl_cmd.out_param[7]= pbpctl_dev_out->ifindex; + } + break; + + case IOCTL_TX_MSG(IS_BYPASS): + bpctl_cmd.status= is_bypass_rd_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_TX): + bpctl_cmd.status= set_tx_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + case IOCTL_TX_MSG(GET_TX): + bpctl_cmd.status= get_tx_rd_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_WD_AUTORESET): + bpctl_cmd.status= set_wd_autoreset_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + + break; + case IOCTL_TX_MSG(GET_WD_AUTORESET): + + bpctl_cmd.status= get_wd_autoreset_rd_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_DISC) : + bpctl_cmd.status=set_disc_rd_fn(pbpctl_dev,bpctl_cmd.in_param[2]); + break; + case IOCTL_TX_MSG(GET_DISC) : + bpctl_cmd.status=get_disc_rd_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(GET_DISC_CHANGE) : + bpctl_cmd.status=get_disc_change_rd_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_DIS_DISC) : + bpctl_cmd.status=set_dis_disc_rd_fn(pbpctl_dev,bpctl_cmd.in_param[2]); + break; + case IOCTL_TX_MSG(GET_DIS_DISC) : + bpctl_cmd.status=get_dis_disc_rd_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_DISC_PWUP) : + bpctl_cmd.status=set_disc_pwup_rd_fn(pbpctl_dev,bpctl_cmd.in_param[2]); + break; + case IOCTL_TX_MSG(GET_DISC_PWUP) : + bpctl_cmd.status=get_disc_pwup_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(GET_BYPASS_INFO): + + bpctl_cmd.status= get_bypass_info_rd_fn(pbpctl_dev, (char *)&bpctl_cmd.data, (char *)&bpctl_cmd.out_param[4]); + break; + + case IOCTL_TX_MSG(SET_TPL) : + bpctl_cmd.status= set_tpl_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_TPL) : + bpctl_cmd.status= get_tpl_rd_fn(pbpctl_dev); + break; +//#ifdef PMC_FIX_FLAG + case IOCTL_TX_MSG(SET_BP_WAIT_AT_PWUP) : + bpctl_cmd.status= set_bp_wait_at_pwup_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BP_WAIT_AT_PWUP) : + bpctl_cmd.status= get_bp_wait_at_pwup_rd_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(SET_BP_HW_RESET) : + bpctl_cmd.status= set_bp_hw_reset_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BP_HW_RESET) : + bpctl_cmd.status= get_bp_hw_reset_rd_fn(pbpctl_dev); + break; +//#endif +#ifdef BP_SELF_TEST + case IOCTL_TX_MSG(SET_BP_SELF_TEST): + bpctl_cmd.status= set_bp_self_test_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + + break; + case IOCTL_TX_MSG(GET_BP_SELF_TEST): + bpctl_cmd.status= get_bp_self_test_rd_fn(pbpctl_dev); + break; + + +#endif +#if 0 + case IOCTL_TX_MSG(SET_DISC_PORT) : + bpctl_cmd.status= set_disc_port_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_DISC_PORT) : + bpctl_cmd.status= get_disc_port_rd_fn(pbpctl_dev); + break; + + case IOCTL_TX_MSG(SET_DISC_PORT_PWUP) : + bpctl_cmd.status= set_disc_port_pwup_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_DISC_PORT_PWUP) : + bpctl_cmd.status= get_disc_port_pwup_rd_fn(pbpctl_dev); + break; +#endif + case IOCTL_TX_MSG(SET_BP_FORCE_LINK): + bpctl_cmd.status= set_bp_force_link_rd_fn(dev_idx, bpctl_cmd.in_param[2]); + break; + + case IOCTL_TX_MSG(GET_BP_FORCE_LINK): + bpctl_cmd.status= get_bp_force_link_rd_fn(dev_idx); + break; + + case IOCTL_TX_MSG(SET_BP_MANUF) : + bpctl_cmd.status= set_bp_manuf_rd_fn(pbpctl_dev); + break; + + + default: + + ret= -EOPNOTSUPP; + goto bp_exit; + } + bpcmd_exit: + if (copy_to_user(argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) + ret= -EFAULT; + ret= SUCCESS; + bp_exit: +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) +#endif + unlock_bpctl(); + return ret; +} + + +static struct file_operations Fops = { + .owner = THIS_MODULE, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) + .ioctl = device_ioctl, +#else + .unlocked_ioctl = device_ioctl, +#endif + + .open = device_open, + .release = device_release, /* a.k.a. close */ +}; + + +typedef struct _bpmod_info_t { + unsigned int vendor; + unsigned int device; + unsigned int subvendor; + unsigned int subdevice; + unsigned int index; + char *bp_name; + +} bpmod_info_t; + + +#define SILICOM_SVID 0x1374 + +static bpmod_info_t tx_ctl_pci_tbl[] = { + {0x8086, 0x15A4, SILICOM_SVID, 0x01B0, 0, "PE310G4DBiR-T"}, + {0x8086, 0x15A4, 0x1B2E, 0x01B0, 0, "PE310G4DBiR-T-RB2"}, + + {0x8086, 0x15A4, 0x8086, 0x000, 0, "PE310G4DBiR"}, + {0x8086, 0x15A4, SILICOM_SVID, 0x01B1, 0, "PE310G4DBiR-SRD"}, + {0x8086, 0x15A4, 0x1B2E, 0x01B1, 0, "PE310G4DBiR-SRD-RB2"}, + + {0x8086, 0x15A4, SILICOM_SVID, 0x01B2, 0, "PE310G4DBiR-LRD"}, + {0x8086, 0x15A4, 0x1B2E, 0x01B2, 0, "PE310G4DBiR-LRD-RB2"}, + + {0x8086, 0x15A4, SILICOM_SVID, 0x01B3, 0, "PE310G4DBiR-ERD"}, + {0x8086, 0x15A4, 0x1B2E, 0x01B3, 0, "PE310G4DBiR-ERD-RB2"}, + + {0x8086, 0x15A4, SILICOM_SVID, 0x01B4, 0, "PE310G4DBiR-DA"}, + {0x8086, 0x15A4, 0x1B2E, 0x01B4, 0, "PE310G4DBiR-DA-RB2"}, + + + + {0x8086, 0x15A5, SILICOM_SVID, 0x01B0, 0, "PE310G4DBiR-T"}, + {0x8086, 0x15A5, 0x1B2E, 0x01B0, 0, "PE310G4DBiR-T-RB2"}, + + {0x8086, 0x15A5, 0x8086, 0x000, 0, "PE310G4DBiR"}, + {0x8086, 0x15A5, SILICOM_SVID, 0x01B1, 0, "PE310G4DBiR-SRD"}, + {0x8086, 0x15A5, 0x1B2E, 0x01B1, 0, "PE310G4DBiR-SRD-RB2"}, + + {0x8086, 0x15A5, SILICOM_SVID, 0x01B2, 0, "PE310G4DBiR-LRD"}, + {0x8086, 0x15A5, 0x1B2E, 0x01B2, 0, "PE310G4DBiR-LRD-RB2"}, + + {0x8086, 0x15A5, SILICOM_SVID, 0x01B3, 0, "PE310G4DBiR-ERD"}, + {0x8086, 0x15A5, 0x1B2E, 0x01B3, 0, "PE310G4DBiR-ERD-RB2"}, + + {0x8086, 0x15A5, SILICOM_SVID, 0x01B4, 0, "PE310G4DBiR-DA"}, + {0x8086, 0x15A5, 0x1B2E, 0x01B4, 0, "PE310G4DBiR-DA-RB2"}, + + + + {0x8086, 0x15A4, SILICOM_SVID, 0x01B8, 0, "PE340G2DBIR-QS41"}, + {0x8086, 0x15A4, 0x1B2E, 0x01B8, 0, "PE340G2DBIR-QS41-RB2"}, + + {0x8086, 0x15A4, SILICOM_SVID, 0x01B9, 0, "PE340G2DBIR-QS43"}, + {0x8086, 0x15A4, 0x1B2E, 0x01B9, 0, "PE340G2DBIR-QS43-RB2"}, + + {0x8086, 0x15A4, SILICOM_SVID, 0x01BA, 0, "PE340G2DBIR-QL4"}, + {0x8086, 0x15A4, 0x1B2E, 0x01BA, 0, "PE340G2DBIR-QL4-RB2"}, + + {0x8086, 0x15A4, SILICOM_SVID, 0x01BC, 0, "PE3100G2DBIR-ZS4"}, + {0x8086, 0x15A4, 0x1B2E, 0x01BC, 0, "PE3100G2DBIR-ZS4-RB2"}, + +#if 0 + {0x8086, 0x15A4, SILICOM_SVID, 0x01C0, 0, "PE3100G2DQIR-QX4/QS4/QL4"}, + {0x8086, 0x15A4, SILICOM_SVID, 0x01C1, 0, "PE3100G2DQIRL-QX4/QS4/QL4"}, + {0x8086, 0x15A4, SILICOM_SVID, 0x01C2, 0, "PE3100G2DQIRM-QX4/QS4/QL4"}, + {0x8086, 0x15A4, SILICOM_SVID, 0x01C8, 0, "PE325G2DSIR"}, +#endif + + /* required last entry */ + {0,} +}; + + + + + + +static int v2_bypass_init_module(void) +{ + int ret_val, idx, idx_dev = 0, idx_dev_mng = 0; + struct pci_dev *pdev1 = NULL; + unsigned long mmio_start, mmio_len; + + ret_val = register_chrdev (major_num, DEVICE_NAME, &Fops); + if (ret_val < 0) { + printk("%s failed with %d\n",DEVICE_NAME,ret_val); + return ret_val; + } + major_num = ret_val; /* dynamic */ + for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) { + while ((pdev1=pci_get_subsys(tx_ctl_pci_tbl[idx].vendor, + tx_ctl_pci_tbl[idx].device, + tx_ctl_pci_tbl[idx].subvendor, + tx_ctl_pci_tbl[idx].subdevice, + pdev1))) { + + u32 __iomem *uc_addr; + + if (tx_ctl_pci_tbl[idx].device == 0x15a4) { + + uc_addr = ioremap(pci_resource_start(pdev1, 0), + FM10K_UC_ADDR_SIZE); + if (uc_addr) { + if (readl((void *)(uc_addr+0)) & 0x4) { + mng_device_num++; + } + if (!(DBI410_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice))) + device_num++; + } + } + else if (DBI410_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice)){ + if ((PCI_FUNC(pdev1->devfn) == 1) || + (PCI_FUNC(pdev1->devfn) == 2) || + (PCI_FUNC(pdev1->devfn) == 3) || + (PCI_FUNC(pdev1->devfn) == 4)) + device_num++; + } + } + } + if (!device_num) { + printk("No such device\n"); + unregister_chrdev(major_num, DEVICE_NAME); + return -1; + } + + bpctl_dev_arr=kmalloc ((device_num) * sizeof (bpctl_dev_t), GFP_KERNEL); + bpctl_dev_mng_arr=kmalloc ((mng_device_num) * sizeof (bpctl_dev_mng_t), GFP_KERNEL); + + if (!bpctl_dev_arr || (! bpctl_dev_mng_arr)) { + printk("Allocation error\n"); + unregister_chrdev(major_num, DEVICE_NAME); + return -1; + } + memset(bpctl_dev_arr,0,((device_num) * sizeof (bpctl_dev_t))); + + pdev1=NULL; + for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) { + while ((pdev1=pci_get_subsys(tx_ctl_pci_tbl[idx].vendor, + tx_ctl_pci_tbl[idx].device, + tx_ctl_pci_tbl[idx].subvendor, + tx_ctl_pci_tbl[idx].subdevice, + pdev1))) { + + u32 __iomem *uc_addr; + mmio_start = 0; + mmio_len = 0; + + if ((tx_ctl_pci_tbl[idx].device == 0x15a5) && + (DBI410_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice))) { + + if ((PCI_FUNC(pdev1->devfn) == 1) || + (PCI_FUNC(pdev1->devfn) == 2) || + (PCI_FUNC(pdev1->devfn) == 3) || + (PCI_FUNC(pdev1->devfn) == 4)) { + bpctl_dev_arr[idx_dev].pdev=pdev1; + + bpctl_dev_arr[idx_dev].name = tx_ctl_pci_tbl[idx].bp_name; + bpctl_dev_arr[idx_dev].device = tx_ctl_pci_tbl[idx].device; + bpctl_dev_arr[idx_dev].vendor = tx_ctl_pci_tbl[idx].vendor; + bpctl_dev_arr[idx_dev].subdevice = tx_ctl_pci_tbl[idx].subdevice; + bpctl_dev_arr[idx_dev].subvendor = tx_ctl_pci_tbl[idx].subvendor; + //ctl_dev_arr[idx_dev].pdev=pdev1; + bpctl_dev_arr[idx_dev].func = PCI_FUNC(pdev1->devfn); + bpctl_dev_arr[idx_dev].slot = PCI_SLOT(pdev1->devfn); + bpctl_dev_arr[idx_dev].bus = pdev1->bus->number; + bpctl_dev_arr[idx_dev].bp_master_flag = + (((bpctl_dev_arr[idx_dev].func == 1)||(bpctl_dev_arr[idx_dev].func == 3)) ? 1:0); + bpctl_dev_arr[idx_dev].epl_num = bpctl_dev_arr[idx_dev].func; + bpctl_dev_arr[idx_dev].lane_num = bpctl_dev_arr[idx_dev].func - 1; + bpctl_dev_arr[idx_dev].port_num = 49999 + bpctl_dev_arr[idx_dev].func; + bpctl_dev_arr[idx_dev].epl = 0; + idx_dev++; + } + } + else { + uc_addr = ioremap(pci_resource_start(pdev1, 0), + FM10K_UC_ADDR_SIZE); + + + if (uc_addr) { + if (readl((void *)(uc_addr+0)) & 0x4) { + mmio_start = pci_resource_start (pdev1, 4); + mmio_len = pci_resource_len (pdev1, 4); + if ((!mmio_len)||(!mmio_start)) + continue; + bpctl_dev_mng_arr[idx_dev_mng].pdev=pdev1; + + bpctl_dev_mng_arr[idx_dev_mng].name=tx_ctl_pci_tbl[idx].bp_name; + bpctl_dev_mng_arr[idx_dev_mng].device=tx_ctl_pci_tbl[idx].device; + bpctl_dev_mng_arr[idx_dev_mng].vendor=tx_ctl_pci_tbl[idx].vendor; + bpctl_dev_mng_arr[idx_dev_mng].subdevice=tx_ctl_pci_tbl[idx].subdevice; + bpctl_dev_mng_arr[idx_dev_mng].subvendor=tx_ctl_pci_tbl[idx].subvendor; + //ctl_dev_arr[idx_dev].pdev=pdev1; + bpctl_dev_mng_arr[idx_dev_mng].func= PCI_FUNC(pdev1->devfn); + bpctl_dev_mng_arr[idx_dev_mng].slot= PCI_SLOT(pdev1->devfn); + bpctl_dev_mng_arr[idx_dev_mng].bus=pdev1->bus->number; + bpctl_dev_mng_arr[idx_dev_mng].mem_map=(unsigned long)ioremap(mmio_start,mmio_len); + spin_lock_init(&bpctl_dev_mng_arr[idx_dev_mng].bypass_wr_lock); + if (DBI410_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice)) { + bpctl_dev_mng_arr[idx_dev_mng].port_num = 5; + } + else bpctl_dev_mng_arr[idx_dev_mng].port_num = 4; + mutex_init(&bpctl_dev_mng_arr[idx_dev_mng].i2c_bus_lock); + idx_dev_mng++; + } + } + if (!(DBI410_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice))) { + bpctl_dev_arr[idx_dev].pdev=pdev1; + + bpctl_dev_arr[idx_dev].name = tx_ctl_pci_tbl[idx].bp_name; + bpctl_dev_arr[idx_dev].device = tx_ctl_pci_tbl[idx].device; + bpctl_dev_arr[idx_dev].vendor = tx_ctl_pci_tbl[idx].vendor; + bpctl_dev_arr[idx_dev].subdevice = tx_ctl_pci_tbl[idx].subdevice; + bpctl_dev_arr[idx_dev].subvendor = tx_ctl_pci_tbl[idx].subvendor; + bpctl_dev_arr[idx_dev].func = PCI_FUNC(pdev1->devfn); + bpctl_dev_arr[idx_dev].slot = PCI_SLOT(pdev1->devfn); + bpctl_dev_arr[idx_dev].bus = pdev1->bus->number; + if (!mmio_start) { + bpctl_dev_arr[idx_dev].bp_master_flag = 1; + bpctl_dev_arr[idx_dev].epl_num = 1; + bpctl_dev_arr[idx_dev].port_num = 3; + bpctl_dev_arr[idx_dev].epl = 0; + } + else { + bpctl_dev_arr[idx_dev].epl_num = 2; + bpctl_dev_arr[idx_dev].port_num = 4; + bpctl_dev_arr[idx_dev].epl = 6; + } + bpctl_dev_arr[idx_dev].lane_num = 0; + idx_dev++; + } + + } + } + } + if_scan_init(); + if_scan_mng_init(); + + sema_init (&bpctl_sema, 1); + + + + { + + for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev!=NULL)&&(idx_devpdev; + + } + + + + if (is_bypass_rd_fn(&bpctl_dev_arr[idx_dev])) { + printk(KERN_INFO "%s found, ", bpctl_dev_arr[idx_dev].name); + bpctl_dev_arr[idx_dev].bp_fw_ver=bypass_fw_ver_rd(&bpctl_dev_arr[idx_dev]); + + //bpctl_dev_arr[idx_dev].bp_fw_ver=0xa8; + printk("firmware version: 0x%x\n",bpctl_dev_arr[idx_dev].bp_fw_ver); + } + bpctl_dev_arr[idx_dev].wdt_status=WDT_STATUS_UNKNOWN; + bpctl_dev_arr[idx_dev].reset_time=0; + atomic_set(&bpctl_dev_arr[idx_dev].wdt_busy,0); + bpctl_dev_arr[idx_dev].bp_status_un=1; + + bpctl_dev_arr[idx_dev].bp_caps = get_bypass_caps_rd_fn(&bpctl_dev_arr[idx_dev]); + + get_tpl_rd_fn(&bpctl_dev_arr[idx_dev]); + init_bypass_wd_auto(&bpctl_dev_arr[idx_dev]); + if ((is_bypass_rd_fn(&bpctl_dev_arr[idx_dev])) && + (DBI240_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))) + init_bypass_tpl_auto(&bpctl_dev_arr[idx_dev]); + } + } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + inter_module_register("is_bypass_rd", THIS_MODULE, &is_bypass_rd); + inter_module_register("get_bypass_slave_rd", THIS_MODULE, &get_bypass_slave_rd); + inter_module_register("get_bypass_caps_rd", THIS_MODULE, &get_bypass_caps_rd); + inter_module_register("get_wd_set_caps_rd", THIS_MODULE, &get_wd_set_caps_rd); + inter_module_register("set_bypass_rd", THIS_MODULE, &set_bypass_rd); + inter_module_register("get_bypass_rd", THIS_MODULE, &get_bypass_rd); + inter_module_register("get_bypass_change_rd", THIS_MODULE, &get_bypass_change_rd); + inter_module_register("set_dis_bypass_rd", THIS_MODULE, &set_dis_bypass_rd); + inter_module_register("get_dis_bypass_rd", THIS_MODULE, &get_dis_bypass_rd); + inter_module_register("set_bypass_pwoff_rd", THIS_MODULE, &set_bypass_pwoff_rd); + inter_module_register("get_bypass_pwoff_rd", THIS_MODULE, &get_bypass_pwoff_rd); + inter_module_register("set_bypass_pwup_rd", THIS_MODULE, &set_bypass_pwup_rd); + inter_module_register("get_bypass_pwup_rd", THIS_MODULE, &get_bypass_pwup_rd); + inter_module_register("get_bypass_wd_rd", THIS_MODULE, &get_bypass_wd_rd); + inter_module_register("set_bypass_wd_rd", THIS_MODULE, &set_bypass_wd_rd); + inter_module_register("get_wd_expire_time_rd", THIS_MODULE, &get_wd_expire_time_rd); + inter_module_register("reset_bypass_wd_timer_rd", THIS_MODULE, &reset_bypass_wd_timer_rd); + inter_module_register("set_std_nic_rd", THIS_MODULE, &set_std_nic_rd); + inter_module_register("get_std_nic_rd", THIS_MODULE, &get_std_nic_rd); + inter_module_register("set_tx_rd", THIS_MODULE, &set_tx_rd); + inter_module_register("get_tx_rd", THIS_MODULE, &get_tx_rd); + inter_module_register("set_tpl_rd", THIS_MODULE, &set_tpl_rd); + inter_module_register("get_tpl_rd", THIS_MODULE, &get_tpl_rd); + + inter_module_register("set_bp_hw_reset_rd", THIS_MODULE, &set_bp_hw_reset_rd); + inter_module_register("get_bp_hw_reset_rd", THIS_MODULE, &get_bp_hw_reset_rd); +#if 0 + inter_module_register("set_tap_rd", THIS_MODULE, &set_tap_rd); + inter_module_register("get_tap_rd", THIS_MODULE, &get_tap_rd); + inter_module_register("get_tap_change_rd", THIS_MODULE, &get_tap_change_rd); + inter_module_register("set_dis_tap_rd", THIS_MODULE, &set_dis_tap_rd); + inter_module_register("get_dis_tap_rd", THIS_MODULE, &get_dis_tap_rd); + inter_module_register("set_tap_pwup_rd", THIS_MODULE, &set_tap_pwup_rd); + inter_module_register("get_tap_pwup_rd", THIS_MODULE, &get_tap_pwup_rd); +#endif + inter_module_register("set_bp_disc_rd", THIS_MODULE, &set_bp_disc_rd); + inter_module_register("get_bp_disc_rd", THIS_MODULE, &get_bp_disc_rd); + inter_module_register("get_bp_disc_change_rd", THIS_MODULE, &get_bp_disc_change_rd); + inter_module_register("set_bp_dis_disc_rd", THIS_MODULE, &set_bp_dis_disc_rd); + inter_module_register("get_bp_dis_disc_rd", THIS_MODULE, &get_bp_dis_disc_rd); + inter_module_register("set_bp_disc_pwup_rd", THIS_MODULE, &set_bp_disc_pwup_rd); + inter_module_register("get_bp_disc_pwup_rd", THIS_MODULE, &get_bp_disc_pwup_rd); + inter_module_register("set_wd_exp_mode_rd", THIS_MODULE, &set_wd_exp_mode_rd); + inter_module_register("get_wd_exp_mode_rd", THIS_MODULE, &get_wd_exp_mode_rd); + inter_module_register("set_wd_autoreset_rd", THIS_MODULE, &set_wd_autoreset_rd); + inter_module_register("get_wd_autoreset_rd", THIS_MODULE, &get_wd_autoreset_rd); + inter_module_register("get_bypass_info_rd", THIS_MODULE, &get_bypass_info_rd); + inter_module_register("bp_if_scan_rd", THIS_MODULE, &bp_if_scan_rd); + +#endif + + register_netdevice_notifier(&bp_notifier_block); + register_reboot_notifier(&bp_reboot_block); +#ifdef BP_PROC_SUPPORT + { + int i=0; + bp_proc_create(); + for (i = 0; i < device_num; i++) { + if (bpctl_dev_arr[i].ifindex) { + bypass_proc_remove_dev_rd(&bpctl_dev_arr[i]); + bypass_proc_create_dev_rd(&bpctl_dev_arr[i]); + } + + } + } +#endif + + return 0; +} + + +static void __exit bypass_cleanup_module(void) +{ + int i ; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) + int ret; +#endif + unregister_netdevice_notifier(&bp_notifier_block); + unregister_reboot_notifier(&bp_reboot_block); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + inter_module_unregister("is_bypass_rd"); + inter_module_unregister("get_bypass_slave_rd"); + inter_module_unregister("get_bypass_caps_rd"); + inter_module_unregister("get_wd_set_caps_rd"); + inter_module_unregister("set_bypass_rd"); + inter_module_unregister("get_bypass_rd"); + inter_module_unregister("get_bypass_change_rd"); + inter_module_unregister("set_dis_bypass_rd"); + inter_module_unregister("get_dis_bypass_rd"); + inter_module_unregister("set_bypass_pwoff_rd"); + inter_module_unregister("get_bypass_pwoff_rd"); + inter_module_unregister("set_bypass_pwup_rd"); + inter_module_unregister("get_bypass_pwup_rd"); + inter_module_unregister("set_bypass_wd_rd"); + inter_module_unregister("get_bypass_wd_rd"); + inter_module_unregister("get_wd_expire_time_rd"); + inter_module_unregister("reset_bypass_wd_timer_rd"); + inter_module_unregister("set_std_nic_rd"); + inter_module_unregister("get_std_nic_rd"); + inter_module_unregister("set_tx_rd"); + inter_module_unregister("get_tx_rd"); + inter_module_unregister("set_tpl_rd"); + inter_module_unregister("get_tpl_rd"); +#if 0 + inter_module_unregister("set_tap_rd"); + inter_module_unregister("get_tap_rd"); + inter_module_unregister("get_tap_change_rd"); + inter_module_unregister("set_dis_tap_rd"); + inter_module_unregister("get_dis_tap_rd"); + inter_module_unregister("set_tap_pwup_rd"); + inter_module_unregister("get_tap_pwup_rd"); +#endif + inter_module_unregister("set_bp_disc_rd"); + inter_module_unregister("get_bp_disc_rd"); + inter_module_unregister("get_bp_disc_change_rd"); + inter_module_unregister("set_bp_dis_disc_rd"); + inter_module_unregister("get_bp_dis_disc_rd"); + inter_module_unregister("set_bp_disc_pwup_rd"); + inter_module_unregister("get_bp_disc_pwup_rd"); + inter_module_unregister("set_wd_exp_mode_rd"); + inter_module_unregister("get_wd_exp_mode_rd"); + inter_module_unregister("set_wd_autoreset_rd"); + inter_module_unregister("get_wd_autoreset_rd"); + inter_module_unregister("get_bypass_info_rd"); + inter_module_unregister("bp_if_scan_rd"); + +#endif + + for (i = 0; i < device_num; i++) { + //unsigned long flags; +#ifdef BP_PROC_SUPPORT + bypass_proc_remove_dev_rd(&bpctl_dev_arr[i]); +#endif + remove_bypass_wd_auto(&bpctl_dev_arr[i]); + bpctl_dev_arr[i].reset_time=0; + remove_bypass_tpl_auto(&bpctl_dev_arr[i]); + } +#ifdef BP_PROC_SUPPORT + remove_proc_entry(BP_PROC_DIR, init_net.proc_net); +#endif + + + /* unmap all devices */ + for (i = 0; i < device_num; i++) { +#ifdef BP_SELF_TEST + if (bpctl_dev_arr[i].bp_tx_data) + kfree (bpctl_dev_arr[i].bp_tx_data); +#endif + iounmap ((void *)(bpctl_dev_arr[i].mem_map)); + } + + /* free all devices space */ + if (bpctl_dev_arr) + kfree (bpctl_dev_arr); + + + +/* +* Unregister the device +*/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) + ret = unregister_chrdev(major_num, DEVICE_NAME); +/* +* If there's an error, report it +*/ + if (ret < 0) + printk("Error in module_unregister_chrdev: %d\n", ret); +#else + unregister_chrdev(major_num, DEVICE_NAME); + +#endif +} + + +static int __init bprd_init_module(void) +{ + int ret; + + printk(KERN_INFO BP_MOD_DESCR" v"BP_MOD_VER"\n"); + + ret=v2_bypass_init_module(); + + return ret; +} + + +static void __exit bprd_exit_module(void) +{ +/* pci_unregister_driver(&bpvm_driver); */ + bypass_cleanup_module(); +#ifdef BPVM_KVM + unregister_netdev(netdev); + free_netdev(netdev); +#endif /* BPVM_KVM */ + +} + +module_exit(bprd_exit_module); +module_init(bprd_init_module); + +int is_bypass_rd(int ifindex){ + return(is_bypass_rd_fn(get_dev_idx_p(ifindex))); +} + +int set_bypass_rd (int ifindex, int bypass_mode){ + + return(set_bypass_rd_fn(get_dev_idx_p(ifindex),bypass_mode)); +} + + +int get_bypass_rd (int ifindex){ + + return(get_bypass_rd_fn(get_dev_idx_p(ifindex))); +} + +int get_wd_expire_rd (int ifindex){ + + return(get_wd_expire_rd_fn(get_dev_idx_p(ifindex))); +} + + +int get_bypass_change_rd(int ifindex){ + + return(get_bypass_change_rd_fn(get_dev_idx_p(ifindex))); +} + +int set_dis_bypass_rd(int ifindex, int dis_param){ + return(set_dis_bypass_rd_fn(get_dev_idx_p(ifindex),dis_param)); +} + +int get_dis_bypass_rd(int ifindex){ + + return(get_dis_bypass_rd_fn(get_dev_idx_p(ifindex))); +} + +int set_bypass_pwoff_rd (int ifindex, int bypass_mode){ + return(set_bypass_pwoff_rd_fn(get_dev_idx_p(ifindex),bypass_mode)); + +} + + +int get_bypass_pwoff_rd(int ifindex){ + return(get_bypass_pwoff_rd_fn(get_dev_idx_p(ifindex))); + +} + + +int set_bypass_pwup_rd(int ifindex, int bypass_mode){ + return(set_bypass_pwup_rd_fn(get_dev_idx_p(ifindex),bypass_mode)); + +} + +int get_bypass_pwup_rd(int ifindex){ + return(get_bypass_pwup_rd_fn(get_dev_idx_p(ifindex))); + +} + +int set_bypass_wd_rd(int if_index, int ms_timeout, int *ms_timeout_set){ + if ((is_bypass_rd_fn(get_dev_idx_p(if_index)))<=0) + return BP_NOT_CAP; + *ms_timeout_set= set_bypass_wd_rd_fn(get_dev_idx_p(if_index),ms_timeout); + return 0; +} + +int get_bypass_wd_rd(int ifindex, int *timeout){ + return(get_bypass_wd_rd_fn(get_dev_idx_p(ifindex),timeout)); + +} + +int get_wd_expire_time_rd(int ifindex, int *time_left){ + return(get_wd_expire_time_rd_fn(get_dev_idx_p(ifindex),time_left)); +} + +int reset_bypass_wd_timer_rd(int ifindex){ + return(reset_bypass_wd_timer_rd_fn(get_dev_idx_p(ifindex))); + +} + +int get_wd_set_caps_rd(int ifindex){ + return(get_wd_set_caps_rd_fn(get_dev_idx_p(ifindex))); + +} + +int set_std_nic_rd(int ifindex, int nic_mode){ + return(set_std_nic_rd_fn(get_dev_idx_p(ifindex),nic_mode)); + +} + +int get_std_nic_rd(int ifindex){ + return(get_std_nic_rd_fn(get_dev_idx_p(ifindex))); + +} +#if 0 +int set_tap_rd (int ifindex, int tap_mode){ + return(set_tap_rd_fn(get_dev_idx_p(ifindex),tap_mode)); + +} + +int get_tap_rd (int ifindex){ + return(get_tap_rd_fn(get_dev_idx_p(ifindex))); + +} + +int set_tap_pwup_rd(int ifindex, int tap_mode){ + return(set_tap_pwup_rd_fn(get_dev_idx_p(ifindex),tap_mode)); + +} + +int get_tap_pwup_rd(int ifindex){ + return(get_tap_pwup_rd_fn(get_dev_idx_p(ifindex))); + +} + +int get_tap_change_rd(int ifindex){ + return(get_tap_change_rd_fn(get_dev_idx_p(ifindex))); + +} + +int set_dis_tap_rd(int ifindex, int dis_param){ + return(set_dis_tap_rd_fn(get_dev_idx_p(ifindex),dis_param)); + +} + +int get_dis_tap_rd(int ifindex){ + return(get_dis_tap_rd_fn(get_dev_idx_p(ifindex))); + +} +#endif +int set_bp_disc_rd (int ifindex, int disc_mode){ + return(set_disc_rd_fn(get_dev_idx_p(ifindex),disc_mode)); + +} + +int get_bp_disc_rd (int ifindex){ + return(get_disc_rd_fn(get_dev_idx_p(ifindex))); + +} + +int set_bp_disc_pwup_rd(int ifindex, int disc_mode){ + return(set_disc_pwup_rd_fn(get_dev_idx_p(ifindex),disc_mode)); + +} + +int get_bp_disc_pwup_rd(int ifindex){ + return(get_disc_pwup_rd_fn(get_dev_idx_p(ifindex))); + +} + +int get_bp_disc_change_rd(int ifindex){ + return(get_disc_change_rd_fn(get_dev_idx_p(ifindex))); + +} + +int set_bp_dis_disc_rd(int ifindex, int dis_param){ + return(set_dis_disc_rd_fn(get_dev_idx_p(ifindex),dis_param)); + +} + +int get_bp_dis_disc_rd(int ifindex){ + return(get_dis_disc_rd_fn(get_dev_idx_p(ifindex))); + +} + +int get_wd_exp_mode_rd(int ifindex){ + return(get_wd_exp_mode_rd_fn(get_dev_idx_p(ifindex))); +} + +int set_wd_exp_mode_rd(int ifindex, int param){ + return(set_wd_exp_mode_rd_fn(get_dev_idx_p(ifindex),param)); + +} + +int set_tx_rd(int ifindex, int tx_state){ + return(set_tx_rd_fn(get_dev_idx_p(ifindex), tx_state)); + +} + +int set_tpl_rd(int ifindex, int tpl_state){ + return(set_tpl_rd_fn(get_dev_idx_p(ifindex), tpl_state)); + +} + +int set_bp_hw_reset_rd(int ifindex, int status){ + return(set_bp_hw_reset_rd_fn(get_dev_idx_p(ifindex), status)); + +} + + +int set_wd_autoreset_rd(int ifindex, int param){ + return(set_wd_autoreset_rd_fn(get_dev_idx_p(ifindex),param)); + +} + +int get_wd_autoreset_rd(int ifindex){ + return(get_wd_autoreset_rd_fn(get_dev_idx_p(ifindex))); + +} + + +int get_bypass_caps_rd(int ifindex){ + return(get_bypass_caps_rd_fn(get_dev_idx_p(ifindex))); +} + +int get_bypass_slave_rd(int ifindex){ + bpctl_dev_t *pbpctl_dev_out; + int ret=get_bypass_slave_rd_fn(get_dev_idx_p(ifindex), &pbpctl_dev_out); + if (ret==1) + return(pbpctl_dev_out->ifindex) ; + return -1; + +} + +int get_tx_rd(int ifindex){ + return(get_tx_rd_fn(get_dev_idx_p(ifindex))); + +} + +int get_tpl_rd(int ifindex){ + return(get_tpl_rd_fn(get_dev_idx_p(ifindex))); + +} + +int get_bp_hw_reset_rd(int ifindex){ + return(get_bp_hw_reset_rd_fn(get_dev_idx_p(ifindex))); + +} + + +int get_bypass_info_rd(int ifindex, struct bp_info *bp_info) { + return(get_bypass_info_rd_fn(get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver)); +} + +int bp_if_scan_rd(void) { + if_scan_init(); + return 0; +} + + +EXPORT_SYMBOL_NOVERS(is_bypass_rd); +EXPORT_SYMBOL_NOVERS(get_bypass_slave_rd); +EXPORT_SYMBOL_NOVERS(get_bypass_caps_rd); +EXPORT_SYMBOL_NOVERS(get_wd_set_caps_rd); +EXPORT_SYMBOL_NOVERS(set_bypass_rd); +EXPORT_SYMBOL_NOVERS(get_bypass_rd); +EXPORT_SYMBOL_NOVERS(get_bypass_change_rd); +EXPORT_SYMBOL_NOVERS(set_dis_bypass_rd); +EXPORT_SYMBOL_NOVERS(get_dis_bypass_rd); +EXPORT_SYMBOL_NOVERS(set_bypass_pwoff_rd); +EXPORT_SYMBOL_NOVERS(get_bypass_pwoff_rd); +EXPORT_SYMBOL_NOVERS(set_bypass_pwup_rd); +EXPORT_SYMBOL_NOVERS(get_bypass_pwup_rd); +EXPORT_SYMBOL_NOVERS(set_bypass_wd_rd); +EXPORT_SYMBOL_NOVERS(get_bypass_wd_rd); +EXPORT_SYMBOL_NOVERS(get_wd_expire_time_rd); +EXPORT_SYMBOL_NOVERS(reset_bypass_wd_timer_rd); +EXPORT_SYMBOL_NOVERS(set_std_nic_rd); +EXPORT_SYMBOL_NOVERS(get_std_nic_rd); +EXPORT_SYMBOL_NOVERS(set_tx_rd); +EXPORT_SYMBOL_NOVERS(get_tx_rd); +EXPORT_SYMBOL_NOVERS(set_tpl_rd); +EXPORT_SYMBOL_NOVERS(get_tpl_rd); +EXPORT_SYMBOL_NOVERS(set_bp_hw_reset_rd); +EXPORT_SYMBOL_NOVERS(get_bp_hw_reset_rd); +#if 0 +EXPORT_SYMBOL_NOVERS(set_tap_rd); +EXPORT_SYMBOL_NOVERS(get_tap_rd); +EXPORT_SYMBOL_NOVERS(get_tap_change_rd); +EXPORT_SYMBOL_NOVERS(set_dis_tap_rd); +EXPORT_SYMBOL_NOVERS(get_dis_tap_rd); +EXPORT_SYMBOL_NOVERS(set_tap_pwup_rd); +EXPORT_SYMBOL_NOVERS(get_tap_pwup_rd); +#endif +EXPORT_SYMBOL_NOVERS(set_wd_exp_mode_rd); +EXPORT_SYMBOL_NOVERS(get_wd_exp_mode_rd); +EXPORT_SYMBOL_NOVERS(set_wd_autoreset_rd); +EXPORT_SYMBOL_NOVERS(get_wd_autoreset_rd); +EXPORT_SYMBOL_NOVERS(set_bp_disc_rd); +EXPORT_SYMBOL_NOVERS(get_bp_disc_rd); +EXPORT_SYMBOL_NOVERS(get_bp_disc_change_rd); +EXPORT_SYMBOL_NOVERS(set_bp_dis_disc_rd); +EXPORT_SYMBOL_NOVERS(get_bp_dis_disc_rd); +EXPORT_SYMBOL_NOVERS(set_bp_disc_pwup_rd); +EXPORT_SYMBOL_NOVERS(get_bp_disc_pwup_rd); +EXPORT_SYMBOL_NOVERS(get_bypass_info_rd); +EXPORT_SYMBOL_NOVERS(bp_if_scan_rd); + +#ifdef BP_PROC_SUPPORT + +static struct proc_dir_entry *bp_procfs_dir; + +static struct proc_dir_entry * +proc_getdir(char *name, struct proc_dir_entry *proc_dir) { + struct proc_dir_entry *pde = proc_dir; +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) ) + + for (pde=pde->subdir; pde; pde = pde->next) { + if (pde->namelen && (strcmp(name, pde->name) == 0)) { + /* directory exists */ + break; + } + } + if (pde == (struct proc_dir_entry *) 0) +#endif + { + /* create the directory */ +#if (LINUX_VERSION_CODE > 0x20300) + pde = proc_mkdir(name, proc_dir); +#else + pde = create_proc_entry(name, S_IFDIR, proc_dir); +#endif + if (pde == (struct proc_dir_entry *) 0) { + + return(pde); + } + } + + return(pde); +} + +int bp_proc_create(void) +{ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ) + bp_procfs_dir = proc_getdir(BP_PROC_DIR, proc_net); +#else + bp_procfs_dir = proc_getdir(BP_PROC_DIR, init_net.proc_net); +#endif + + if (bp_procfs_dir == (struct proc_dir_entry *) 0) { + printk(KERN_DEBUG "Could not create procfs nicinfo directory %s\n", BP_PROC_DIR); + return -1; + } + return 0; +} + + + + + + #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) ) + +int +bypass_proc_create_entry_rd(struct pfs_unit_rd *pfs_unit_curr, + char* proc_name, + write_proc_t *write_proc, + read_proc_t *read_proc, + struct proc_dir_entry *parent_pfs, + void *data + ) +{ + strcpy(pfs_unit_curr->proc_name,proc_name); + pfs_unit_curr->proc_entry= create_proc_entry(pfs_unit_curr->proc_name, + S_IFREG|S_IRUSR|S_IWUSR| + S_IRGRP|S_IWGRP| + S_IROTH|S_IWOTH, parent_pfs); + if (pfs_unit_curr->proc_entry == 0) { + + return -1; + } + + pfs_unit_curr->proc_entry->read_proc = read_proc; + pfs_unit_curr->proc_entry->write_proc = write_proc; + pfs_unit_curr->proc_entry->data = data; + + return 0; + + +} + #endif + + + +int +get_bypass_info_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + int len=0; + + len += sprintf(page, "Name\t\t\t%s\n", pbp_device_block->name); + len += sprintf(page+len, "Firmware version\t0x%x\n", pbp_device_block->bp_fw_ver); + + *eof = 1; + return len; +} + + +int +get_bypass_slave_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * dev= (bpctl_dev_t *) data; + + int len=0; + + bpctl_dev_t *slave = get_status_port_rd_fn(dev); + if (!slave) + slave = dev; + if (slave) { + if (slave->ndev) + len = sprintf(page, "%s\n", slave->ndev->name); + else + len=sprintf(page, "fail\n"); + } + + *eof = 1; + return len; + +} + + + +int +get_bypass_caps_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_bypass_caps_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "-1\n"); + else + len=sprintf(page, "0x%x\n", ret); + *eof = 1; + return len; + + +} + + + +int +get_wd_set_caps_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_wd_set_caps_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "-1\n"); + else + len=sprintf(page, "0x%x\n", ret); + *eof = 1; + return len; +} + + + +int +set_bypass_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int bypass_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + + if (strcmp(kbuf,"on")==0) + bypass_param=1; + else if (strcmp(kbuf,"off")==0) + bypass_param=0; + + + set_bypass_rd_fn (pbp_device_block, bypass_param); + + return count; +} + + +int +set_tap_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int tap_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + if (strcmp(kbuf,"on")==0) + tap_param=1; + else if (strcmp(kbuf,"off")==0) + tap_param=0; + + set_tap_rd_fn(pbp_device_block, tap_param); + + return count; +} + + + +int +set_disc_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int tap_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + if (strcmp(kbuf,"on")==0) + tap_param=1; + else if (strcmp(kbuf,"off")==0) + tap_param=0; + + set_disc_rd_fn(pbp_device_block, tap_param); + + return count; +} + + + + +int +get_bypass_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_bypass_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==1) + len=sprintf(page, "on\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +int +get_tap_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_tap_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==1) + len=sprintf(page, "on\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + + *eof = 1; + return len; +} + + +int +get_disc_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_disc_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==1) + len=sprintf(page, "on\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + + *eof = 1; + return len; +} + +int +get_bypass_change_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_bypass_change_rd_fn (pbp_device_block); + if (ret==1) + len=sprintf(page, "on\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + else len=sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + + + + +int +get_tap_change_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_tap_change_rd_fn (pbp_device_block); + if (ret==1) + len=sprintf(page, "on\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + else len=sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + + + +int +get_disc_change_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_disc_change_rd_fn (pbp_device_block); + if (ret==1) + len=sprintf(page, "on\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + else len=sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + + + + + #define isdigit(c) (c >= '0' && c <= '9') +__inline static int atoi( char **s) +{ + int i = 0; + while (isdigit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + + +int +set_bypass_wd_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + unsigned int timeout=0; + char *timeout_ptr=kbuf; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + timeout_ptr=kbuf; + timeout=atoi(&timeout_ptr); + + set_bypass_wd_rd_fn(pbp_device_block, timeout) ; + + return count; +} + +int +get_bypass_wd_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0, timeout=0; + + ret=get_bypass_wd_rd_fn (pbp_device_block, &timeout); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (timeout==-1) + len=sprintf(page, "unknown\n"); + else if (timeout==0) + len=sprintf(page, "disable\n"); + else + len=sprintf(page, "%d\n", timeout); + + *eof = 1; + return len; +} + + + + +int +get_wd_expire_time_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0, timeout=0; + + ret=get_wd_expire_time_rd_fn (pbp_device_block, &timeout); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (timeout==-1) + len=sprintf(page, "expire\n"); + else if (timeout==0) + len=sprintf(page, "disable\n"); + + else + len=sprintf(page, "%d\n", timeout); + *eof = 1; + return len; +} + + + +int +get_tpl_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_tpl_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==1) + len=sprintf(page, "on\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + + *eof = 1; + return len; +} + + + + #ifdef PMC_FIX_FLAG +int +get_wait_at_pwup_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_bp_wait_at_pwup_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==1) + len=sprintf(page, "on\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + + *eof = 1; + return len; +} + + + +int +get_hw_reset_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_bp_hw_reset_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==1) + len=sprintf(page, "on\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + + *eof = 1; + return len; +} + + + + + #endif /*PMC_WAIT_FLAG*/ + + +int +reset_bypass_wd_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=reset_bypass_wd_timer_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==0) + len=sprintf(page, "disable\n"); + else if (ret==1) + len=sprintf(page, "success\n"); + + *eof = 1; + return len; +} + + + +int +set_dis_bypass_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int bypass_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + + if (strcmp(kbuf,"on")==0) + bypass_param=1; + else if (strcmp(kbuf,"off")==0) + bypass_param=0; + + set_dis_bypass_rd_fn (pbp_device_block, bypass_param); + + return count; +} + + + +int +set_dis_tap_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int tap_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + + if (strcmp(kbuf,"on")==0) + tap_param=1; + else if (strcmp(kbuf,"off")==0) + tap_param=0; + + set_dis_tap_rd_fn (pbp_device_block, tap_param); + + return count; +} + + + +int +set_dis_disc_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int tap_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + + if (strcmp(kbuf,"on")==0) + tap_param=1; + else if (strcmp(kbuf,"off")==0) + tap_param=0; + + set_dis_disc_rd_fn (pbp_device_block, tap_param); + + return count; +} + + + + +int +get_dis_bypass_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_dis_bypass_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + else + len=sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_dis_tap_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_dis_tap_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + else + len=sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_dis_disc_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_dis_disc_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + else + len=sprintf(page, "on\n"); + + *eof = 1; + return len; +} + + +int +set_bypass_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int bypass_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + if (strcmp(kbuf,"on")==0) + bypass_param=1; + else if (strcmp(kbuf,"off")==0) + bypass_param=0; + + set_bypass_pwup_rd_fn (pbp_device_block, bypass_param); + + return count; +} + + +int +set_bypass_pwoff_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int bypass_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + if (strcmp(kbuf,"on")==0) + bypass_param=1; + else if (strcmp(kbuf,"off")==0) + bypass_param=0; + + set_bypass_pwoff_rd_fn (pbp_device_block, bypass_param); + + return count; +} + + + + +int +set_tap_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int tap_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + if (strcmp(kbuf,"on")==0) + tap_param=1; + else if (strcmp(kbuf,"off")==0) + tap_param=0; + + set_tap_pwup_rd_fn (pbp_device_block, tap_param); + + return count; +} + + + +int +set_disc_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int tap_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + if (strcmp(kbuf,"on")==0) + tap_param=1; + else if (strcmp(kbuf,"off")==0) + tap_param=0; + + set_disc_pwup_rd_fn (pbp_device_block, tap_param); + + return count; +} + + + +int +get_bypass_pwup_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_bypass_pwup_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + else + len=sprintf(page, "on\n"); + + *eof = 1; + return len; +} + + + +int +get_bypass_pwoff_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_bypass_pwoff_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + else + len=sprintf(page, "on\n"); + + *eof = 1; + return len; +} + + +int +get_tap_pwup_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_tap_pwup_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + else + len=sprintf(page, "on\n"); + + *eof = 1; + return len; +} + +int +get_disc_pwup_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_disc_pwup_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + else + len=sprintf(page, "on\n"); + + *eof = 1; + return len; +} + + + +int +set_std_nic_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int bypass_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + + if (strcmp(kbuf,"on")==0) + bypass_param=1; + else if (strcmp(kbuf,"off")==0) + bypass_param=0; + + set_std_nic_rd_fn (pbp_device_block, bypass_param); + + return count; +} + + +int +get_std_nic_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_std_nic_rd_fn (pbp_device_block); + if (ret==BP_NOT_CAP) + len=sprintf(page, "fail\n"); + else if (ret==0) + len=sprintf(page, "off\n"); + else + len=sprintf(page, "on\n"); + + *eof = 1; + return len; +} + + + +int +get_wd_exp_mode_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_wd_exp_mode_rd_fn (pbp_device_block); + if (ret==1) + len=sprintf(page, "tap\n"); + else if (ret==0) + len=sprintf(page, "bypass\n"); + else if (ret==2) + len=sprintf(page, "disc\n"); + + else len=sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + +int +set_wd_exp_mode_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int bypass_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + + if (strcmp(kbuf,"tap")==0) + bypass_param=1; + else if (strcmp(kbuf,"bypass")==0) + bypass_param=0; + else if (strcmp(kbuf,"disc")==0) + bypass_param=2; + + set_wd_exp_mode_rd_fn(pbp_device_block, bypass_param); + + return count; +} + + + + + +int +get_wd_autoreset_pfs (char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int len=0, ret=0; + + ret=get_wd_autoreset_rd_fn (pbp_device_block); + if (ret>=0) + len=sprintf(page, "%d\n",ret); + else len=sprintf(page, "fail\n"); + + *eof = 1; + return len; +} + + +int +set_wd_autoreset_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + u32 timeout=0; + char *timeout_ptr=kbuf; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + timeout_ptr=kbuf; + timeout=atoi(&timeout_ptr); + + set_wd_autoreset_rd_fn(pbp_device_block, timeout) ; + + return count; +} + + +int +set_tpl_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int tpl_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + if (strcmp(kbuf,"on")==0) + tpl_param=1; + else if (strcmp(kbuf,"off")==0) + tpl_param=0; + + set_tpl_rd_fn(pbp_device_block, tpl_param); + + return count; +} + #ifdef PMC_FIX_FLAG +int +set_wait_at_pwup_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int tpl_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + if (strcmp(kbuf,"on")==0) + tpl_param=1; + else if (strcmp(kbuf,"off")==0) + tpl_param=0; + + set_bp_wait_at_pwup_rd_fn(pbp_device_block, tpl_param); + + return count; +} + +int +set_hw_reset_pfs(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + + char kbuf[256]; + bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data; + + int tpl_param=0, length=0; + + if (count>(sizeof(kbuf)-1)) + return -1; + + if (copy_from_user(&kbuf,buffer,count)) { + return -1; + } + + kbuf[count]='\0'; + length=strlen(kbuf); + if (kbuf[length-1]=='\n') + kbuf[--length]='\0'; + + if (strcmp(kbuf,"on")==0) + tpl_param=1; + else if (strcmp(kbuf,"off")==0) + tpl_param=0; + + set_bp_hw_reset_rd_fn(pbp_device_block, tpl_param); + + return count; +} + + #endif /*PMC_FIX_FLAG*/ + #if ( LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0) ) + +static int user_on_off(const void __user *buffer, size_t count) +{ + + char kbuf[256]; + int length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) + return -1; + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "on") == 0) + return 1; + if (strcmp(kbuf, "off") == 0) + return 0; + return 0; +} + + + #define RO_FOPS(name) \ +static int name##_open(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, show_##name, PDE_DATA(inode));\ +} \ +static const struct file_operations name##_ops = { \ + .open = name##_open, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ +}; + + #define RW_FOPS(name) \ +static int name##_open(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, show_##name, PDE_DATA(inode));\ +} \ +static const struct file_operations name##_ops = { \ + .open = name##_open, \ + .read = seq_read, \ + .write = name##_write, \ + .llseek = seq_lseek, \ + .release = single_release, \ +}; + +static int show_bypass_info(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + + seq_printf(m, "Name\t\t\t%s\n", dev->name); + seq_printf(m, "Firmware version\t0x%x\n", dev->bp_fw_ver); + return 0; +} +RO_FOPS(bypass_info) + +static int show_bypass_slave(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + bpctl_dev_t *slave = get_status_port_rd_fn(dev); + if (!slave) + slave = dev; + if (!slave) + seq_printf(m, "fail\n"); + else if (slave->ndev) + seq_printf(m, "%s\n", slave->ndev->name); + return 0; +} +RO_FOPS(bypass_slave) + +static int show_bypass_caps(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_bypass_caps_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "-1\n"); + else + seq_printf(m, "0x%x\n", ret); + return 0; +} +RO_FOPS(bypass_caps) + +static ssize_t std_nic_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int bypass_param = user_on_off(buffer, count); + if (bypass_param < 0) + return -EINVAL; + + set_std_nic_rd_fn(PDE_DATA(file_inode(file)), bypass_param); + return count; +} +static int show_std_nic(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_std_nic_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "on\n"); + return 0; +} +RW_FOPS(std_nic) + + +static ssize_t bypass_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int bypass_param = user_on_off(buffer, count); + if (bypass_param < 0) + return -1; + + set_bypass_rd_fn(PDE_DATA(file_inode(file)), bypass_param); + return count; +} +static int show_bypass(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_bypass_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 1) + seq_printf(m, "on\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + return 0; +} +RW_FOPS(bypass) + +static ssize_t tap_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) + return -1; + + set_tap_rd_fn(PDE_DATA(file_inode(file)), tap_param); + return count; +} +static int show_tap(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_tap_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 1) + seq_printf(m, "on\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + return 0; +} +RW_FOPS(tap) + + +static ssize_t disc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) + return -1; + + set_disc_rd_fn(PDE_DATA(file_inode(file)), tap_param); + return count; +} +static int show_disc(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_disc_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 1) + seq_printf(m, "on\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + return 0; +} +RW_FOPS(disc) + +static int show_bypass_change(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_bypass_change_rd_fn(dev); + if (ret == 1) + seq_printf(m, "on\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "fail\n"); + return 0; +} +RO_FOPS(bypass_change) + +static int show_tap_change(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_tap_change_rd_fn(dev); + if (ret == 1) + seq_printf(m, "on\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "fail\n"); + return 0; +} +RO_FOPS(tap_change) + + + +static int show_disc_change(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_disc_change_rd_fn(dev); + if (ret == 1) + seq_printf(m, "on\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "fail\n"); + return 0; +} +RO_FOPS(disc_change) + +static int show_tpl(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_tpl_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 1) + seq_printf(m, "on\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + return 0; +} +static ssize_t tpl_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + bpctl_dev_t *dev = PDE_DATA(file_inode(file)); + int tpl_param = user_on_off(buffer, count); + if (tpl_param < 0) + return -1; + + set_tpl_rd_fn(dev, tpl_param); + return count; +} + +RW_FOPS(tpl) + +static ssize_t wait_at_pwup_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + bpctl_dev_t *dev = PDE_DATA(file_inode(file)); + int tpl_param = user_on_off(buffer, count); + if (tpl_param < 0) + return -1; + + set_bp_wait_at_pwup_rd_fn(dev, tpl_param); + return count; +} +static int show_wait_at_pwup(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_bp_wait_at_pwup_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 1) + seq_printf(m, "on\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + return 0; +} +RW_FOPS(wait_at_pwup) + +static ssize_t hw_reset_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + bpctl_dev_t *dev = PDE_DATA(file_inode(file)); + int tpl_param = user_on_off(buffer, count); + if (tpl_param < 0) + return -1; + + set_bp_hw_reset_rd_fn(dev, tpl_param); + return count; +} + + +static int show_hw_reset(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_bp_hw_reset_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 1) + seq_printf(m, "on\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + return 0; +} +RW_FOPS(hw_reset) + +static ssize_t dis_bypass_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int bypass_param = user_on_off(buffer, count); + if (bypass_param < 0) + return -EINVAL; + + set_dis_bypass_rd_fn(PDE_DATA(file_inode(file)), bypass_param); + return count; +} +static int show_dis_bypass(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_dis_bypass_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "on\n"); + return 0; +} +RW_FOPS(dis_bypass) + +static ssize_t dis_tap_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) + return -EINVAL; + + set_dis_tap_rd_fn(PDE_DATA(file_inode(file)), tap_param); + return count; +} + +static int show_dis_tap(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_dis_tap_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "on\n"); + return 0; +} +RW_FOPS(dis_tap) + +static ssize_t dis_disc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) + return -EINVAL; + + set_dis_disc_rd_fn(PDE_DATA(file_inode(file)), tap_param); + return count; +} +static int show_dis_disc(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_dis_disc_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "on\n"); + return 0; +} +RW_FOPS(dis_disc) + +static ssize_t bypass_pwup_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int bypass_param = user_on_off(buffer, count); + if (bypass_param < 0) + return -EINVAL; + + set_bypass_pwup_rd_fn(PDE_DATA(file_inode(file)), bypass_param); + return count; +} +static int show_bypass_pwup(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_bypass_pwup_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "on\n"); + return 0; +} +RW_FOPS(bypass_pwup) + +static ssize_t bypass_pwoff_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int bypass_param = user_on_off(buffer, count); + if (bypass_param < 0) + return -EINVAL; + + set_bypass_pwoff_rd_fn(PDE_DATA(file_inode(file)), bypass_param); + return count; +} +static int show_bypass_pwoff(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_bypass_pwoff_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "on\n"); + return 0; +} +RW_FOPS(bypass_pwoff) + +static ssize_t tap_pwup_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) + return -EINVAL; + + set_tap_pwup_rd_fn(PDE_DATA(file_inode(file)), tap_param); + return count; +} +static int show_tap_pwup(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_tap_pwup_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "on\n"); + return 0; +} +RW_FOPS(tap_pwup) + +static ssize_t disc_pwup_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int tap_param = user_on_off(buffer, count); + if (tap_param < 0) + return -EINVAL; + + set_disc_pwup_rd_fn(PDE_DATA(file_inode(file)), tap_param); + return count; +} +static int show_disc_pwup(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_disc_pwup_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 0) + seq_printf(m, "off\n"); + else + seq_printf(m, "on\n"); + return 0; +} +RW_FOPS(disc_pwup) + + +static int show_reset_bypass_wd(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = reset_bypass_wd_timer_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (ret == 0) + seq_printf(m, "disable\n"); + else if (ret == 1) + seq_printf(m, "success\n"); + return 0; +} +RO_FOPS(reset_bypass_wd) + + + + + + +static ssize_t bypass_wd_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + bpctl_dev_t *dev = PDE_DATA(file_inode(file)); + int timeout; + int ret = kstrtoint_from_user(buffer, count, 10, &timeout); + if (ret) + return ret; + set_bypass_wd_rd_fn(dev, timeout); + return count; +} + +static int show_bypass_wd(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = 0, timeout = 0; + + ret = get_bypass_wd_rd_fn(dev, &timeout); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (timeout == -1) + seq_printf(m, "unknown\n"); + else if (timeout == 0) + seq_printf(m, "disable\n"); + else + seq_printf(m, "%d\n", timeout); + return 0; +} +RW_FOPS(bypass_wd) + +static int show_wd_expire_time(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = 0, timeout = 0; + ret = get_wd_expire_time_rd_fn(dev, &timeout); + if (ret == BP_NOT_CAP) + seq_printf(m, "fail\n"); + else if (timeout == -1) + seq_printf(m, "expire\n"); + else if (timeout == 0) + seq_printf(m, "disable\n"); + else + seq_printf(m, "%d\n", timeout); + return 0; +} +RO_FOPS(wd_expire_time) + + + +static ssize_t wd_exp_mode_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + char kbuf[256]; + int bypass_param = 0, length = 0; + + if (count > (sizeof(kbuf) - 1)) + return -1; + + if (copy_from_user(&kbuf, buffer, count)) + return -1; + + kbuf[count] = '\0'; + length = strlen(kbuf); + if (kbuf[length - 1] == '\n') + kbuf[--length] = '\0'; + + if (strcmp(kbuf, "tap") == 0) + bypass_param = 1; + else if (strcmp(kbuf, "bypass") == 0) + bypass_param = 0; + else if (strcmp(kbuf, "disc") == 0) + bypass_param = 2; + + set_wd_exp_mode_rd_fn(PDE_DATA(file_inode(file)), bypass_param); + + return count; +} +static int show_wd_exp_mode(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_wd_exp_mode_rd_fn(dev); + if (ret == 1) + seq_printf(m, "tap\n"); + else if (ret == 0) + seq_printf(m, "bypass\n"); + else if (ret == 2) + seq_printf(m, "disc\n"); + else + seq_printf(m, "fail\n"); + return 0; +} +RW_FOPS(wd_exp_mode) + +static int show_wd_set_caps(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_wd_set_caps_rd_fn(dev); + if (ret == BP_NOT_CAP) + seq_printf(m, "-1\n"); + else + seq_printf(m, "0x%x\n", ret); + return 0; +} +RO_FOPS(wd_set_caps) + + + +static ssize_t wd_autoreset_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) +{ + int timeout; + int ret = kstrtoint_from_user(buffer, count, 10, &timeout); + if (ret) + return ret; + set_wd_autoreset_rd_fn(PDE_DATA(file_inode(file)), timeout); + return count; +} +static int show_wd_autoreset(struct seq_file *m, void *v) +{ + bpctl_dev_t *dev = m->private; + int ret = get_wd_autoreset_rd_fn(dev); + if (ret >= 0) + seq_printf(m, "%d\n", ret); + else + seq_printf(m, "fail\n"); + return 0; +} +RW_FOPS(wd_autoreset) + #endif + + + + + #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) ) +int bypass_proc_create_dev_rd(bpctl_dev_t * pbp_device_block){ + struct bypass_pfs_rd *current_pfs = &(pbp_device_block->bypass_pfs_set); + static struct proc_dir_entry *procfs_dir=NULL; + int ret=0; + + + if (!pbp_device_block->ndev) + return -1; + + sprintf(current_pfs->dir_name,"bypass_%s",pbp_device_block->ndev->name); + + if (!bp_procfs_dir) + return -1; + + /* create device proc dir */ + procfs_dir = proc_getdir(current_pfs->dir_name,bp_procfs_dir); + if (procfs_dir == 0) { + printk(KERN_DEBUG "Could not create procfs directory %s\n", + current_pfs->dir_name); + return -1; + } + current_pfs->bypass_entry= procfs_dir; + + if (bypass_proc_create_entry_rd(&(current_pfs->bypass_info), + BYPASS_INFO_ENTRY_SD, + NULL, /* write */ + get_bypass_info_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + if (pbp_device_block->bp_caps & SW_CTL_CAP) { + + + /* Create set param proc's */ + if (bypass_proc_create_entry_rd(&(current_pfs->bypass_slave), + BYPASS_SLAVE_ENTRY_SD, + NULL, /* write */ + get_bypass_slave_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + + if (bypass_proc_create_entry_rd(&(current_pfs->bypass_caps), + BYPASS_CAPS_ENTRY_SD, + NULL, /* write */ + get_bypass_caps_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + if (bypass_proc_create_entry_rd(&(current_pfs->wd_set_caps), + WD_SET_CAPS_ENTRY_SD, + NULL, /* write */ + get_wd_set_caps_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + if (bypass_proc_create_entry_rd(&(current_pfs->bypass_wd), + BYPASS_WD_ENTRY_SD, + set_bypass_wd_pfs, /* write */ + get_bypass_wd_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + + if (bypass_proc_create_entry_rd(&(current_pfs->wd_expire_time), + WD_EXPIRE_TIME_ENTRY_SD, + NULL, /* write */ + get_wd_expire_time_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + if (bypass_proc_create_entry_rd(&(current_pfs->reset_bypass_wd), + RESET_BYPASS_WD_ENTRY_SD, + NULL, /* write */ + reset_bypass_wd_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + if (bypass_proc_create_entry_rd(&(current_pfs->std_nic), + STD_NIC_ENTRY_SD, + set_std_nic_pfs, /* write */ + get_std_nic_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + + if (pbp_device_block->bp_caps & BP_CAP) { + if (bypass_proc_create_entry_rd(&(current_pfs->bypass), + BYPASS_ENTRY_SD, + set_bypass_pfs, /* write */ + get_bypass_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + if (bypass_proc_create_entry_rd(&(current_pfs->dis_bypass), + DIS_BYPASS_ENTRY_SD, + set_dis_bypass_pfs, /* write */ + get_dis_bypass_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + if (bypass_proc_create_entry_rd(&(current_pfs->bypass_pwup), + BYPASS_PWUP_ENTRY_SD, + set_bypass_pwup_pfs, /* write */ + get_bypass_pwup_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + if (bypass_proc_create_entry_rd(&(current_pfs->bypass_pwoff), + BYPASS_PWOFF_ENTRY_SD, + set_bypass_pwoff_pfs, /* write */ + get_bypass_pwoff_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + + if (bypass_proc_create_entry_rd(&(current_pfs->bypass_change), + BYPASS_CHANGE_ENTRY_SD, + NULL, /* write */ + get_bypass_change_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + } + + if (pbp_device_block->bp_caps & TAP_CAP) { + + if (bypass_proc_create_entry_rd(&(current_pfs->tap), + TAP_ENTRY_SD, + set_tap_pfs, /* write */ + get_tap_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + if (bypass_proc_create_entry_rd(&(current_pfs->dis_tap), + DIS_TAP_ENTRY_SD, + set_dis_tap_pfs, /* write */ + get_dis_tap_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + if (bypass_proc_create_entry_rd(&(current_pfs->tap_pwup), + TAP_PWUP_ENTRY_SD, + set_tap_pwup_pfs, /* write */ + get_tap_pwup_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + if (bypass_proc_create_entry_rd(&(current_pfs->tap_change), + TAP_CHANGE_ENTRY_SD, + NULL, /* write */ + get_tap_change_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + } + if (pbp_device_block->bp_caps & DISC_CAP) { + + if (bypass_proc_create_entry_rd(&(current_pfs->tap), + DISC_ENTRY_SD, + set_disc_pfs, /* write */ + get_disc_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; +#if 1 + + if (bypass_proc_create_entry_rd(&(current_pfs->dis_tap), + DIS_DISC_ENTRY_SD, + set_dis_disc_pfs, /* write */ + get_dis_disc_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; +#endif + + if (bypass_proc_create_entry_rd(&(current_pfs->tap_pwup), + DISC_PWUP_ENTRY_SD, + set_disc_pwup_pfs, /* write */ + get_disc_pwup_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + if (bypass_proc_create_entry_rd(&(current_pfs->tap_change), + DISC_CHANGE_ENTRY_SD, + NULL, /* write */ + get_disc_change_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + } + + + if (bypass_proc_create_entry_rd(&(current_pfs->wd_exp_mode), + WD_EXP_MODE_ENTRY_SD, + set_wd_exp_mode_pfs, /* write */ + get_wd_exp_mode_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + + if (bypass_proc_create_entry_rd(&(current_pfs->wd_autoreset), + WD_AUTORESET_ENTRY_SD, + set_wd_autoreset_pfs, /* write */ + get_wd_autoreset_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + if (bypass_proc_create_entry_rd(&(current_pfs->tpl), + TPL_ENTRY_SD, + set_tpl_pfs, /* write */ + get_tpl_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; +#ifdef PMC_FIX_FLAG + if (bypass_proc_create_entry_rd(&(current_pfs->tpl), + WAIT_AT_PWUP_ENTRY_SD, + set_wait_at_pwup_pfs, /* write */ + get_wait_at_pwup_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + if (bypass_proc_create_entry_rd(&(current_pfs->tpl), + HW_RESET_ENTRY_SD, + set_hw_reset_pfs, /* write */ + get_hw_reset_pfs, /* read */ + procfs_dir, + pbp_device_block)) + ret= -1; + +#endif + + } + if (ret<0) + printk(KERN_DEBUG "Create proc entry failed\n"); + + return ret; +} + #else + +static int procfs_add(char *proc_name, const struct file_operations *fops, + bpctl_dev_t *dev) +{ + struct bypass_pfs_rd *pfs = &dev->bypass_pfs_set; + if (!proc_create_data(proc_name, 0644, pfs->bypass_entry, fops, dev)) + return -1; + return 0; +} + +int bypass_proc_create_dev_rd(bpctl_dev_t *pbp_device_block) +{ + struct bypass_pfs_rd *current_pfs = &(pbp_device_block->bypass_pfs_set); + static struct proc_dir_entry *procfs_dir = NULL; + int ret = 0; + + if (!pbp_device_block->ndev) + return -1; + sprintf(current_pfs->dir_name, "bypass_%s", + pbp_device_block->ndev->name); + + if (!bp_procfs_dir) + return -1; + + /* create device proc dir */ + procfs_dir = proc_mkdir(current_pfs->dir_name, bp_procfs_dir); + if (!procfs_dir) { + printk(KERN_DEBUG "Could not create procfs directory %s\n", + current_pfs->dir_name); + return -1; + } + current_pfs->bypass_entry = procfs_dir; + +#define ENTRY(x) ret |= procfs_add(#x, &x##_ops, pbp_device_block) + ENTRY(bypass_info); + if (pbp_device_block->bp_caps & SW_CTL_CAP) { + /* Create set param proc's */ + ENTRY(bypass_slave); + ENTRY(bypass_caps); + ENTRY(wd_set_caps); + ENTRY(bypass_wd); + ENTRY(wd_expire_time); + ENTRY(reset_bypass_wd); + ENTRY(std_nic); + if (pbp_device_block->bp_caps & BP_CAP) { + ENTRY(bypass); + ENTRY(dis_bypass); + ENTRY(bypass_pwup); + ENTRY(bypass_pwoff); + ENTRY(bypass_change); + } + if (pbp_device_block->bp_caps & TAP_CAP) { + ENTRY(tap); + ENTRY(dis_tap); + ENTRY(tap_pwup); + ENTRY(tap_change); + } + if (pbp_device_block->bp_caps & DISC_CAP) { + ENTRY(disc); + ENTRY(dis_disc); + ENTRY(disc_pwup); + ENTRY(disc_change); + } + + ENTRY(wd_exp_mode); + ENTRY(wd_autoreset); + ENTRY(tpl); +#ifdef PMC_FIX_FLAG + ENTRY(wait_at_pwup); + ENTRY(hw_reset); +#endif + } +#undef ENTRY + if (ret < 0) + printk(KERN_DEBUG "Create proc entry failed\n"); + + return ret; +} + + #endif + #if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) ) +int bypass_proc_remove_dev_rd(bpctl_dev_t * pbp_device_block){ + + struct bypass_pfs_rd *current_pfs = &pbp_device_block->bypass_pfs_set; + struct proc_dir_entry *pde = current_pfs->bypass_entry, *pde_curr=NULL; + char name[256]; + if (!pde) + return 0; + for (pde=pde->subdir; pde; ) { + strcpy(name,pde->name); + pde_curr=pde; + pde=pde->next; + remove_proc_entry(name,current_pfs->bypass_entry); + } + if (!pde) + remove_proc_entry(current_pfs->dir_name,bp_procfs_dir); + + current_pfs->bypass_entry=NULL; + + + return 0; +} + #else + + +int bypass_proc_remove_dev_rd(bpctl_dev_t *pbp_device_block) +{ + + struct bypass_pfs_rd *current_pfs = &pbp_device_block->bypass_pfs_set; + remove_proc_subtree(current_pfs->dir_name, bp_procfs_dir); + current_pfs->bypass_entry = NULL; + return 0; +} + #endif + + +#endif //BP_PROC_SUPPORT + + diff --git a/bprd_mod.h b/bprd_mod.h new file mode 100755 index 0000000..03a1f72 --- /dev/null +++ b/bprd_mod.h @@ -0,0 +1,132 @@ +/************************************************************************** + +Copyright (c) 2006-2013, Silicom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Silicom nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#ifndef BPRD_MOD_H +#define BPRD_MOD_H +#include "bits.h" + +#ifndef KERNEL_VERSION + #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) ) + #define msleep(x) do { if(in_interrupt()) { \ + /* Don't mdelay in interrupt context! */ \ + BUG(); \ + } else { \ + set_current_state(TASK_UNINTERRUPTIBLE); \ + schedule_timeout((x * HZ)/1000 + 2); \ + } } while(0) +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) + #define EXPORT_SYMBOL_NOVERS EXPORT_SYMBOL +#endif + +#define BP_PROC_DIR "bypass" + + +#define PULSE_SET_ENTRY_RD "pulse_set" +#define ZERO_SET_ENTRY_RD "zero_set" +#define PULSE_GET1_ENTRY_RD "pulse_get1" +#define PULSE_GET2_ENTRY_RD "pulse_get2" + +#define CMND_ON_ENTRY_RD "cmnd_on" +#define CMND_OFF_ENTRY_RD "cmnd_off" +#define RESET_CONT_ENTRY_RD "reset_cont" + +/*COMMANDS*/ +#define BYPASS_INFO_ENTRY_RD "bypass_info" + +#define BYPASS_SLAVE_ENTRY_RD "bypass_slave" +#define BYPASS_CAPS_ENTRY_RD "bypass_caps" +#define WD_SET_CAPS_ENTRY_RD "wd_set_caps" +#define BYPASS_ENTRY_RD "bypass" +#define BYPASS_CHANGE_ENTRY_RD "bypass_change" +#define BYPASS_WD_ENTRY_RD "bypass_wd" +#define WD_EXPIRE_TIME_ENTRY_RD "wd_expire_time" +#define RESET_BYPASS_WD_ENTRY_RD "reset_bypass_wd" +#define DIS_BYPASS_ENTRY_RD "dis_bypass" +#define BYPASS_PWUP_ENTRY_RD "bypass_pwup" +#define BYPASS_PWOFF_ENTRY_RD "bypass_pwoff" +#define STD_NIC_ENTRY_RD "std_nic" +#define STD_NIC_ENTRY_RD "std_nic" +#define TAP_ENTRY_RD "tap" +#define TAP_CHANGE_ENTRY_RD "tap_change" +#define DIS_TAP_ENTRY_RD "dis_tap" +#define TAP_PWUP_ENTRY_RD "tap_pwup" +#define TWO_PORT_LINK_ENTRY_RD "two_port_link" +#define WD_EXP_MODE_ENTRY_RD "wd_exp_mode" +#define WD_AUTORESET_ENTRY_RD "wd_autoreset" +#define TPL_ENTRY_RD "tpl" +#define WAIT_AT_PWUP_ENTRY_RD "wait_at_pwup" +#define HW_RESET_ENTRY_RD "hw_reset" +#define DISC_ENTRY_RD "disc" +#define DISC_CHANGE_ENTRY_RD "disc_change" +#define DIS_DISC_ENTRY_RD "dis_disc" +#define DISC_PWUP_ENTRY_RD "disc_pwup" + + + + + +#ifndef jiffies_to_msecs + #define jiffies_to_msecs(x) _kc_jiffies_to_msecs(x) +static inline unsigned int jiffies_to_msecs(const unsigned long j) +{ +#if HZ <= 1000 && !(1000 % HZ) + return(1000 / HZ) * j; +#elif HZ > 1000 && !(HZ % 1000) + return(j + (HZ / 1000) - 1)/(HZ / 1000); +#else + return(j * 1000) / HZ; +#endif +} +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) + + #define pci_get_class pci_find_class + #define pci_get_subsys pci_find_subsys + #define pci_get_device pci_find_device + +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)) + #define MODULE_VERSION(_version) +#endif + + + +#endif diff --git a/bprd_util.c b/bprd_util.c new file mode 100755 index 0000000..603e7eb --- /dev/null +++ b/bprd_util.c @@ -0,0 +1,3541 @@ +/************************************************************************** + +Copyright (c) 2006-2013, Silicom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Silicom nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#include /* open */ +#include /* exit */ +#include /* ioctl */ +#include +#include +#include +#include +#include "bprd_ioctl.h" +#include "bprd_util.h" + +static void bp_usage(void){ + printf("Usage: "PROG_NAME" [parameters]\n"); + printf(" "PROG_NAME" \n"); + printf(" - interface name, for example, eth0, or all for all Bypass-SD/TAP-SD Control devices\n"); + printf(" - bypass control command (see Commands List).\n"); + printf("[parameters] - set_bypass_wd command:\n"); + printf(" WDT timeout interval, msec (0 for disabling WDT).\n"); + printf(" set_bypass/set_bypass_pwoff/set_bypass_pwup/set_dis_bypass commands:\n"); + printf(" on/off for enable/disable Bypass\n"); + printf(" set_std_nic command:\n"); + printf(" on/off for enable/disable Standard NIC mode\n"); + printf(" set_tx command:\n"); + printf(" on/off for enable/disable transmit\n"); + printf(" set_tpl command:\n"); + printf(" on/off for enable/disable TPL\n"); +#ifdef PMC_FIX_FLAG + printf(" set_wait_at_pwup command:\n"); + printf(" on/off for enable/disable wait_at_pwup\n"); +#endif +#ifdef BP_DBI_FLAG + printf(" set_force_link_on command:\n"); + printf(" on/off for enable/disable force_link_on\n"); +#endif + printf(" set_hw_reset command:\n"); + printf(" on/off for enable/disable hw_reset\n"); + printf(" set_tap/set_tap_pwup/set_dis_tap commands:\n"); + printf(" on/off for enable/disable TAP\n"); + printf(" set_disc/set_disc_pwup/set_dis_disc commands:\n"); + printf(" on/off for enable/disable Disc\n"); + printf(" set_wd_exp_mode command:\n"); + printf(" bypass/tap/disc for bypass/tap/disc mode\n"); + printf(" set_wd_autoreset command:\n"); + printf(" WDT autoreset interval, msec (0 for disabling WDT autoreset).\n"); + printf("if_scan - refresh the list of network interfaces..\n"); + + printf("info - print Program Information.\n"); + printf("help - print this message.\n"); + printf(" Commands List:\n"); + printf("is_bypass - check if device is a Bypass/TAP controlling device\n"); + printf("get_bypass_slave - get the second port participate in the Bypass/TAP pair\n"); + printf("get_bypass_caps - obtain Bypass/TAP capabilities information\n"); + printf("get_wd_set_caps - obtain watchdog timer settings capabilities\n"); + printf("get_bypass_info - get bypass/TAP info\n"); + printf("set_bypass - set Bypass mode state\n"); + printf("get_bypass - get Bypass mode state\n"); + printf("get_bypass_change - get change of Bypass mode state from last status check\n"); + printf("set_dis_bypass - set Disable Bypass mode\n"); + printf("get_dis_bypass - get Disable Bypass mode state\n"); + printf("set_bypass_pwoff - set Bypass mode at power-off state\n"); + printf("get_bypass_pwoff - get Bypass mode at power-off state\n"); + printf("set_bypass_pwup - set Bypass mode at power-up state\n"); + printf("get_bypass_pwup - get Bypass mode at power-up state\n"); + printf("set_std_nic - set Standard NIC mode of operation\n"); + printf("get_std_nic - get Standard NIC mode settings\n"); + printf("set_bypass_wd - set watchdog state\n"); + printf("get_bypass_wd - get watchdog state\n"); + printf("get_wd_time_expire - get watchdog expired time\n"); + printf("get_wd_expire - get watchdog expired status\n"); + printf("reset_bypass_wd - reset watchdog timer\n"); + printf("set_tx - set transmit enable / disable\n"); + printf("get_tx - get transmitter state (enabled / disabled)\n"); + printf("set_tpl - set TPL enable / disable\n"); + printf("get_tpl - get TPL state (enabled / disabled)\n"); +#ifdef PMC_FIX_FLAG + printf("set_wait_at_pwup - set wait_at_pwup enable / disable\n"); + printf("get_wait_at_pwup - get wait_at_pwup (enabled / disabled)\n"); +#endif +#ifdef BP_DBI_FLAG + printf("set_force_link_on - set force_link_on enable / disable\n"); + printf("get_force_link_on - get force_link_on (enabled / disabled)\n"); +#endif + printf("set_hw_reset - set hw_reset enable / disable\n"); + printf("get_hw_reset - get hw_reset (enabled / disabled)\n"); + printf("set_tap - set TAP mode state\n"); + printf("get_tap - get TAP mode state\n"); + printf("get_tap_change - get change of TAP mode state from last status check\n"); + printf("set_dis_tap - set Disable TAP mode\n"); + printf("get_dis_tap - get Disable TAP mode state\n"); + printf("set_tap_pwup - set TAP mode at power-up state\n"); + printf("get_tap_pwup - get TAP mode at power-up state\n"); + printf("set_disc - set Disc mode state\n"); + printf("get_disc - get Disc mode state\n"); + printf("get_disc_change - get change of Disc mode state from last status check\n"); + printf("set_dis_disc - set Disable Disc mode\n"); + printf("get_dis_disc - get Disable Disc mode state\n"); + printf("set_disc_pwup - set Disc mode at power-up state\n"); + printf("get_disc_pwup - get Disc mode at power-up state\n"); +#if 0 + printf("get_disc_port - get Disc Port mode state\n"); + printf("set_disc_port_pwup - set Disc Port mode at power-up state\n"); + printf("get_disc_port_pwup - get Disc Port mode at power-up state\n"); +#endif + + printf("set_wd_exp_mode - set adapter state when WDT expired\n"); + printf("get_wd_exp_mode - get adapter state when WDT expired\n"); + printf("set_wd_autoreset - set WDT autoreset mode\n"); + printf("get_wd_autoreset - get WDT autoreset mode\n"); +#ifdef BP_SELF_TEST + printf("set_bst - set Bypass Self Test mode\n"); + printf("get_bst - get Bypass Self Test mode\n"); + +#endif + + + printf("\nExample: "PROG_NAME" eth0 set_bypass_wd 5000\n"); + printf(" "PROG_NAME" all set_bypass on\n"); + printf(" "PROG_NAME" eth0 set_wd_exp_mode tap\n"); + printf(" "PROG_NAME" 0b:00.0 get_bypass_info\n"); + + +} + + +#define BPCTL_GET_CMD(fn,file_desc,if_index,dev_num, bus, slot, func) \ + ({if((bus)||(slot)||(func)||(if_index)) \ + get_##fn##_cmd(file_desc,if_index, bus, slot, func); \ + else \ + get_##fn##_all_cmd(file_desc,dev_num);}) + +#define BPCTL_SET_CMD(fn,file_desc,if_index,dev_num,param, bus, slot, func) \ + ({if((bus)||(slot)||(func)||(if_index)) \ + set_##fn##_cmd(file_desc,if_index,param, bus, slot, func); \ + else \ + set_##fn##_all_cmd(file_desc,dev_num,param);}) + +#define IS_BYPASS_CMD(file_desc,if_index,dev_num, bus, slot, func) \ + ({if((bus)||(slot)||(func)||(if_index)) \ + is_bypass_cmd(file_desc,if_index, bus, slot, func); \ + else \ + is_bypass_all_cmd(file_desc,dev_num);}) + +#define RESET_WD_CMD(file_desc,if_index,dev_num, bus, slot, func) \ + ({if((bus)||(slot)||(func)||(if_index)) \ + reset_bypass_wd_cmd(file_desc,if_index, bus, slot, func); \ + else \ + reset_bypass_wd_all_cmd(file_desc,dev_num);}) + +#define BP_MANUF_CMD(file_desc,if_index,dev_num, bus, slot, func) \ + ({if((bus)||(slot)||(func)||(if_index)) \ + set_bp_manuf_cmd(file_desc,if_index, bus, slot, func); \ + else \ + set_bp_manuf_all_cmd(file_desc,dev_num);}) + + + + + +int if_info_msg (int file_desc, struct bpctl_cmd *bpctl_cmd){ + char if_name[IFNAMSIZ]; + int ret_val = 0; + struct bpctl_cmd bpctl_cmd1; + + memset(&bpctl_cmd1, 0, sizeof(bpctl_cmd1)); + bpctl_cmd1.in_param[1] = bpctl_cmd->out_param[3]; + bpctl_cmd1.in_param[5] = bpctl_cmd->out_param[0]; + bpctl_cmd1.in_param[6] = bpctl_cmd->out_param[1]; + bpctl_cmd1.in_param[7] = bpctl_cmd->out_param[2]; + + + + printf("%02x:%02x.%x ",bpctl_cmd->out_param[0],bpctl_cmd->out_param[1],bpctl_cmd->out_param[2]); + if ((bpctl_cmd->out_param[3]>0)&&(if_indextoname(bpctl_cmd->out_param[3], (char *)&if_name)!=NULL)) + printf("%s ",if_name); + else printf(" "); + + if ((ret_val = ioctl(file_desc, IOCTL_TX_MSG(IS_BYPASS), &bpctl_cmd1))<0) { + return 0; + } + + if (bpctl_cmd1.status < 0) { + return 0; + } + /* if ((bpctl_cmd->out_param[2]==1)||(bpctl_cmd->out_param[2]==3)) { */ + if (bpctl_cmd1.status == 0) { + printf("slave\n"); + return 0; + } else return 1; +} + +int if_infox_msg (struct bpctl_cmd *bpctl_cmd){ + char if_name[IFNAMSIZ]; + + printf("%02x:%02x.%x ",bpctl_cmd->out_param[0],bpctl_cmd->out_param[1],bpctl_cmd->out_param[2]); + if ((bpctl_cmd->out_param[3]>0)&&(if_indextoname(bpctl_cmd->out_param[3], (char *)&if_name)!=NULL)) + printf("%s ",if_name); + else printf(" "); + if ((bpctl_cmd->out_param[2]==1)||(bpctl_cmd->out_param[2]==3)) { + return 0; + } else return 1; +} + + +void set_dis_bypass_cmd(int file_desc,int if_index,int bp_mode, int bus, int slot, int func){ + int ret_val; + struct bpctl_cmd bpctl_cmd; + + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + bpctl_cmd.in_param[1]=if_index; + bpctl_cmd.in_param[2]=bp_mode; + + bpctl_cmd.in_param[5]=bus; + bpctl_cmd.in_param[6]= slot; + bpctl_cmd.in_param[7]= func; + + if ((ret_val = ioctl(file_desc, IOCTL_TX_MSG(SET_DIS_BYPASS), &bpctl_cmd))<0) { + printf(NOT_SUPP_BPCTL_MSG); + return; + } + if ((ret_val == 0)&&(bpctl_cmd.status==0)) { + printf(SET_DIS_BYPASS_ENTRY" "SUCCESS_MSG); + } else { + printf(NOT_SUPP_SLAVE_MSG); + } +} + +void set_dis_bypass_all_cmd(int file_desc, int dev_num, int bp_mode){ + int ret_val,i; + struct bpctl_cmd bpctl_cmd; + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + + bpctl_cmd.in_param[1]=0; + bpctl_cmd.in_param[2]=bp_mode; + + for (i=0;i0)&&(if_indextoname(bpctl_cmd.out_param[7], (char *)&if_name)!=NULL)) + printf("%s",if_name); + printf("\n"); + } + + else { + printf(GET_BPSLAVE_FAIL_MSG); + return; + } +} + +void get_bypass_slave_all_cmd(int file_desc,int dev_num){ + int ret_val, i; + struct bpctl_cmd bpctl_cmd; + char if_name[IFNAMSIZ]; + + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + + bpctl_cmd.in_param[1]=0; + for (i=0;i0)&&(if_indextoname(bpctl_cmd.out_param[7], (char *)&if_name)!=NULL)) + printf("%s",if_name); + printf("\n"); + } + } + } +} + + +void is_bypass_cmd(int file_desc,int if_index, int bus, int slot, int func){ + int ret_val ; + struct bpctl_cmd bpctl_cmd; + + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + bpctl_cmd.in_param[1]=if_index; + bpctl_cmd.in_param[5]=bus; + bpctl_cmd.in_param[6]= slot; + bpctl_cmd.in_param[7]= func; + + + if ((ret_val = ioctl(file_desc, IOCTL_TX_MSG(IS_BYPASS), &bpctl_cmd))<0) { + printf(NOT_SUPP_BPCTL_MSG); + return; + } + + if (bpctl_cmd.status <0) { + printf(NOT_SUPP_BPT_MSG); + return; + } + if (bpctl_cmd.status==0) + printf(SLAVE_IF_MSG); + else printf(MASTER_IF_MSG); +} + +void is_bypass_all_cmd(int file_desc,int dev_num){ + int ret_val, i; + struct bpctl_cmd bpctl_cmd; + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + + bpctl_cmd.in_param[1]=0; + + for (i=0;i=0)) { + if (!bpctl_cmd.status) + printf(WD_DIS_MSG); + else if (bpctl_cmd.status>0) + printf(WDT_STATE_MSG,bpctl_cmd.status); + } else { + printf(NOT_SUPP_SLAVE_MSG); + } +} + +void set_bypass_wd_all_cmd(int file_desc, int dev_num, int timeout){ + int ret_val,i; + struct bpctl_cmd bpctl_cmd; + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + + bpctl_cmd.in_param[1]=0; + bpctl_cmd.in_param[2]=timeout; + + for (i=0;i0) + printf(WD_STATE_EXT_MSG,bpctl_cmd.data[0] ); + else printf(WD_STATE_UNKNOWN_MSG); +} + +void get_bypass_wd_all_cmd(int file_desc, int dev_num){ + int ret_val,i; + struct bpctl_cmd bpctl_cmd; + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + + bpctl_cmd.in_param[1]=0; + + for (i=0;i0) + printf("%d\n", bpctl_cmd.data[0]); + else printf("unknown\n"); + } + + + + } +} + +void get_wd_expire_time_cmd(int file_desc, int if_index, int bus, int slot, int func){ + int ret_val; + struct bpctl_cmd bpctl_cmd; + + + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + bpctl_cmd.in_param[1]=if_index; + bpctl_cmd.in_param[5]=bus; + bpctl_cmd.in_param[6]= slot; + bpctl_cmd.in_param[7]= func; + + if ((ret_val = ioctl(file_desc, IOCTL_TX_MSG(GET_WD_EXPIRE_TIME), &bpctl_cmd))<0) { + printf(NOT_SUPP_BPCTL_MSG); + return; + } + if (bpctl_cmd.status<0) + printf(NOT_WDT_SLAVE_MSG); + else if (!bpctl_cmd.data[0]) + printf(WD_DIS_MSG); + else if (bpctl_cmd.data[0]>0) + printf(WD_TIME_LEFT_MSG,bpctl_cmd.data[0] ); + else + printf(WDT_EXP_MSG); +} + +void get_wd_expire_time_all_cmd(int file_desc, int dev_num){ + int ret_val,i; + struct bpctl_cmd bpctl_cmd; + + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + bpctl_cmd.in_param[1]=0; + + for (i=0;i0) + printf("%d\n", bpctl_cmd.data[0]); + else printf("expired\n"); + } + + + + } +} + +void reset_bypass_wd_cmd(int file_desc, int if_index, int bus, int slot, int func){ + int ret_val; + struct bpctl_cmd bpctl_cmd; + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + + bpctl_cmd.in_param[1]=if_index; + bpctl_cmd.in_param[5]=bus; + bpctl_cmd.in_param[6]= slot; + bpctl_cmd.in_param[7]= func; + + if ((ret_val = ioctl(file_desc, IOCTL_TX_MSG(RESET_BYPASS_WD_TIMER), &bpctl_cmd))<0) { + printf(NOT_SUPP_BPCTL_MSG); + return; + } + if ((ret_val == 0)&&(bpctl_cmd.status>=0)) { + if (bpctl_cmd.status<0) + printf(NOT_WDT_SLAVE_MSG); + else if (!bpctl_cmd.status) + printf(WD_DIS_MSG); + else if (bpctl_cmd.status>0) + printf(RESET_BYPASS_WD_TIMER_ENTRY" "SUCCESS_MSG); + } else { + printf(NOT_SUPP_SLAVE_MSG); + } +} + +void reset_bypass_wd_all_cmd(int file_desc, int dev_num){ + int ret_val,i; + struct bpctl_cmd bpctl_cmd; + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + + bpctl_cmd.in_param[1]=0; + + for (i=0;i=0)) + printf(SET_STD_NIC_ENTRY" "SUCCESS_MSG); + else + printf(NOT_SUPP_SLAVE_MSG); +} + +void set_std_nic_all_cmd(int file_desc, int dev_num, int nic_mode){ + int ret_val,i; + struct bpctl_cmd bpctl_cmd; + memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + + + bpctl_cmd.in_param[1]=0; + bpctl_cmd.in_param[2]=nic_mode; + + for (i=0;i=65)&&(str[i]<=90)) + str[i]+=32; +} + +static unsigned long str_to_hex(char *p) { + unsigned long hex = 0; + unsigned long length = strlen(p), shift = 0; + unsigned char dig = 0; + + str_low(p); + + length = strlen(p); + + if (length == 0 ) + return 0; + + do { + dig = p[--length]; + dig = dig<'a' ? (dig - '0') : (dig - 'a' + 0xa); + hex |= (dig<=3) { + struct bpctl_cmd bpctl_cmd; +#if 0 + if ((strncmp(argp[1],"eth",3))&&((strncmp(argp[1],"all",3)))) { + fprintf(stderr,NOT_NET_DEV_MSG,argp[1]); + return ERROR; + } +#endif + if (strstr(argp[1], ":")) { + cmd_user=strdup(argp[1]); + bus = str_to_hex(strsep (&cmd_user, ":")); + if (!strstr(cmd_user, ".")) + goto cmd_err; + slot = str_to_hex(strsep (&cmd_user, ".")); + func= str_to_hex(cmd_user); + + // return 0; + + } else if (!strcmp(argp[1], "all")) { + if_index=0; + if (ioctl(file_desc, IOCTL_TX_MSG(GET_DEV_NUM), &bpctl_cmd)<0) { + printf(GET_DEV_NUM_FAIL_MSG); + return ERROR; + } + if ((dev_num=bpctl_cmd.out_param[0])==0) { + printf(NO_BPCTL_DEV_MSG); + return ERROR; + } + + } else { + if_name= argp[1]; + if_index=if_nametoindex(if_name); + if (if_index==0) { + printf("%s is not exist!\n",if_name); + return ERROR; + } + bpctl_cmd.in_param[1]=if_index; + } + i=2; + if (!strcmp(argp[i], SET_TX_ENTRY)) { + int nic_mode=0; + if ((argc<(i+2))||((nic_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(tx,file_desc,if_index,dev_num,nic_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_TX_ENTRY)) { + BPCTL_GET_CMD(tx,file_desc,if_index,dev_num, bus, slot, func); + return OK; + }if (!strcmp(argp[i], SET_TPL_ENTRY)) { + int nic_mode=0; + if ((argc<(i+2))||((nic_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(tpl,file_desc,if_index,dev_num,nic_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_TPL_ENTRY)) { + BPCTL_GET_CMD(tpl,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], IS_BYPASS_ENTRY)) { + IS_BYPASS_CMD(file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_BYPASS_SLAVE_ENTRY)) { + BPCTL_GET_CMD(bypass_slave,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_BYPASS_CAPS_ENTRY)) { + BPCTL_GET_CMD(bypass_caps,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_WD_SET_CAPS_ENTRY)) { + BPCTL_GET_CMD(wd_set_caps,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_BYPASS_ENTRY)) { + int nic_mode=0; + + if ((argc<(i+2))||((nic_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + + BPCTL_SET_CMD(bypass,file_desc,if_index,dev_num,nic_mode, bus, slot, func); + return OK; + + } else if (!strcmp(argp[i], GET_BYPASS_ENTRY)) { + BPCTL_GET_CMD(bypass,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_WD_EXPIRE_ENTRY)) { + BPCTL_GET_CMD(wd_expire,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_BYPASS_CHANGE_ENTRY)) { + BPCTL_GET_CMD(bypass_change,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_DIS_BYPASS_ENTRY)) { + int nic_mode=0; + if ((argc<(i+2))||((nic_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(dis_bypass,file_desc,if_index,dev_num,nic_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_DIS_BYPASS_ENTRY)) { + BPCTL_GET_CMD(dis_bypass,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_BYPASS_PWOFF_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(bypass_pwoff,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_BYPASS_PWOFF_ENTRY)) { + BPCTL_GET_CMD(bypass_pwoff,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_BYPASS_PWUP_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(bypass_pwup,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_BYPASS_PWUP_ENTRY)) { + BPCTL_GET_CMD(bypass_pwup,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_STD_NIC_ENTRY)) { + int nic_mode=0; + if ((argc<(i+2))||((nic_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(std_nic,file_desc,if_index,dev_num,nic_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_STD_NIC_ENTRY)) { + BPCTL_GET_CMD(std_nic,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_TX_ENTRY)) { + int nic_mode=0; + if ((argc<(i+2))||((nic_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(tx,file_desc, if_index,dev_num,nic_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_TX_ENTRY)) { + BPCTL_GET_CMD(tx,file_desc, if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_BYPASS_WD_ENTRY)) { + int timeout=0; + if (argc<(i+2)) + goto cmd_err; + timeout=atoi(argp[i+1]); + BPCTL_SET_CMD(bypass_wd,file_desc,if_index,dev_num,timeout, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_BYPASS_WD_ENTRY)) { + BPCTL_GET_CMD(bypass_wd,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_WD_EXPIRE_TIME_ENTRY)) { + BPCTL_GET_CMD(wd_expire_time,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], RESET_BYPASS_WD_TIMER_ENTRY)) { + RESET_WD_CMD(file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_BP_MANUF_ENTRY)) { + BP_MANUF_CMD(file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_TAP_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(tap,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_TAP_ENTRY)) { + BPCTL_GET_CMD(tap,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_TAP_CHANGE_ENTRY)) { + BPCTL_GET_CMD(tap_change,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_DIS_TAP_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(dis_tap,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_DIS_TAP_ENTRY)) { + BPCTL_GET_CMD(dis_tap,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_TAP_PWUP_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(tap_pwup,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_TAP_PWUP_ENTRY)) { + BPCTL_GET_CMD(tap_pwup,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } +#if 0 + else if (!strcmp(argp[i], SET_DISC_PORT_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(disc_port,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_DISC_PORT_ENTRY)) { + BPCTL_GET_CMD(disc_port,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_DISC_PORT_PWUP_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(disc_port_pwup,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } +#endif + else if (!strcmp(argp[i], GET_DISC_PORT_PWUP_ENTRY)) { + BPCTL_GET_CMD(disc_port_pwup,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_DISC_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(disc,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_DISC_ENTRY)) { + BPCTL_GET_CMD(disc,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_DISC_CHANGE_ENTRY)) { + BPCTL_GET_CMD(disc_change,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_DIS_DISC_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(dis_disc,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_DIS_DISC_ENTRY)) { + BPCTL_GET_CMD(dis_disc,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_DISC_PWUP_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(disc_pwup,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_DISC_PWUP_ENTRY)) { + BPCTL_GET_CMD(disc_pwup,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } + + else if (!strcmp(argp[i], SET_WD_EXP_MODE_ENTRY)) { + int mode=0; + if ((argc<(i+2))||((mode=parse_wd_exp_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(wd_exp_mode,file_desc,if_index,dev_num,mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_WD_EXP_MODE_ENTRY)) { + BPCTL_GET_CMD(wd_exp_mode,file_desc,if_index,dev_num, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], SET_WD_AUTORESET_ENTRY)) { + int timeout=0; + if (argc<(i+2)) + goto cmd_err; + timeout=atoi(argp[i+1]); + BPCTL_SET_CMD(wd_autoreset,file_desc, if_index,dev_num,timeout, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_WD_AUTORESET_ENTRY)) { + BPCTL_GET_CMD(wd_autoreset,file_desc, if_index,dev_num, bus, slot, func); + return OK; +#ifdef BP_DBI_FLAG + } else if (!strcmp(argp[i], SET_FORCE_LINK_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(bp_force_link,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_FORCE_LINK_ENTRY)) { + BPCTL_GET_CMD(bp_force_link,file_desc,if_index,dev_num, bus, slot, func); + return OK; +#endif + +#ifdef BP_SELF_TEST + } else if (!strcmp(argp[i], SET_BP_SELF_TEST_ENTRY)) { + int timeout=0; + if (argc<(i+2)) + goto cmd_err; + timeout=atoi(argp[i+1]); + BPCTL_SET_CMD(bp_self_test,file_desc, if_index,dev_num,timeout, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_BP_SELF_TEST_ENTRY)) { + BPCTL_GET_CMD(bp_self_test,file_desc, if_index,dev_num, bus, slot, func); + return OK; +#endif + +//#ifdef PMC_FIX_FLAG + } else if (!strcmp(argp[i], SET_HW_RESET_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(bp_hw_reset,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_HW_RESET_ENTRY)) { + BPCTL_GET_CMD(bp_hw_reset,file_desc,if_index,dev_num, bus, slot, func); + return OK; + + } else if (!strcmp(argp[i], SET_WAIT_AT_PWUP_ENTRY)) { + int bypass_mode=0; + if ((argc<(i+2))||((bypass_mode=parse_bypass_mode(argp[i+1]))<0)) + goto cmd_err; + BPCTL_SET_CMD(bp_wait_at_pwup,file_desc,if_index,dev_num,bypass_mode, bus, slot, func); + return OK; + } else if (!strcmp(argp[i], GET_WAIT_AT_PWUP_ENTRY)) { + BPCTL_GET_CMD(bp_wait_at_pwup,file_desc,if_index,dev_num, bus, slot, func); + return OK; +//#endif + } else if (!strcmp(argp[i], GET_BYPASS_INFO_ENTRY)) { + BPCTL_GET_CMD(bypass_info, file_desc,if_index,dev_num, bus, slot, func); + return OK; + } + } + cmd_err: + printf("Command line error!\n"); + bp_usage(); + return ERROR; +} + +/* +* Main - Call the ioctl functions +*/ +int main(int argc, char **argp, char **envp){ + + int file_desc; + file_desc = open(DEVICE_NODE, 0); + + if (file_desc < 0) { + printf("Can't open device file: %s\n", DEVICE_NAME); + exit(-1); + } + parse_cmdline(argc, argp, file_desc); + close(file_desc); + return OK; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bprd_util.h b/bprd_util.h new file mode 100755 index 0000000..94abbf3 --- /dev/null +++ b/bprd_util.h @@ -0,0 +1,194 @@ +/************************************************************************** + +Copyright (c) 2006-2013, Silicom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Silicom nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#ifndef BPCTL_UTIL_H +#define BPCTL_UTIL_H + +#include "bp_msg.h" + + +#define APP_NAME "Bypass-SD Control utility" +#define COPYRT_MSG "Copyright Silicom Ltd." +#define PROG_NAME "bprdctl_util" +#define UTIL_VER "1.0.13" + + +#define OK 0 +#define ERROR 1 + +#define HELP_ENTRY "help" +#define INFO_ENTRY "info" +#define IF_SCAN_ENTRY "if_scan" + +#define SET_TX_ENTRY "set_tx" +#define GET_TX_ENTRY "get_tx" +#define SET_TPL_ENTRY "set_tpl" +#define GET_TPL_ENTRY "get_tpl" +#define GET_DEV_NUM_ENTRY "get_dev_num" + +#define IS_BYPASS_ENTRY "is_bypass" +#define GET_BYPASS_SLAVE_ENTRY "get_bypass_slave" +#define GET_BYPASS_CAPS_ENTRY "get_bypass_caps" +#define GET_WD_SET_CAPS_ENTRY "get_wd_set_caps" +#define SET_BYPASS_ENTRY "set_bypass" +#define GET_BYPASS_ENTRY "get_bypass" +#define GET_BYPASS_CHANGE_ENTRY "get_bypass_change" +#define SET_DIS_BYPASS_ENTRY "set_dis_bypass" +#define GET_DIS_BYPASS_ENTRY "get_dis_bypass" +#define SET_BYPASS_PWOFF_ENTRY "set_bypass_pwoff" +#define GET_BYPASS_PWOFF_ENTRY "get_bypass_pwoff" +#define SET_BYPASS_PWUP_ENTRY "set_bypass_pwup" +#define GET_BYPASS_PWUP_ENTRY "get_bypass_pwup" +#define SET_STD_NIC_ENTRY "set_std_nic" +#define GET_STD_NIC_ENTRY "get_std_nic" +#define SET_BYPASS_WD_ENTRY "set_bypass_wd" +#define GET_BYPASS_WD_ENTRY "get_bypass_wd" +#define GET_WD_EXPIRE_TIME_ENTRY "get_wd_time_expire" +#define RESET_BYPASS_WD_TIMER_ENTRY "reset_bypass_wd" +#define SET_TX_ENTRY "set_tx" +#define GET_TX_ENTRY "get_tx" +#define BYPASS_ENABLE "on" +#define BYPASS_DISABLE "off" +#define TAP_MODE "tap" +#define BYPASS_MODE "bypass" +#define SET_TAP_ENTRY "set_tap" +#define GET_TAP_ENTRY "get_tap" +#define GET_TAP_CHANGE_ENTRY "get_tap_change" +#define SET_DIS_TAP_ENTRY "set_dis_tap" +#define GET_DIS_TAP_ENTRY "get_dis_tap" +#define SET_TAP_PWUP_ENTRY "set_tap_pwup" +#define GET_TAP_PWUP_ENTRY "get_tap_pwup" +#define SET_WD_EXP_MODE_ENTRY "set_wd_exp_mode" +#define GET_WD_EXP_MODE_ENTRY "get_wd_exp_mode" +#define SET_FORCE_LINK_ENTRY "set_force_link_on" +#define GET_FORCE_LINK_ENTRY "get_force_link_on" + +#define SET_BP_WAIT_AT_PWUP_ENTRY "set_wait_at_pwup" +#define GET_BP_WAIT_AT_PWUP_ENTRY "get_wait_at_pwup" +#define SET_BP_HW_RESET_ENTRY "set_hw_reset" +#define GET_BP_HW_RESET_ENTRY "get_hw_reset" + +#define SET_DISC_PORT_ENTRY "set_disc_port" +#define GET_DISC_PORT_ENTRY "get_disc_port" +#define SET_DISC_PORT_PWUP_ENTRY "set_disc_port_pwup" +#define GET_DISC_PORT_PWUP_ENTRY "get_disc_port_pwup" + + + + + +#define BYPASS_ENABLE "on" +#define BYPASS_DISABLE "off" +#define IF_NAME "eth" +#define ALL_NAME "all " + + +#define IF_NAME "eth" + +struct bp_cap { + int flag; + char *desc; +} bp_cap, *pbp_cap; + + + +struct bp_cap bp_cap_array[]={ + {BP_CAP , BP_CAP_MSG}, + {BP_STATUS_CAP , BP_STATUS_CAP_MSG}, + {BP_STATUS_CHANGE_CAP , BP_STATUS_CHANGE_CAP_MSG}, + {SW_CTL_CAP , SW_CTL_CAP_MSG}, + {BP_DIS_CAP , BP_DIS_CAP_MSG}, + {BP_DIS_STATUS_CAP , BP_DIS_STATUS_CAP_MSG}, + {STD_NIC_CAP , STD_NIC_CAP_MSG}, + {BP_PWOFF_ON_CAP , BP_PWOFF_ON_CAP_MSG}, + {BP_PWOFF_OFF_CAP , BP_PWOFF_OFF_CAP_MSG}, + {BP_PWOFF_CTL_CAP , BP_PWOFF_CTL_CAP_MSG}, + {BP_PWUP_ON_CAP , BP_PWUP_ON_CAP_MSG}, + {BP_PWUP_OFF_CAP , BP_PWUP_OFF_CAP_MSG}, + {BP_PWUP_CTL_CAP , BP_PWUP_CTL_CAP_MSG}, + {WD_CTL_CAP , WD_CTL_CAP_MSG}, + {WD_STATUS_CAP , WD_STATUS_CAP_MSG}, + {WD_TIMEOUT_CAP , WD_TIMEOUT_CAP_MSG}, + {TX_CTL_CAP , TX_CTL_CAP_MSG}, + {TX_STATUS_CAP , TX_STATUS_CAP_MSG}, + {TAP_CAP , TAP_CAP_MSG}, + {TAP_STATUS_CAP , TAP_STATUS_CAP_MSG}, + {TAP_STATUS_CHANGE_CAP , TAP_STATUS_CHANGE_CAP_MSG}, + {TAP_DIS_CAP , TAP_DIS_CAP_MSG}, + {TAP_DIS_STATUS_CAP , TAP_DIS_STATUS_CAP_MSG}, + {TAP_PWUP_ON_CAP , TAP_PWUP_ON_CAP_MSG}, + {TAP_PWUP_OFF_CAP , TAP_PWUP_OFF_CAP_MSG}, + {TAP_PWUP_CTL_CAP , TAP_PWUP_CTL_CAP_MSG}, + {NIC_CAP_NEG , NIC_CAP_NEG_MSG}, + {TPL_CAP , TPL_CAP_MSG}, + {DISC_CAP , DISC_CAP_MSG}, + {DISC_DIS_CAP , DISC_DIS_CAP_MSG}, + {DISC_PWUP_CTL_CAP , DISC_PWUP_CTL_CAP_MSG}, + + {0,NULL} +} ; + + + + + + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bprdctl_start b/bprdctl_start new file mode 100755 index 0000000..160fd40 --- /dev/null +++ b/bprdctl_start @@ -0,0 +1,23 @@ +#!/bin/sh +drv_name="bprdctl_mod" +dev_node="bprdctl" +if grep '^staff:' /etc/group > /dev/null; then + group="staff" +else + group="wheel" +fi + +# remove old device node +rm -f /dev/${dev_node}? + +# load the driver +modprobe ${drv_name} + +# extract major number for device +major=`cat /proc/devices | awk "\\$2==\"$dev_node\" {print \\$1}"` + +# make new node +mknod /dev/${dev_node}0 c $major 0 +ln -sf /dev/${dev_node}0 /dev/${dev_node} +chgrp $group /dev/${dev_node}0 +chmod 644 /dev/${dev_node}0 diff --git a/bprdctl_stop b/bprdctl_stop new file mode 100755 index 0000000..9561744 --- /dev/null +++ b/bprdctl_stop @@ -0,0 +1,7 @@ +#!/bin/sh + +/sbin/rmmod bprdctl_mod $* || exit 1 + +rm -f /dev/bprdctl0 /dev/bprdctl + +exit 0 diff --git a/bypass.h b/bypass.h new file mode 100755 index 0000000..61cfd4f --- /dev/null +++ b/bypass.h @@ -0,0 +1,237 @@ +/************************************************************************** + +Copyright (c) 2006-2013, Silicom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Silicom nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#ifndef BYPASS_H +#define BYPASS_H + +/* Bypass related */ + +#define SYNC_CMD_VAL 2 /* 10b */ +#define SYNC_CMD_LEN 2 + +#define WR_CMD_VAL 2 /* 10b */ +#define WR_CMD_LEN 2 + +#define RD_CMD_VAL 1 /* 10b */ +#define RD_CMD_LEN 2 + +#define ADDR_CMD_LEN 4 + +#define WR_DATA_LEN 8 +#define RD_DATA_LEN 8 + + +#define PIC_SIGN_REG_ADDR 0x7 +#define PIC_SIGN_VALUE 0xcd + + +#define STATUS_REG_ADDR 0 +#define WDT_EN_MASK 0x01 //BIT_0 +#define CMND_EN_MASK 0x02 //BIT_1 +#define DIS_BYPASS_CAP_MASK 0x04 //BIT_2 /* Bypass Cap is disable*/ +#define DFLT_PWRON_MASK 0x08 //BIT_3 +#define BYPASS_OFF_MASK 0x10 //BIT_4 +#define BYPASS_FLAG_MASK 0x20 //BIT_5 +#define STD_NIC_MASK (DIS_BYPASS_CAP_MASK | BYPASS_OFF_MASK | DFLT_PWRON_MASK) +#define WD_EXP_FLAG_MASK 0x40 //BIT_6 +#define DFLT_PWROFF_MASK 0x80 //BIT_7 +#define STD_NIC_PWOFF_MASK (DIS_BYPASS_CAP_MASK | BYPASS_OFF_MASK | DFLT_PWRON_MASK | DFLT_PWROFF_MASK) + + +#define PRODUCT_CAP_REG_ADDR 0x5 +#define BYPASS_SUPPORT_MASK 0x01 //BIT_0 +#define TAP_SUPPORT_MASK 0x02 //BIT_1 +#define NORMAL_UNSUPPORT_MASK 0x04 /*BIT_2*/ +#define DISC_SUPPORT_MASK 0x08 //BIT_3 +#define TPL2_SUPPORT_MASK 0x10 //BIT_4 +#define DISC_PORT_SUPPORT_MASK 0x20 //BIT_5 + + + +#define STATUS_TAP_REG_ADDR 0x6 +#define WDTE_TAP_BPN_MASK 0x01 //BIT_1 /* 1 when wdt expired -> TAP, 0 - Bypass */ +#define DIS_TAP_CAP_MASK 0x04 //BIT_2 /* TAP Cap is disable*/ +#define DFLT_PWRON_TAP_MASK 0x08 //BIT_3 +#define TAP_OFF_MASK 0x10 //BIT_4 +#define TAP_FLAG_MASK 0x20 //BIT_5 +#define TX_DISA_MASK 0x40 +#define TX_DISB_MASK 0x80 + +#define STD_NIC_TAP_MASK (DIS_TAP_CAP_MASK | TAP_OFF_MASK | DFLT_PWRON_TAP_MASK) + +#define STATUS_DISC_REG_ADDR 13 + #define WDTE_DISC_BPN_MASK 0x01 //BIT_0 /* 1 when wdt expired -> TAP, 0 - Bypass */ + #define STD_NIC_ON_MASK 0x02 //BIT_1 + #define DIS_DISC_CAP_MASK 0x04 //BIT_2 /* TAP Cap is disable*/ + #define DFLT_PWRON_DISC_MASK 0x08 //BIT_3 + #define DISC_OFF_MASK 0x10 //BIT_4 + #define DISC_FLAG_MASK 0x20 //BIT_5 + #define TPL2_FLAG_MASK 0x40 //BIT_6 + #define STD_NIC_DISC_MASK DIS_DISC_CAP_MASK + +#define CONT_CONFIG_REG_ADDR 12 + #define EN_HW_RESET_MASK 0x2 /* BIT_1 */ + #define WAIT_AT_PWUP_MASK 0x1 /* BIT_0 */ + + + +#define VER_REG_ADDR 0x1 +#define BP_FW_VER_A0 0xa0 +#define BP_FW_VER_A1 0xa1 + +#define INT_VER_MASK 0xf0 +#define EXT_VER_MASK 0xf +/* */ +#define PXG2BPI_VER 0x0 +#define PXG2TBPI_VER 0x1 +#define PXE2TBPI_VER 0x2 +#define PXG4BPFI_VER 0x4 +#define BP_FW_EXT_VER7 0x6 +#define BP_FW_EXT_VER8 0x8 +#define BP_FW_EXT_VER9 0x9 + +#define OLD_IF_VER -1 + +#define CMND_REG_ADDR 10 /* 1010b */ +#define WDT_REG_ADDR 4 +#define TMRL_REG_ADDR 2 +#define TMRH_REG_ADDR 3 + +/* NEW_FW */ +#define WDT_INTERVAL 5 //20 +#define WDT_CMND_INTERVAL 200 //50 +#define CMND_INTERVAL 200 //100 /* usec */ +#define PULSE_TIME 100 + +/* OLD_FW */ +#define INIT_CMND_INTERVAL 40 +#define PULSE_INTERVAL 5 +#define WDT_TIME_CNT 3 + +/* Intel Commands */ + +#define CMND_OFF_INT 0xf +#define PWROFF_BYPASS_ON_INT 0x5 +#define BYPASS_ON_INT 0x6 +#define DIS_BYPASS_CAP_INT 0x4 +#define RESET_WDT_INT 0x1 + +/* Intel timing */ + +#define BYPASS_DELAY_INT 4 /* msec */ +#define CMND_INTERVAL_INT 2 /* msec */ + +/* Silicom Commands */ +#define CMND_ON 0x4 +#define CMND_OFF 0x2 +#define BYPASS_ON 0xa +#define BYPASS_OFF 0x8 +#define PORT_LINK_EN 0xe +#define PORT_LINK_DIS 0xc +#define WDT_ON 0x10 /* 0x1f (11111) - max*/ +#define TIMEOUT_UNIT 100 +#define TIMEOUT_MAX_STEP 15 +#define WDT_TIMEOUT_MIN 100 /* msec */ +#define WDT_TIMEOUT_MAX 3276800 /* msec */ +#define WDT_AUTO_MIN_INT 500 +#define WDT_TIMEOUT_DEF WDT_TIMEOUT_MIN +#define WDT_OFF 0x6 +#define WDT_RELOAD 0x9 +#define RESET_CONT 0x20 +#define DIS_BYPASS_CAP 0x22 +#define EN_BYPASS_CAP 0x24 +#define BYPASS_STATE_PWRON 0x26 +#define NORMAL_STATE_PWRON 0x28 +#define BYPASS_STATE_PWROFF 0x27 +#define NORMAL_STATE_PWROFF 0x29 +#define TAP_ON 0xb +#define TAP_OFF 0x9 +#define TAP_STATE_PWRON 0x2a +#define DIS_TAP_CAP 0x2c +#define EN_TAP_CAP 0x2e +#define STD_NIC_OFF 0x86 +#define STD_NIC_ON 0x84 +#define DISC_ON 0x85 +#define DISC_OFF 0x8a +#define DISC_STATE_PWRON 0x87 +#define DIS_DISC_CAP 0x88 +#define EN_DISC_CAP 0x89 +#define TPL2_ON 0x8c +#define TPL2_OFF 0x8b +#define BP_WAIT_AT_PWUP_EN 0x80 +#define BP_WAIT_AT_PWUP_DIS 0x81 +#define BP_HW_RESET_EN 0x82 +#define BP_HW_RESET_DIS 0x83 + +#define TX_DISA 0x8d +#define TX_DISB 0x8e +#define TX_ENA 0xA0 +#define TX_ENB 0xA1 + +#define TX_DISA_PWRUP 0xA2 +#define TX_DISB_PWRUP 0xA3 +#define TX_ENA_PWRUP 0xA4 +#define TX_ENB_PWRUP 0xA5 + + +#define BYPASS_CAP_DELAY 35 /* msec */ +#define DFLT_PWRON_DELAY 10 /* msec */ +#define LATCH_DELAY 15 /* msec */ +#define EEPROM_WR_DELAY 20 /* msec */ + +#define BP_LINK_MON_DELAY 4 /* sec */ + + +#define BP_FW_EXT_VER0 0xa0 +#define BP_FW_EXT_VER1 0xa1 +#define BP_FW_EXT_VER2 0xb1 + +#define BP_OK 0 +#define BP_NOT_CAP -1 +#define WDT_STATUS_EXP -2 +#define WDT_STATUS_UNKNOWN -1 +#define WDT_STATUS_EN 1 +#define WDT_STATUS_DIS 0 + + +#define ETH_P_BPTEST 0xabba + + +#define BPTEST_DATA_LEN 60 + + + + +#endif /* BYPASS_H*/ + + diff --git a/common.mk b/common.mk new file mode 100755 index 0000000..8c43f76 --- /dev/null +++ b/common.mk @@ -0,0 +1,335 @@ +################################################################################ +# +# Intel(R) 10GbE PCI Express Linux Network Driver +# Copyright(c) 1999 - 2017 Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope 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. +# +# The full GNU General Public License is included in this distribution in +# the file called "COPYING". +# +# Contact Information: +# Linux NICS +# e1000-devel Mailing List +# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 +# +################################################################################ + +# common Makefile rules useful for out-of-tree Linux driver builds +# +# Usage: include common.mk +# +# After including, you probably want to add a minimum_kver_check call +# +# Required Variables: +# DRIVER +# -- Set to the lowercase driver name + +##################### +# Helpful functions # +##################### + +readlink = $(shell readlink -f ${1}) + +# helper functions for converting kernel version to version codes +get_kver = $(or $(word ${2},$(subst ., ,${1})),0) +get_kvercode = $(shell [ "${1}" -ge 0 -a "${1}" -le 255 2>/dev/null ] && \ + [ "${2}" -ge 0 -a "${2}" -le 255 2>/dev/null ] && \ + [ "${3}" -ge 0 -a "${3}" -le 255 2>/dev/null ] && \ + printf %d $$(( ( ${1} << 16 ) + ( ${2} << 8 ) + ( ${3} ) )) ) + +################ +# depmod Macro # +################ + +cmd_depmod = /sbin/depmod $(if ${SYSTEM_MAP_FILE},-e -F ${SYSTEM_MAP_FILE}) \ + $(if $(strip ${INSTALL_MOD_PATH}),-b ${INSTALL_MOD_PATH}) \ + -a ${KVER} + +################ +# dracut Macro # +################ + +cmd_initrd := $(shell \ + if which dracut > /dev/null 2>&1 ; then \ + echo "dracut --force"; \ + elif which update-initramfs > /dev/null 2>&1 ; then \ + echo "update-initramfs -u"; \ + fi ) + +##################### +# Environment tests # +##################### + +DRIVER_UPPERCASE := $(shell echo ${DRIVER} | tr "[:lower:]" "[:upper:]") + +ifeq (,${BUILD_KERNEL}) +BUILD_KERNEL=$(shell uname -r) +endif + +# Kernel Search Path +# All the places we look for kernel source +KSP := /lib/modules/${BUILD_KERNEL}/source \ + /lib/modules/${BUILD_KERNEL}/build \ + /usr/src/linux-${BUILD_KERNEL} \ + /usr/src/linux-$(${BUILD_KERNEL} | sed 's/-.*//') \ + /usr/src/kernel-headers-${BUILD_KERNEL} \ + /usr/src/kernel-source-${BUILD_KERNEL} \ + /usr/src/linux-$(${BUILD_KERNEL} | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/') \ + /usr/src/linux \ + /usr/src/kernels/${BUILD_KERNEL} \ + /usr/src/kernels + +# prune the list down to only values that exist and have an include/linux +# sub-directory. We can't use include/config because some older kernels don't +# have this. +test_dir = $(shell [ -e ${dir}/include/linux ] && echo ${dir}) +KSP := $(foreach dir, ${KSP}, ${test_dir}) + +# we will use this first valid entry in the search path +ifeq (,${KSRC}) + KSRC := $(firstword ${KSP}) +endif + +ifeq (,${KSRC}) + $(warning *** Kernel header files not in any of the expected locations.) + $(warning *** Install the appropriate kernel development package, e.g.) + $(error kernel-devel, for building kernel modules and try again) +else +ifeq (/lib/modules/${BUILD_KERNEL}/source, ${KSRC}) + KOBJ := /lib/modules/${BUILD_KERNEL}/build +else + KOBJ := ${KSRC} +endif +endif + +# Version file Search Path +VSP := ${KOBJ}/include/generated/utsrelease.h \ + ${KOBJ}/include/linux/utsrelease.h \ + ${KOBJ}/include/linux/version.h \ + ${KOBJ}/include/generated/uapi/linux/version.h \ + /boot/vmlinuz.version.h + +# Config file Search Path +CSP := ${KOBJ}/include/generated/autoconf.h \ + ${KOBJ}/include/linux/autoconf.h \ + /boot/vmlinuz.autoconf.h + +# System.map Search Path (for depmod) +MSP := ${KSRC}/System.map \ + /boot/System.map-${BUILD_KERNEL} + +# prune the lists down to only files that exist +test_file = $(shell [ -f ${file} ] && echo ${file}) +VSP := $(foreach file, ${VSP}, ${test_file}) +CSP := $(foreach file, ${CSP}, ${test_file}) +MSP := $(foreach file, ${MSP}, ${test_file}) + + +# and use the first valid entry in the Search Paths +ifeq (,${VERSION_FILE}) + VERSION_FILE := $(firstword ${VSP}) +endif + +ifeq (,${CONFIG_FILE}) + CONFIG_FILE := $(firstword ${CSP}) +endif + +ifeq (,${SYSTEM_MAP_FILE}) + SYSTEM_MAP_FILE := $(firstword ${MSP}) +endif + +ifeq (,$(wildcard ${VERSION_FILE})) + $(error Linux kernel source not configured - missing version header file) +endif + +ifeq (,$(wildcard ${CONFIG_FILE})) + $(error Linux kernel source not configured - missing autoconf.h) +endif + +ifeq (,$(wildcard ${SYSTEM_MAP_FILE})) + $(warning Missing System.map file - depmod will not check for missing symbols) +endif + +####################### +# Linux Version Setup # +####################### + +# The following command line parameter is intended for development of KCOMPAT +# against upstream kernels such as net-next which have broken or non-updated +# version codes in their Makefile. They are intended for debugging and +# development purpose only so that we can easily test new KCOMPAT early. If you +# don't know what this means, you do not need to set this flag. There is no +# arcane magic here. + +# Convert LINUX_VERSION into LINUX_VERSION_CODE +ifneq (${LINUX_VERSION},) + LINUX_VERSION_CODE=$(call get_kvercode,$(call get_kver,${LINUX_VERSION},1),$(call get_kver,${LINUX_VERSION},2),$(call get_kver,${LINUX_VERSION},3)) +endif + +# Honor LINUX_VERSION_CODE +ifneq (${LINUX_VERSION_CODE},) + $(warning Forcing target kernel to build with LINUX_VERSION_CODE of ${LINUX_VERSION_CODE}$(if ${LINUX_VERSION}, from LINUX_VERSION=${LINUX_VERSION}). Do this at your own risk.) + KVER_CODE := ${LINUX_VERSION_CODE} + EXTRA_CFLAGS += -DLINUX_VERSION_CODE=${LINUX_VERSION_CODE} +endif + +# Determine SLE_LOCALVERSION_CODE for SuSE SLE >= 11 (needed by kcompat) +# This assumes SuSE will continue setting CONFIG_LOCALVERSION to the string +# appended to the stable kernel version on which their kernel is based with +# additional versioning information (up to 3 numbers), a possible abbreviated +# git SHA1 commit id and a kernel type, e.g. CONFIG_LOCALVERSION=-1.2.3-default +# or CONFIG_LOCALVERSION=-999.gdeadbee-default +ifeq (1,$(shell ${CC} -E -dM ${CONFIG_FILE} 2> /dev/null |\ + grep -m 1 CONFIG_SUSE_KERNEL | awk '{ print $$3 }')) + +ifneq (10,$(shell ${CC} -E -dM ${CONFIG_FILE} 2> /dev/null |\ + grep -m 1 CONFIG_SLE_VERSION | awk '{ print $$3 }')) + + LOCALVERSION := $(shell ${CC} -E -dM ${CONFIG_FILE} 2> /dev/null |\ + grep -m 1 CONFIG_LOCALVERSION | awk '{ print $$3 }' |\ + cut -d'-' -f2 | sed 's/\.g[[:xdigit:]]\{7\}//') + LOCALVER_A := $(shell echo ${LOCALVERSION} | cut -d'.' -f1) + LOCALVER_B := $(shell echo ${LOCALVERSION} | cut -s -d'.' -f2) + LOCALVER_C := $(shell echo ${LOCALVERSION} | cut -s -d'.' -f3) + SLE_LOCALVERSION_CODE := $(shell expr ${LOCALVER_A} \* 65536 + \ + 0${LOCALVER_B} \* 256 + 0${LOCALVER_C}) + EXTRA_CFLAGS += -DSLE_LOCALVERSION_CODE=${SLE_LOCALVERSION_CODE} +endif +endif + +EXTRA_CFLAGS += -DVER_STR_SET='\"$(MOD_VER)\"' +EXTRA_CFLAGS += -DBP_READ_REG +EXTRA_CFLAGS += -DPMC_FIX_FLAG +EXTRA_CFLAGS += -DBP_SYNC_FLAG +EXTRA_CFLAGS += -DBP_10G +#EXTRA_CFLAGS += -DADI_RANGELEY_SUPPORT +#EXTRA_CFLAGS += -BP_HW_WD_CNT +#EXTRA_CFLAGS += -DBPVM_KVM + + + +#EXTRA_CFLAGS += -DBP_SELF_TEST +#EXTRA_CFLAGS += -DBP_LINK_FAIL_NOTIFIER +#EXTRA_CFLAGS += -DBP_PROC_SUPPORT +#EXTRA_CFLAGS += -DBP_DBI_FLAG + +EXTRA_CFLAGS += ${CFLAGS_EXTRA} + +# get the kernel version - we use this to find the correct install path +KVER := $(shell ${CC} ${EXTRA_CFLAGS} -E -dM ${VERSION_FILE} | grep UTS_RELEASE | \ + awk '{ print $$3 }' | sed 's/\"//g') + +# assume source symlink is the same as build, otherwise adjust KOBJ +ifneq (,$(wildcard /lib/modules/${KVER}/build)) + ifneq (${KSRC},$(call readlink,/lib/modules/${KVER}/build)) + KOBJ=/lib/modules/${KVER}/build + endif +endif + +ifeq (${KVER_CODE},) + KVER_CODE := $(shell ${CC} ${EXTRA_CFLAGS} -E -dM ${VSP} 2> /dev/null |\ + grep -m 1 LINUX_VERSION_CODE | awk '{ print $$3 }' | sed 's/\"//g') +endif + +# minimum_kver_check +# +# helper function to provide uniform output for different drivers to abort the +# build based on kernel version check. Usage: "$(call minimum_kver_check,2,6,XX)". +define _minimum_kver_check +ifeq (0,$(shell [ ${KVER_CODE} -lt $(call get_kvercode,${1},${2},${3}) ]; echo "$$?")) + $$(warning *** Aborting the build.) + $$(error This driver is not supported on kernel versions older than ${1}.${2}.${3}) +endif +endef +minimum_kver_check = $(eval $(call _minimum_kver_check,${1},${2},${3})) + +################ +# Manual Pages # +################ + +MANSECTION = 7 + +ifeq (,${MANDIR}) + # find the best place to install the man page + MANPATH := $(shell (manpath 2>/dev/null || echo $MANPATH) | sed 's/:/ /g') + ifneq (,${MANPATH}) + # test based on inclusion in MANPATH + test_dir = $(findstring ${dir}, ${MANPATH}) + else + # no MANPATH, test based on directory existence + test_dir = $(shell [ -e ${dir} ] && echo ${dir}) + endif + # our preferred install path + # should /usr/local/man be in here ? + MANDIR := /usr/share/man /usr/man + MANDIR := $(foreach dir, ${MANDIR}, ${test_dir}) + MANDIR := $(firstword ${MANDIR}) +endif +ifeq (,${MANDIR}) + # fallback to /usr/man + MANDIR := /usr/man +endif + +#################### +# CCFLAGS variable # +#################### + +# set correct CCFLAGS variable for kernels older than 2.6.24 +ifeq (0,$(shell [ ${KVER_CODE} -lt $(call get_kvercode,2,6,24) ]; echo $$?)) +CCFLAGS_VAR := EXTRA_CFLAGS +else +CCFLAGS_VAR := ccflags-y +endif + +################# +# KBUILD_OUTPUT # +################# + +# Only set KBUILD_OUTPUT if the real paths of KOBJ and KSRC differ +ifneq ($(call readlink,${KSRC}),$(call readlink,${KOBJ})) +export KBUILD_OUTPUT ?= ${KOBJ} +endif + +############################ +# Module Install Directory # +############################ + +# Default to using updates/drivers/net/ethernet/intel/ path, since depmod since +# v3.1 defaults to checking updates folder first, and only checking kernels/ +# and extra afterwards. We use updates instead of kernel/* due to desire to +# prevent over-writing built-in modules files. +export INSTALL_MOD_DIR ?= updates/drivers/net/ethernet/intel/${DRIVER} + +###################### +# Kernel Build Macro # +###################### + +# kernel build function +# ${1} is the kernel build target +# ${2} may contain any extra rules to pass directly to the sub-make process +# +# This function is expected to be executed by +# @+$(call kernelbuild,,) +# from within a Makefile recipe. +# +# The following variables are expected to be defined for its use: +# GCC_I_SYS -- if set it will enable use of gcc-i-sys.sh wrapper to use -isystem +# CCFLAGS_VAR -- the CCFLAGS variable to set extra CFLAGS +# EXTRA_CFLAGS -- a set of extra CFLAGS to pass into the ccflags-y variable +# KSRC -- the location of the kernel source tree to build against +# DRIVER_UPPERCASE -- the uppercase name of the kernel module, set from DRIVER +# +kernelbuild = ${MAKE} $(if ${GCC_I_SYS},CC="${GCC_I_SYS}") \ + ${CCFLAGS_VAR}="${EXTRA_CFLAGS}" \ + -C "${KSRC}" \ + CONFIG_${DRIVER_UPPERCASE}=m \ + M="${CURDIR}" \ + ${2} ${1} diff --git a/libbp_rd.h b/libbp_rd.h new file mode 100755 index 0000000..dafa251 --- /dev/null +++ b/libbp_rd.h @@ -0,0 +1,585 @@ +/************************************************************************** + +Copyright (c) 2006-2013, Silicom +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Silicom nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#define BP_CAP 0x01 //BIT_0 +#define BP_STATUS_CAP 0x02 //BIT_1 +#define BP_STATUS_CHANGE_CAP 0x04 //BIT_2 +#define SW_CTL_CAP 0x08 //BIT_3 +#define BP_DIS_CAP 0x10 //BIT_4 +#define BP_DIS_STATUS_CAP 0x20 //BIT_5 +#define STD_NIC_CAP 0x40 //BIT_6 +#define BP_PWOFF_ON_CAP 0x80 //BIT_7 +#define BP_PWOFF_OFF_CAP 0x0100 //BIT_8 +#define BP_PWOFF_CTL_CAP 0x0200 //BIT_9 +#define BP_PWUP_ON_CAP 0x0400 //BIT_10 +#define BP_PWUP_OFF_CAP 0x0800 //BIT_11 +#define BP_PWUP_CTL_CAP 0x1000 //BIT_12 +#define WD_CTL_CAP 0x2000 //BIT_13 +#define WD_STATUS_CAP 0x4000 //BIT_14 +#define WD_TIMEOUT_CAP 0x8000 //BIT_15 +#define TX_CTL_CAP 0x10000 //BIT_16 +#define TX_STATUS_CAP 0x20000 //BIT_17 +#define TAP_CAP 0x40000 //BIT_18 +#define TAP_STATUS_CAP 0x80000 //BIT_19 +#define TAP_STATUS_CHANGE_CAP 0x100000 //BIT_20 +#define TAP_DIS_CAP 0x200000 //BIT_21 +#define TAP_DIS_STATUS_CAP 0x400000 //BIT_22 +#define TAP_PWUP_ON_CAP 0x800000 //BIT_23 +#define TAP_PWUP_OFF_CAP 0x1000000 //BIT 24 +#define TAP_PWUP_CTL_CAP 0x2000000 //BIT 25 +#define NIC_CAP_NEG 0x4000000 //BIT 26 + +#define WD_MIN_TIME_GET(desc) (desc & 0xf) +#define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf +#define WDT_STEP_TIME 0x10 + + +struct bp_info { + char prod_name[14]; + unsigned char fw_ver; +}; + +/** + * is_bypass - check if device is a Bypass controlling device + * @if_index: network device index + * + * Output: + * 1 - if device is bypass controlling device, + * 0 - if device is bypass slave device + * -1 - device not support Bypass + **/ +int is_bypass_rd(int if_index); + +/** + * get_bypass_slave - get second port participate in the Bypass pair + * @if_index: network device index + * + * Output: + * network device index of the slave device + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_bypass_slave_rd(int if_index); + +/** + * get_bypass_caps - get second port participate in the Bypass pair + * @if_index: network device index + * + * Output: + * flags word on success;flag word is a 32-bit mask word with each bit defines different + * capability as described bellow. + * Value of 1 for supporting this feature. 0 for not supporting this feature. + * -1 - on failure (if the device is not capable of the operation or not a Bypass device) + * Bit feature description + * + * 0 BP_CAP The interface is Bypass capable in general + * + * 1 BP_STATUS_CAP The interface can report of the current Bypass mode + * + * 2 BP_STATUS_CHANGE_CAP The interface can report on a change to bypass mode from + * the last time the mode was defined + * + * 3 SW_CTL_CAP The interface is Software controlled capable for bypass/non bypass modes. + * + * 4 BP_DIS_CAP The interface is capable of disabling the Bypass mode at all times. + * This mode will retain its mode even during power loss and also after + * power recovery. This will overcome on any bypass operation due to + * watchdog timeout or set bypass command. + * + * 5 BP_DIS_STATUS_CAP The interface can report of the current DIS_BP_CAP + * + * 6 STD_NIC_CAP The interface is capable to be configured to operate as standard, non Bypass, + * NIC interface (have direct connection to interfaces at all power modes) + * + * 7 BP_PWOFF_NO_CAP The interface can be in Bypass mode at power off state + * + * 8 BP_PWOFF_OFF_CAP The interface can disconnect the Bypass mode at power off state without + * effecting all the other states of operation + * + * 9 BP_PWOFF_CTL_CAP The behavior of the Bypass mode at Power-off state can be controlled by + * software without effecting any other state + * + *10 BP_PWUP_ON_CAP The interface can be in Bypass mode when power is turned on + * (until the system take control of the bypass functionality) + * + *11 BP_PWUP_OFF_CAP The interface can disconnect from Bypass mode when power is turned on + * (until the system take control of the bypass functionality) + * + *12 BP_PWUP_CTL_CAP The behavior of the Bypass mode at Power-up can be controlled by software + * + *13 WD_CTL_CAP The interface has watchdog capabilities to turn to Bypass mode when not reset + * for defined period of time. + * + *14 WD_STATUS_CAP The interface can report on the watchdog status (Active/inactive) + * + *15 WD_TIMEOUT_CAP The interface can report the time left till watchdog triggers to Bypass mode. + * + *16-31 RESERVED + * + * **/ +int get_bypass_caps_rd(int if_index); + +/** + * get_wd_set_caps - Obtain watchdog timer setting capabilities + * @if_index: network device index + * + * Output: + * + * Set of numbers defining the various parameters of the watchdog capable + * to be set to as described bellow. + * -1 - on failure (device not support Bypass or it's a slave device) + * + * Bit feature description + * + * 0-3 WD_MIN_TIME The interface WD minimal time period in 100mS units + * + * 4 WD_STEP_TIME The steps of the WD timer in + * 0 - for linear steps (WD_MIN_TIME * X) + * 1 - for multiply by 2 from previous step (WD_MIN_TIME * 2^X) + * + * 5-8 WD_STEP_COUNT Number of steps the WD timer supports in 2^X + * (X bit available for defining the value) + * + * + * + **/ +int get_wd_set_caps_rd(int if_index); + +/** + * set_bypass - set Bypass state + * @if_index: network device index of the controlling device + * @bypass_mode: bypass mode (1=on, 0=off) + * Output: + * 0 - on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int set_bypass_rd(int if_index, int bypass_mode); + +/** + * get_bypass - Get Bypass mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_bypass_rd(int if_index); + +/** + * get_bypass_change - Get change of Bypass mode state from last status check + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_bypass_change_rd(int if_index); + +/** + * set_dis_bypass - Set Disable Bypass mode + * @if_index: network device index of the controlling device + * @dis_bypass: disable bypass(1=dis, 0=en) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_dis_bypass_rd(int if_index, int dis_bypass); + +/** + * get_dis_bypass - Get Disable Bypass mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (normal Bypass mode/ Disable bypass) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_dis_bypass_rd(int if_index); + +/** + * set_bypass_pwoff - Set Bypass mode at power-off state + * @if_index: network device index of the controlling device + * @bypass_mode: bypass mode setting at power off state (1=BP en, 0=BP Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_bypass_pwoff_rd(int if_index, int bypass_mode); + + +/** + * get_bypass_pwoff - Get Bypass mode state at power-off state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable bypass at power off state / normal Bypass mode) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_bypass_pwoff_rd(int if_index); + +/** + * set_bypass_pwup - Set Bypass mode at power-up state + * @if_index: network device index of the controlling device + * @bypass_mode: bypass mode setting at power up state (1=BP en, 0=BP Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_bypass_pwup_rd(int if_index, int bypass_mode); + +/** + * get_bypass_pwup - Get Bypass mode state at power-up state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable bypass at power up state / normal Bypass mode) + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_bypass_pwup_rd(int if_index); + +/** + * set_bypass_wd - Set watchdog state + * @if_index: network device index of the controlling device + * @ms_timeout: requested timeout (in ms units), 0 for disabling the watchdog timer + * @ms_timeout_set(output): requested timeout (in ms units), + * that the adapter supports and will be used by the watchdog + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_bypass_wd_rd(int if_index, int ms_timeout, int *ms_timeout_set); + +/** + * get_bypass_wd - Get watchdog state + * @if_index: network device index of the controlling device + * @ms_timeout (output): WDT timeout (in ms units), + * -1 for unknown wdt status + * 0 if WDT is disabled + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_bypass_wd_rd(int if_index, int *ms_timeout_set); + +/** + * get_wd_expire_time - Get watchdog expire + * @if_index: network device index of the controlling device + * @ms_time_left (output): time left till watchdog time expire, + * -1 if WDT has expired + * 0 if WDT is disabled + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int get_wd_expire_time_rd(int if_index, int *ms_time_left); + +/** + * reset_bypass_wd_timer - Reset watchdog timer + * @if_index: network device index of the controlling device + * + * Output: + * 1 - on success + * 0 - watchdog is not configured + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int reset_bypass_wd_timer_rd(int if_index); + +/** + * set_std_nic - Standard NIC mode of operation + * @if_index: network device index of the controlling device + * @nic_mode: 0/1 (Default Bypass mode / Standard NIC mode) + * + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int set_std_nic_rd(int if_index, int nic_mode); + +/** + * get_std_nic - Get Standard NIC mode setting + * @if_index: network device index of the controlling device + * + * Output: + * 0/1 (Default Bypass mode / Standard NIC mode) on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device) + **/ +int get_std_nic_rd(int if_index); + +/** + * set_tx - set transmitter enable/disable + * @if_index: network device index of the controlling device + * @tx_state: 0/1 (Transmit Disable / Transmit Enable) + * + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ) + **/ +int set_tx_rd(int if_index, int tx_state); + +/** + * get_tx - get transmitter state (disable / enable) + * @if_index: network device index of the controlling device + * + * Output: + * 0/1 (ransmit Disable / Transmit Enable) on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass) + **/ +int get_tx_rd(int if_index); + + +/** + * set_tpl - set TPL enable/disable + * @if_index: network device index of the controlling device + * @tx_state: 0/1 (TPL Disable / TPL Enable) + * + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ) + **/ +int set_tpl_rd(int if_index, int tpl_state); + +/** + * get_tpl - get TPL state (disable / enable) + * @if_index: network device index of the controlling device + * + * Output: + * 0/1 (TPL Disable / TPL Enable) on success + * -1 - on failure (device is not capable of the operation) + **/ +int get_tpl_rd(int if_index); + + +int get_bp_hw_reset_rd(int if_index); + +int set_bp_hw_reset_rd(int if_index, int status); + + + +#if 0 +/** + * set_tap - set TAP state + * @if_index: network device index of the controlling device + * @tap_mode: 1 tap mode , 0 normal nic mode + * Output: + * 0 - on success + * -1 - on failure (device not support TAP or it's a slave device) + **/ +int set_tap_rd(int if_index, int tap_mode); + +/** + * get_tap - Get TAP mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support TAP or it's a slave device) + **/ +int get_tap_rd(int if_index); + +/** + * get_tap_change - Get change of TAP mode state from last status check + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support TAP or it's a slave device) + **/ +int get_tap_change_rd(int if_index); + +/** + * set_dis_tap - Set Disable TAP mode + * @if_index: network device index of the controlling device + * @dis_tap: disable tap(1=dis, 0=en) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int set_dis_tap_rd(int if_index, int dis_tap); + +/** + * get_dis_tap - Get Disable TAP mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (normal TAP mode/ Disable TAP) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int get_dis_tap_rd(int if_index); + +/** + * set_tap_pwup - Set TAP mode at power-up state + * @if_index: network device index of the controlling device + * @bypass_mode: tap mode setting at power up state (1=TAP en, 0=TAP Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int set_tap_pwup_rd(int if_index, int tap_mode); + +/** + * get_tap_pwup - Get TAP mode state at power-up state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable TAP at power up state / normal TAP mode) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int get_tap_pwup_rd(int if_index); +#endif +/** + * set_wd_exp_mode - Set adapter state when WDT expired. + * @if_index: network device index of the controlling device + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * Output: + * 0 - on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int set_wd_exp_mode_rd(int if_index, int bypass_mode); + +/** + * get_wd_exp_mode - Get adapter state when WDT expired. + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (bypass/tap) on success + * -1 - on failure (device not support Bypass or it's a slave device) + **/ +int get_wd_exp_mode_rd(int if_index); + +/** + * set_wd_autoreset - reset WDT periodically. + * @if_index: network device index of the controlling device + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * Output: + * 1 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int set_wd_autoreset_rd(int if_index, int time); + +/** + * set_wd_autoreset - reset WDT periodically. + * @if_index: network device index of the controlling device + * @bypass_mode: adapter mode (1=tap mode, 0=bypass mode) + * Output: + * 1 - on success + * -1 - on failure (device is not capable of the operation ordevice not support Bypass + * or it's a slave device or unknown wdt status) + **/ +int get_wd_autoreset_rd(int if_index); +/** + * set_disc - set DISC state + * @if_index: network device index of the controlling device + * @tap_mode: 1 DISC mode , 0 normal nic mode + * Output: + * 0 - on success + * -1 - on failure (device not support disconnect or it's a slave device) + **/ +int set_bp_disc_rd(int if_index, int disc_mode); + +/** + * get_disc - Get disc mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support disconnect or it's a slave device) + **/ +int get_bp_disc_rd(int if_index); + +/** + * get_disc_change - Get change of DISC mode state from last status check + * @if_index: network device index of the controlling device + * Output: + * 0/1 - (off/on) on success + * -1 - on failure (device not support disconnect or it's a slave device) + **/ +int get_bp_disc_change_rd(int if_index); + +/** + * set_dis_disc - Set Disable DISC mode + * @if_index: network device index of the controlling device + * @dis_disc: disable disconnect(1=dis, 0=en) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support DISC + * or it's a slave device) + **/ +int set_bp_dis_disc_rd(int if_index, int dis_disc); + +/** + * get_dis_disc - Get Disable DISC mode state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (normal DISC mode/ Disable DISC) + * -1 - on failure (device is not capable of the operation ordevice not support TAP + * or it's a slave device) + **/ +int get_bp_dis_disc_rd(int if_index); + +/** + * set_disc_pwup - Set DISC mode at power-up state + * @if_index: network device index of the controlling device + * @disc_mode: DISC mode setting at power up state (1= en, 0= Dis) + * Output: + * 0 - on success + * -1 - on failure (device is not capable of the operation ordevice not support DISC + * or it's a slave device) + **/ +int set_bp_disc_pwup_rd(int if_index, int disc_mode); + +/** + * get_disc_pwup - Get DISC mode state at power-up state + * @if_index: network device index of the controlling device + * Output: + * 0/1 - on success (Disable DISC at power up state / normal DISC mode) + * -1 - on failure (device is not capable of the operation ordevice not support DISC + * or it's a slave device) + **/ +int get_bp_disc_pwup_rd(int if_index); + + + +int get_bypass_info_rd(int if_index, struct bp_info *bp_info); +int bp_if_scan_rd(void); +/*int get_dev_num_rd(void);*/ + + + + + + + diff --git a/readme.txt b/readme.txt new file mode 100755 index 0000000..41c4b1b --- /dev/null +++ b/readme.txt @@ -0,0 +1,100 @@ + Silicom Linux Bypass-SD Control Utility + +1. Compiling, installing and loading the software. + + Compiling and installing the software in the system directory: + # make install + +2. Software loading: + # bprdctl_start + +3. Using the software. + +3.1 Utility. + +Usage: bprdctl_util [parameters] + bprdctl_util + - interface name, for example, eth0, or all for all Bypass-SD/TAP-SD Control devices + - bypass control command (see Commands List). +[parameters] - set_bypass_wd command: + WDT timeout interval, msec (0 for disabling WDT). + set_bypass/set_bypass_pwoff/set_bypass_pwup/set_dis_bypass commands: + on/off for enable/disable Bypass + set_std_nic command: + on/off for enable/disable Standard NIC mode + set_tx command: + on/off for enable/disable transmit + set_tpl command: + on/off for enable/disable TPL + set_hw_reset command: + on/off for enable/disable hw_reset + set_tap/set_tap_pwup/set_dis_tap commands: + on/off for enable/disable TAP + set_disc/set_disc_pwup/set_dis_disc commands: + on/off for enable/disable Disc + set_wd_exp_mode command: + bypass/tap/disc for bypass/tap/disc mode + set_wd_autoreset command: + WDT autoreset interval, msec (0 for disabling WDT autoreset). +if_scan - refresh the list of network interfaces. +info - print Program Information. +help - print this message. + Commands List: +is_bypass - check if device is a Bypass/TAP controlling device +get_bypass_slave - get the second port participate in the Bypass/TAP pair +get_bypass_caps - obtain Bypass/TAP capabilities information +get_wd_set_caps - obtain watchdog timer settings capabilities +get_bypass_info - get bypass/TAP info +set_bypass - set Bypass mode state +get_bypass - get Bypass mode state +get_bypass_change - get change of Bypass mode state from last status check +set_dis_bypass - set Disable Bypass mode +get_dis_bypass - get Disable Bypass mode state +set_bypass_pwoff - set Bypass mode at power-off state +get_bypass_pwoff - get Bypass mode at power-off state +set_bypass_pwup - set Bypass mode at power-up state +get_bypass_pwup - get Bypass mode at power-up state +set_std_nic - set Standard NIC mode of operation +get_std_nic - get Standard NIC mode settings +set_bypass_wd - set watchdog state +get_bypass_wd - get watchdog state +get_wd_time_expire - get watchdog expired time +reset_bypass_wd - reset watchdog timer +set_tx - set transmit enable / disable +get_tx - get transmitter state (enabled / disabled) +set_tpl - set TPL enable / disable +get_tpl - get TPL state (enabled / disabled) +set_hw_reset - set hw_reset enable / disable +get_hw_reset - get hw_reset (enabled / disabled) +set_tap - set TAP mode state +get_tap - get TAP mode state +get_tap_change - get change of TAP mode state from last status check +set_dis_tap - set Disable TAP mode +get_dis_tap - get Disable TAP mode state +set_tap_pwup - set TAP mode at power-up state +get_tap_pwup - get TAP mode at power-up state +set_disc - set Disc mode state +get_disc - get Disc mode state +get_disc_change - get change of Disc mode state from last status check +set_dis_disc - set Disable Disc mode +get_dis_disc - get Disable Disc mode state +set_disc_pwup - set Disc mode at power-up state +get_disc_pwup - get Disc mode at power-up state +set_wd_exp_mode - set adapter state when WDT expired +get_wd_exp_mode - get adapter state when WDT expired +set_wd_autoreset - set WDT autoreset mode +get_wd_autoreset - get WDT autoreset mode + +Example: bprdctl_util eth0 set_bypass_wd 5000 + bprdctl_util all set_bypass on + bprdctl_util eth0 set_wd_exp_mode tap + bprdctl_util 0b:00.0 get_bypass_info + +4. Software unloading. + + # bprdctl_stop + +5. Uninstall. + + # make uninstall + diff --git a/release.txt b/release.txt new file mode 100755 index 0000000..8fecd4b --- /dev/null +++ b/release.txt @@ -0,0 +1,46 @@ + Release Notes + Silicom Linux Bypass-SD Control Utility + Version 1.0.13 + 05/09/2019 +v1.0.13 +- Added support for kernel 4.15 + +v1.0.12 +- Fixed mng port detection for adapters with PLX + +v1.0.11 +- Added support for Bypass 100G + +v1.0.10 +- Added support for SET_TPL for 40G adapter. + +v1.0.9 +- Added support for SET_TX for 40G adapter. + +v1.0.8 +- Added support for PE310G4DBiR-T. + +v1.0.7 +- Removed debug printout. + +v1.0.6 +- Added mux semaphore support. + +v1.0.1.3 +- Fixed get_wd_expire. + +v1.0.1.2 +- Fixed get_bypass_slave for 2x40. + +v1.0.1.2 +- Fixed device_num (all) for 4x10. +- Fixed help. + +v1.0.0 +- Initial version, lock free. + + + + + +