From 708f90ee7616739125269c325e727120cd15d711 Mon Sep 17 00:00:00 2001 From: Silicom Ltd Date: Tue, 18 Jun 2019 14:22:49 +0000 Subject: [PATCH] Upstream release 5.2.0.41 --- Makefile | 407 ++-- bits.h | 32 - bnx2x_reg.h | 32 - bp_cmd.h | 675 +++++++ bp_cmd_vm.h | 506 +++++ bp_ioctl.h | 3 + bp_mod.c | 5453 ++++++++++++++++++++++++++++++++++++++++++++------- bp_mod.h | 249 ++- bp_msg.h | 4 +- bp_util.c | 230 ++- bp_util.h | 8 +- bpctl_start | 33 - bpctl_stop | 33 - bypass.h | 12 +- common.mk | 335 ++++ libbp_sd.h | 2 +- release.txt | 110 +- 17 files changed, 6888 insertions(+), 1236 deletions(-) create mode 100755 bp_cmd.h create mode 100755 bp_cmd_vm.h create mode 100755 common.mk diff --git a/Makefile b/Makefile index c1b3028..b4f0272 100755 --- a/Makefile +++ b/Makefile @@ -1,301 +1,134 @@ +################################################################################ +# +# 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=5.0.65.1 - - -# core driver files -CFILES = bp_mod.c -HFILES = bp_mod.h +MOD_VER=5.2.0.41 PRDPATH_UTIL=/bin TARGET_UTIL=bpctl_util -OBJS = bp_util.o +OBJS_UTIL = bp_util.o -ifeq (,$(BUILD_KERNEL)) -BUILD_KERNEL=$(shell uname -r) -endif +ifneq ($(KERNELRELEASE),) +# kbuild part of makefile +# +# Makefile for the Intel(R) 10GbE PCI Express Linux Network Driver +# + +obj-$(CONFIG_BPCTL_MOD) += bpctl_mod.o + +define bpctl_mod-y + bp_mod.o +endef +bpctl_mod-y := $(strip ${bpctl_mod-y}) -########################################################################### -# Environment tests +else # ifneq($(KERNELRELEASE),) +# normal makefile -# Kernel Search Path -# All the places we look for kernel source -KSP := /lib/modules/$(BUILD_KERNEL)/build \ - /lib/modules/$(BUILD_KERNEL)/source \ - /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 +DRIVER := bpctl_mod -# prune the list down to only values that exist -# and have an include/linux sub-directory -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) +ifeq (,$(wildcard common.mk)) + $(error Cannot find common.mk build rules) else -ifeq (/lib/modules/$(BUILD_KERNEL)/source, $(KSRC)) - KOBJ := /lib/modules/$(BUILD_KERNEL)/build -else - KOBJ := $(KSRC) -endif + include common.mk 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 - -# 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)) - -# 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)) +# Check that kernel version is at least 2.6.0, since we don't support 2.4.x +# kernels with the BPCTL 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 -ifeq (,$(wildcard $(VERSION_FILE))) - $(error Linux kernel source not configured - missing version header file) -endif +###################### +# Kernel Build Macro # +###################### -ifeq (,$(wildcard $(CONFIG_FILE))) - $(error Linux kernel source not configured - missing autoconf.h) -endif +# 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}) -# pick a compiler -ifneq (,$(findstring egcs-2.91.66, $(shell cat /proc/version))) - CC := kgcc gcc cc -else - CC := gcc cc -endif -test_cc = $(shell $(cc) --version > /dev/null 2>&1 && echo $(cc)) -CC := $(foreach cc, $(CC), $(test_cc)) -CC := $(firstword $(CC)) -ifeq (,$(CC)) - $(error Compiler not found) -endif +############### +# Build rules # +############### -# we need to know what platform the driver is being built on -# some additional features are only built on Intel platforms -ARCH := $(shell uname -m | sed 's/i.86/i386/') -ifeq ($(ARCH),alpha) - EXTRA_CFLAGS += -ffixed-8 -mno-fp-regs -endif -ifeq ($(ARCH),x86_64) - EXTRA_CFLAGS += -mcmodel=kernel -mno-red-zone -endif -ifeq ($(ARCH),ppc) - EXTRA_CFLAGS += -msoft-float -endif -ifeq ($(ARCH),ppc64) - EXTRA_CFLAGS += -m64 -msoft-float - LDFLAGS += -melf64ppc -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 += -DBP_SELF_TEST -#EXTRA_CFLAGS += -DBP_LINK_FAIL_NOTIFIER -EXTRA_CFLAGS += -DBP_PROC_SUPPORT -#EXTRA_CFLAGS += -DBP_DBI_FLAG -# extra flags for module builds -EXTRA_CFLAGS += -DDRIVER_$(shell echo $(DRIVER_NAME) | tr '[a-z]' '[A-Z]') -EXTRA_CFLAGS += -DDRIVER_NAME=$(DRIVER_NAME) -EXTRA_CFLAGS += -DDRIVER_NAME_CAPS=$(shell echo $(DRIVER_NAME) | tr '[a-z]' '[A-Z]') -# standard flags for module builds -EXTRA_CFLAGS += -DLINUX -D__KERNEL__ -DMODULE -O2 -pipe -Wall -EXTRA_CFLAGS += -I$(KSRC)/generated/uapi -I$(KSRC)/include -I. -EXTRA_CFLAGS += $(shell [ -f $(KSRC)/include/linux/modversions.h ] && \ - echo "-DMODVERSIONS -DEXPORT_SYMTAB \ - -include $(KSRC)/include/linux/modversions.h") - -EXTRA_CFLAGS += $(CFLAGS_EXTRA) - -RHC := $(KSRC)/include/linux/rhconfig.h -ifneq (,$(wildcard $(RHC))) - # 7.3 typo in rhconfig.h - ifneq (,$(shell $(CC) $(CFLAGS) -E -dM $(RHC) | grep __module__bigmem)) - EXTRA_CFLAGS += -D__module_bigmem - endif -endif - -# 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),$(shell readlink /lib/modules/$(KVER)/build)) - KOBJ=/lib/modules/$(KVER)/build -endif -endif - -KVER_CODE := $(shell $(CC) $(EXTRA_CFLAGS) -E -dM $(VSP) 2>/dev/null |\ - grep -m 1 LINUX_VERSION_CODE | awk '{ print $$3 }' | sed 's/\"//g') - -# abort the build on kernels older than 2.4.0 -ifneq (1,$(shell [ $(KVER_CODE) -ge 132096 ] && echo 1 || echo 0)) - $(error *** Aborting the build. \ - *** This driver is not supported on kernel versions older than 2.4.0) -endif - - - -# set the install path -INSTDIR := /lib/modules/$(KVER)/kernel/drivers/net/$(DRIVER_NAME) - -# look for SMP in config.h -SMP := $(shell $(CC) $(EXTRA_CFLAGS) -E -dM $(CONFIG_FILE) | \ - grep -w CONFIG_SMP | awk '{ print $$3 }') -ifneq ($(SMP),1) - SMP := 0 -endif - -ifneq ($(SMP),$(shell uname -a | grep SMP > /dev/null 2>&1 && echo 1 || echo 0)) - $(warning ***) - ifeq ($(SMP),1) - $(warning *** Warning: kernel source configuration (SMP)) - $(warning *** does not match running kernel (UP)) - else - $(warning *** Warning: kernel source configuration (UP)) - $(warning *** does not match running kernel (SMP)) - endif - $(warning *** Continuing with build,) - $(warning *** resulting driver may not be what you want) - $(warning ***) -endif - -ifeq ($(SMP),1) - EXTRA_CFLAGS += -D__SMP__ -endif - -########################################################################### -# Kernel Version Specific rules - -ifeq (1,$(shell [ $(KVER_CODE) -ge 132352 ] && echo 1 || echo 0)) - -# Makefile for 2.5.x and newer kernel -TARGET = bpctl_mod.ko - -# man page -MANSECTION = 7 -MANFILE = $(TARGET:.ko=.$(MANSECTION)) - -ifneq ($(PATCHLEVEL),) -EXTRA_CFLAGS += $(CFLAGS_EXTRA) -obj-m += bpctl_mod.o -bpctl_mod-objs := $(CFILES:.c=.o) -else +# Standard compilation, with regular output default: $(TARGET_UTIL) -ifeq ($(KOBJ),$(KSRC)) - $(MAKE) -C $(KSRC) SUBDIRS=$(shell pwd) modules -else - $(MAKE) -C $(KSRC) O=$(KOBJ) SUBDIRS=$(shell pwd) modules -endif -endif + @+$(call devkernelbuild,modules) -else # ifeq (1,$(shell [ $(KVER_CODE) -ge 132352 ] && echo 1 || echo 0)) +# Noisy output, for extra debugging +noisy: + @+$(call devkernelbuild,modules,V=1) -# Makefile for 2.4.x kernel -TARGET = bpctl_mod.o +# Silence any output generated +silent: + @+$(call devkernelbuild,modules,>/dev/null) -# man page -MANSECTION = 7 -MANFILE = $(TARGET:.o=.$(MANSECTION)) +# Enable higher warning level +checkwarnings: clean + @+$(call devkernelbuild,modules,W=1) -# Get rid of compile warnings in kernel header files from SuSE -ifneq (,$(wildcard /etc/SuSE-release)) - EXTRA_CFLAGS += -Wno-sign-compare -fno-strict-aliasing -endif +# Run sparse static analyzer +sparse: clean + @+$(call devkernelbuild,modules,C=2 CF="-D__CHECK_ENDIAN__ -Wbitwise -Wcontext") -# Get rid of compile warnings in kernel header files from fedora -ifneq (,$(wildcard /etc/fedora-release)) - EXTRA_CFLAGS += -fno-strict-aliasing -endif -CFLAGS += $(EXTRA_CFLAGS) - -.SILENT: $(TARGET) -$(TARGET): $(filter-out $(TARGET), $(CFILES:.c=.o)) - $(LD) $(LDFLAGS) -r $^ -o $@ - echo; echo - echo "**************************************************" - echo "** $(TARGET) built for $(KVER)" - echo -n "** SMP " - if [ "$(SMP)" = "1" ]; \ - then echo "Enabled"; else echo "Disabled"; fi - echo "**************************************************" - echo - -$(CFILES:.c=.o): $(HFILES) Makefile -default: - $(MAKE) - -endif # ifeq (1,$(shell [ $(KVER_CODE) -ge 132352 ] && echo 1 || echo 0)) +# Run coccicheck static analyzer +ccc: clean + @+$(call devkernelbuild,modules,coccicheck MODE=report)) -# depmod version for rpm builds -DEPVER := $(shell /sbin/depmod -V 2>/dev/null | \ - awk 'BEGIN {FS="."} NR==1 {print $$2}') +# Clean the module subdirectories +clean: + @+$(call devkernelbuild,clean) + @-rm -rf *.ko + rm -rf $(OBJS_UTIL) $(TARGET_UTIL) -########################################################################### -# Build rules - -install: default - # remove all old versions of the driver - find $(INSTALL_MOD_PATH)/lib/modules/$(KVER) -name $(TARGET) -exec rm -f {} \; || true - find $(INSTALL_MOD_PATH)/lib/modules/$(KVER) -name $(TARGET).gz -exec rm -f {} \; || true - install -D -m 777 $(TARGET) $(INSTALL_MOD_PATH)$(INSTDIR)/$(TARGET) -ifeq (,$(INSTALL_MOD_PATH)) - /sbin/depmod -a || true -else - ifeq ($(DEPVER),1 ) - /sbin/depmod -r $(INSTALL_MOD_PATH) -a || true - else - /sbin/depmod -b $(INSTALL_MOD_PATH) -a -n $(KVERSION) > /dev/null || true - endif -endif +# 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 bpctl_start $(INSTALL_MOD_PATH)$(PRDPATH_UTIL) - install bpctl_stop $(INSTALL_MOD_PATH)$(PRDPATH_UTIL) + install bpctl_stop $(INSTALL_MOD_PATH)$(PRDPATH_UTIL) + +$(TARGET_UTIL): $(OBJS_UTIL) + $(CC) $(OBJS_UTIL) -g -Wall -o $(TARGET_UTIL) -$(TARGET_UTIL): $(OBJS) -$(OBJS): bp_util.c - $(CC) $(CFLAGS) -c bp_util.c -DBP_DBI_FLAG -DPMC_FIX_FLAG -DVER_STR_SET="\"$(MOD_VER)\"" - - $(CC) $(OBJS) -o $(TARGET_UTIL) uninstall: - if [ -e $(INSTDIR)/$(TARGET) ] ; then \ - rm -f $(INSTDIR)/$(TARGET) ; \ - fi - /sbin/depmod -a + 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 @@ -304,14 +137,34 @@ uninstall: fi if [ -e $(INSTALL_MOD_PATH)$(PRDPATH_UTIL)/bpctl_stop ] ; then \ rm -f $(INSTALL_MOD_PATH)$(PRDPATH_UTIL)/bpctl_stop ; \ - fi -.PHONY: clean install + fi -clean: -ifeq ($(KOBJ),$(KSRC)) - $(MAKE) -C $(KSRC) SUBDIRS=$(shell pwd) clean -else - $(MAKE) -C $(KSRC) O=$(KOBJ) SUBDIRS=$(shell pwd) clean -endif - rm -rf $(TARGET) $(TARGET:.ko=.o) $(TARGET:.ko=.mod.c) $(TARGET:.ko=.mod.o) $(CFILES:.c=.o) .*cmd .tmp_versions $(OBJS) $(TARGET_UTIL) Module.symvers Modules.symvers modules.order Module.markers - +######## +# 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 index aa5daad..693c5e6 100755 --- a/bits.h +++ b/bits.h @@ -1,35 +1,3 @@ -/************************************************************************** - -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 BITS_H #define BITS_H diff --git a/bnx2x_reg.h b/bnx2x_reg.h index b2da915..11abb12 100755 --- a/bnx2x_reg.h +++ b/bnx2x_reg.h @@ -1,35 +1,3 @@ -/************************************************************************** - -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. - -***************************************************************************/ /* [R 19] Interrupt register #0 read */ 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_cmd_vm.h b/bp_cmd_vm.h new file mode 100755 index 0000000..001a42f --- /dev/null +++ b/bp_cmd_vm.h @@ -0,0 +1,506 @@ +#ifndef __BP_CMD_VM_H__ +#define __BP_CMD_VM_H__ + +//#define FW_HEADER_DEF 1 + +#ifndef FW_HEADER_DEF +#ifndef U32_T +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 +#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_VM_GET_BYPASS_CAPS 1 +#define CMD_VM_GET_WD_SET_CAPS 2 +#define CMD_VM_SET_BYPASS 3 +#define CMD_VM_GET_BYPASS 4 +#define CMD_VM_GET_BYPASS_CHANGE 5 +#define CMD_VM_SET_BYPASS_WD 6 +#define CMD_VM_GET_BYPASS_WD 7 +#define CMD_VM_GET_WD_EXPIRE_TIME 8 +#define CMD_VM_RESET_BYPASS_WD_TIMER 9 +#define CMD_VM_SET_DIS_BYPASS 10 +#define CMD_VM_GET_DIS_BYPASS 11 +#define CMD_VM_SET_BYPASS_PWOFF 12 +#define CMD_VM_GET_BYPASS_PWOFF 13 +#define CMD_VM_SET_BYPASS_PWUP 14 +#define CMD_VM_GET_BYPASS_PWUP 15 +#define CMD_VM_SET_STD_NIC 16 +#define CMD_VM_GET_STD_NIC 17 +#define CMD_VM_SET_TAP 18 +#define CMD_VM_GET_TAP 19 +#define CMD_VM_GET_TAP_CHANGE 20 +#define CMD_VM_SET_DIS_TAP 21 +#define CMD_VM_GET_DIS_TAP 22 +#define CMD_VM_SET_TAP_PWUP 23 +#define CMD_VM_GET_TAP_PWUP 24 +#define CMD_VM_SET_WD_EXP_MODE 25 +#define CMD_VM_GET_WD_EXP_MODE 26 +#define CMD_VM_SET_DISC 27 +#define CMD_VM_GET_DISC 28 +#define CMD_VM_GET_DISC_CHANGE 29 +#define CMD_VM_SET_DIS_DISC 30 +#define CMD_VM_GET_DIS_DISC 31 +#define CMD_VM_SET_DISC_PWUP 32 +#define CMD_VM_GET_DISC_PWUP 33 + +#define CMD_VM_SET_WD_AUTORESET 34 +#define CMD_VM_GET_WD_AUTORESET 35 + +#define CMD_VM_SET_TPL 36 +#define CMD_VM_GET_TPL 37 +#define CMD_VM_GET_BYPASS_SLAVE 38 +#define CMD_VM_IS_BYPASS 39 +#define CMD_VM_SET_TX 40 +#define CMD_VM_GET_TX 41 + + +#define CMD_VM_GET_BYPASS_INFO 100 +#define CMD_VM_GET_BP_WAIT_AT_PWUP 101 +#define CMD_VM_SET_BP_WAIT_AT_PWUP 102 +#define CMD_VM_GET_BP_HW_RESET 103 +#define CMD_VM_SET_BP_HW_RESET 104 +#define CMD_VM_SET_BP_MANUF 105 + +#define CMD_VM_GET_BPNIC_INFO 106 +#define CMD_VM_GET_BP_PCI_INFO 107 +#define CMD_VM_GET_BP_ALL_INFO 108 + + +#define CMD_VM_GET_BP_DEV_NUM 109 +#define CMD_VM_GET_BP_DRV_VER 110 +#define CMD_VM_GET_BP_OEM_DATA 111 + +#define CMD_VM_SET_BP_BLINK 112 + + + +typedef U8_T cmd_vm_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_vm_rsp_id_t; + + + + +typedef U8_T cmd_vm_bp_board_t; + + + +/* + * BP device info + */ +typedef struct _cmd_vm_bp_info_t { + cmd_vm_bp_board_t dev_id; + byte fw_ver; +}cmd_vm_bp_info_t; + + +/* + * BP command device number + */ +#define DEV_NUM_MAX 4 +typedef U8_T cmd_vm_dev_num_t; + + +/* + * BP command data lenth type + */ +typedef U8_T cmd_vm_data_len_t; + + +/* + * BP command data structure + */ +typedef union _cmd_vm_data_t { +#if 0 + /* + * CMD_GET_BYPASS_CAPS + */ +#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 +#endif + U32_T bypass_caps; + + + /* + * 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_STD_NIC + */ + /* + * CMD_GET_STD_NIC + */ +#define DEF_BYPASS_MODE 0 +#define STD_NIC_MODE 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 + + U8_T wd_exp_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_GET_BYPASS_INFO + */ + cmd_vm_bp_info_t bypass_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_vm_data_t; + + +/******************************************************\ +* * +* * +* * +\******************************************************/ +#define BP_CMD_PACKET_SIZE (sizeof(cmd_vm_dev_num_t) \ + + sizeof(cmd_vm_id_t) \ + + sizeof(cmd_vm_data_len_t) \ + + sizeof(cmd_vm_data_t)) + +typedef union _bp_cmd_vm_t { + byte cmd_vm_bytes[64]; // For Byte Access + + struct { + byte str[6]; + byte str1[6]; + byte type[2]; + U32_T multiplex_id; + U32_T request_id; + cmd_vm_dev_num_t cmd_vm_dev_num; + cmd_vm_id_t cmd_vm_id; + cmd_vm_data_len_t cmd_vm_data_len; + U32_T cmd_vm_data; + }cmd_vm; + +}bp_cmd_vm_t; + + +/******************************************************\ +* * +* * +* * +\******************************************************/ +#define BP_VM_RSP_PACKET_SIZE sizeof(cmd_vm_rsp_id_t) \ + + sizeof(cmd_vm_data_len_t) \ + + sizeof(cmd_vm_data_t) + +typedef union _bp_cmd_vm_rsp_t { + byte cmd_vm_bytes[64]; // For Byte Access + + struct { + byte str[6]; + byte str1[6]; + byte type[2]; + U32_T multiplex_id; + U32_T request_id; + cmd_vm_rsp_id_t rsp_id; + cmd_vm_data_len_t rsp_data_len; + U32_T rsp_data; + }rsp; + struct { + byte str[6]; + byte str1[6]; + byte type[2]; + U32_T multiplex_id; + U32_T request_id; + cmd_vm_rsp_id_t rsp_id; + byte fw_ver; + byte info[40]; + }rsp_info; +}bp_cmd_vm_rsp_t; + +#ifndef FW_HEADER_DEF + #pragma pack(pop) /* push current alignment to stack */ +#endif + +#endif /* End of __BP_CMD_VM_H__ */ diff --git a/bp_ioctl.h b/bp_ioctl.h index 66bed7a..e2b0c39 100755 --- a/bp_ioctl.h +++ b/bp_ioctl.h @@ -129,12 +129,15 @@ typedef enum { 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, diff --git a/bp_mod.c b/bp_mod.c index 6ae7a45..b3abc61 100755 --- a/bp_mod.c +++ b/bp_mod.c @@ -1,6 +1,6 @@ /************************************************************************** -Copyright (c) 2006-2013, Silicom +Copyright (c) 2005-2015, Silicom All rights reserved. Redistribution and use in source and binary forms, with or without @@ -30,6 +30,7 @@ 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 @@ -56,13 +57,27 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "bp_ioctl.h" #include "bp_mod.h" #include "bypass.h" #include "libbp_sd.h" +#include "bp_cmd.h" + #define SUCCESS 0 #define BP_MOD_VER VER_STR_SET @@ -70,12 +85,15 @@ POSSIBILITY OF SUCH DAMAGE. static int Device_Open = 0; static int major_num=0; +spinlock_t bypass_wr_lock; +static struct i2c_client *client = NULL; +static unsigned int na_base = 0; MODULE_AUTHOR("Anna Lukin, annal@silicom.co.il"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION(BP_MOD_DESCR); MODULE_VERSION(BP_MOD_VER); -spinlock_t bpvm_lock; +/*spinlock_t bpvm_lock;*/ @@ -87,7 +105,7 @@ if (down_interruptible(&bpctl_sema)) { \ #define unlock_bpctl() \ up(&bpctl_sema); - +int bp_shutdown = 0; /* Media Types */ typedef enum { bp_copper = 0, @@ -137,6 +155,9 @@ typedef struct _bpctl_dev { 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; @@ -156,6 +177,7 @@ typedef struct _bpctl_dev { bp_media_type media_type; int bp_tpl_flag; struct timer_list bp_tpl_timer; + int tpl_wait; spinlock_t bypass_wr_lock; int bp_10g; int bp_10gb; @@ -163,7 +185,9 @@ typedef struct _bpctl_dev { int bp_10g9; int bp_i80; int bp_540; -#ifdef BP_SELF_TEST + int bp_40g; + int bp_rang; +/* #ifdef BP_SELF_TEST */ int (*hard_start_xmit_save) (struct sk_buff *skb, struct net_device *dev); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) @@ -172,45 +196,79 @@ typedef struct _bpctl_dev { #endif int bp_self_test_flag; char *bp_tx_data; - -#endif + 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; +/* #endif */ struct bypass_pfs_sd bypass_pfs_set; char proc_dir[128]; } bpctl_dev_t; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,15,0)) + +#ifndef do_gettimeofday + +#define do_gettimeofday(x) _kc_do_gettimeofday(x) +static inline void _kc_do_gettimeofday(struct timeval *tv) +{ + struct timespec64 now; + + ktime_get_real_ts64(&now); + tv->tv_sec = now.tv_sec; + tv->tv_usec = now.tv_nsec/1000; +} + +#endif +#endif + 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/2)) + if ((tv_end.tv_usec-tv.tv_usec)<(x)) return 0; - } else if ((~tv.tv_usec+tv_end.tv_usec)<(x/2)) + } 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; + /* printk("bpmod: udelay failed!\n");*/ } - printk("bpmod: udelay failed!\n"); + /*printk("bpmod: udelay failed!!\n");*/ +#else + udelay(x); +#endif } void msec_delay_bp(unsigned long x){ +#ifdef BP_NDELAY_MODE + return; +#else int i; - if (1) { + if (in_interrupt()) { for (i = 0; i < 1000; i++) { usec_delay_bp(x) ; } } else { msleep(x); } +#endif } @@ -221,7 +279,11 @@ static bpctl_dev_t *bpctl_dev_b;*/ static bpctl_dev_t *bpctl_dev_arr; static struct semaphore bpctl_sema; -static int device_num=0; +static int device_num = 0; + +#ifdef ADI_RANGELEY_SUPPORT +static int na_device_num = 0; +#endif static int get_dev_idx(int ifindex); @@ -232,6 +294,9 @@ static int wdt_timer(bpctl_dev_t *pbpctl_dev, int *time_left); static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev); static void if_scan_init(void); +static int tx_status (bpctl_dev_t *pbpctl_dev); +static int set_tx (bpctl_dev_t *pbpctl_dev, int tx_state); + int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block); int bypass_proc_remove_dev_sd(bpctl_dev_t * pbp_device_block); int bp_proc_create(void); @@ -239,6 +304,10 @@ int bp_proc_create(void); int is_bypass_fn(bpctl_dev_t *pbpctl_dev); int get_dev_idx_bsf(int bus, int slot, int func); +int get_bypass_caps_fn(bpctl_dev_t *pbpctl_dev); +int get_wd_expire_fn (bpctl_dev_t *pbpctl_dev); + +int wdt_on(bpctl_dev_t *pbpctl_dev, unsigned int timeout); static int bp_get_dev_idx_bsf(struct net_device *dev, int *index) @@ -267,7 +336,14 @@ static int bp_get_dev_idx_bsf(struct net_device *dev, int *index) *index = get_dev_idx_bsf(bus, slot, func); return 0; } - +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) { @@ -276,16 +352,15 @@ static int bp_device_event(struct notifier_block *unused, #else struct net_device *dev = netdev_notifier_info_to_dev(ptr); #endif - static bpctl_dev_t *pbpctl_dev, *pbpctl_dev_m; + static bpctl_dev_t *pbpctl_dev, *pbpctl_dev_m, *pbpctl_dev2; int dev_num = 0, ret = 0, ret_d = 0, time_left = 0; - - /* printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); */ - /* return NOTIFY_DONE; */ + /*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; + int idx_dev; if (bp_get_dev_idx_bsf(dev, &idx_dev)) return NOTIFY_DONE; @@ -303,8 +378,8 @@ static int bp_device_event(struct notifier_block *unused, 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++) { + ((idx_dev < device_num) + && (bpctl_dev_arr[idx_dev].pdev != NULL)); idx_dev++) { if (bpctl_dev_arr[idx_dev].ndev == dev) { bypass_proc_remove_dev_sd(&bpctl_dev_arr [idx_dev]); @@ -320,8 +395,8 @@ static int bp_device_event(struct notifier_block *unused, 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++) { + ((idx_dev < device_num) + && (bpctl_dev_arr[idx_dev].pdev != NULL)); idx_dev++) { if (bpctl_dev_arr[idx_dev].ndev == dev) { bypass_proc_remove_dev_sd(&bpctl_dev_arr [idx_dev]); @@ -340,34 +415,70 @@ static int bp_device_event(struct notifier_block *unused, switch (event) { case NETDEV_CHANGE:{ - if (netif_carrier_ok(dev)) - return NOTIFY_DONE; + if (((dev_num = get_dev_idx(dev->ifindex)) == -1) || (!(pbpctl_dev = &bpctl_dev_arr[dev_num]))) return NOTIFY_DONE; - if ((is_bypass_fn(pbpctl_dev)) == 1) + if(bp_shutdown == 1) + return NOTIFY_DONE; + + if ((is_bypass_fn(pbpctl_dev)) == 1){ pbpctl_dev_m = pbpctl_dev; - else - pbpctl_dev_m = get_master_port_fn(pbpctl_dev); - if (!pbpctl_dev_m) + 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; - ret = bypass_status(pbpctl_dev_m); - if (ret == 1) - printk("bpmod: %s is in the Bypass mode now", - dev->name); - ret_d = disc_status(pbpctl_dev_m); - if (ret_d == 1) - printk - ("bpmod: %s is in the Disconnect mode now", - dev->name); - if (ret || ret_d) { - wdt_timer(pbpctl_dev_m, &time_left); - if (time_left == -1) - printk("; WDT has expired"); - printk(".\n"); + + if (netif_carrier_ok(dev)) { + if(pbpctl_dev_m->bp_tpl_flag){ + if (tx_status(pbpctl_dev)) { + pbpctl_dev->tpl_wait = 0; + if (!tx_status(pbpctl_dev2)) { + pbpctl_dev2->tpl_wait = 1; + set_tx(pbpctl_dev2, 1); + } + } + } + return NOTIFY_DONE; + } + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + ret = get_wd_expire_fn(pbpctl_dev_m); + if (ret == 1) + printk("bpmod: %s WDT has expired\n", dev->name); + } else { + ret = bypass_status(pbpctl_dev_m); + if (ret == 1) + printk("bpmod: %s is in the Bypass mode now", + dev->name); + ret_d = disc_status(pbpctl_dev_m); + if (ret_d == 1) + printk("bpmod: %s is in the Disconnect mode now", + dev->name); + if (ret || ret_d) { + wdt_timer(pbpctl_dev_m, &time_left); + if (time_left == -1) + printk("; WDT has expired"); + printk(".\n"); + + } + } + if(pbpctl_dev_m->bp_tpl_flag){ + if(pbpctl_dev_m->bp_tpl_flag){ + if (tx_status(pbpctl_dev)) { + if (tx_status(pbpctl_dev2)) + set_tx(pbpctl_dev2, 0); + } else + printk("bpmod: %s NIC Link is Down forse by TPL mode.\n", + dev->name); + + } } return NOTIFY_DONE; @@ -384,6 +495,9 @@ static int bp_device_event(struct notifier_block *unused, static struct notifier_block bp_notifier_block = { .notifier_call = bp_device_event, }; +static struct notifier_block bp_reboot_block = { + .notifier_call = bp_reboot_event, +}; @@ -407,7 +521,661 @@ static int device_release(struct inode *inode, struct file *file) return SUCCESS; } -int is_bypass_fn(bpctl_dev_t *pbpctl_dev); +/******************* I2C INTERFACE *****************************************************/ +static inline void setsda(bpctl_dev_t *pslcm_dev, unsigned char bit){ + writel(0x3f80010, (void *)((pslcm_dev->mem_map) + 0x88100)); + BP40G_RD_REG(pslcm_dev, GPIO_STAT); + if(bit) + writel(0x60, (void *)((pslcm_dev->mem_map) + 0x88184)); + else + writel(0x40, (void *)((pslcm_dev->mem_map) + 0x88184)); + BP40G_RD_REG(pslcm_dev, GPIO_STAT); +} + +static inline void setscl(bpctl_dev_t *pslcm_dev, unsigned char bit){ + writel(0x3f80010, (void *)((pslcm_dev->mem_map) + 0x88104)); + BP40G_RD_REG(pslcm_dev, GPIO_STAT); + if(bit) + writel(0x61, (void *)((pslcm_dev->mem_map) + 0x88184)); + else + writel(0x41, (void *)((pslcm_dev->mem_map) + 0x88184)); + BP40G_RD_REG(pslcm_dev, GPIO_STAT); +} + + +static inline void sdalo(bpctl_dev_t *pslcm_dev) +{ + + setsda(pslcm_dev, 0); + udelay((TIME_CLK + 1) / 2); +} + +static inline void sdahi(bpctl_dev_t *pslcm_dev) +{ + setsda(pslcm_dev, 1); + udelay((TIME_CLK + 1) / 2); +} + +static inline unsigned char getscl(bpctl_dev_t *pslcm_dev) +{ + unsigned char ctrl_ext; + writel(0x3f00000, (void *)((pslcm_dev->mem_map) + 0x88104)); + BP40G_RD_REG(pslcm_dev, GPIO_STAT); + ctrl_ext = BP40G_RD_REG(pslcm_dev, GPIO_STAT); + return ( (ctrl_ext&BIT_1)? 1:0); +} + +static inline unsigned char getsda(bpctl_dev_t *pslcm_dev) +{ + unsigned char ctrl_ext; + writel(0x3f00000, (void *)((pslcm_dev->mem_map) + 0x88100)); + BP40G_RD_REG(pslcm_dev, GPIO_STAT); + ctrl_ext = BP40G_RD_REG(pslcm_dev, GPIO_STAT); + return ( (ctrl_ext&BIT_0)? 1:0); +} + + +/* + * Raise scl line, and do checking for delays. This is necessary for slower + * devices. + */ +static int sclhi(bpctl_dev_t *pslcm_dev) +{ + unsigned long start; + + setscl(pslcm_dev, 1); + + /* Not all adapters have scl sense line... !!!*/ + + start = jiffies; + while (!getscl(pslcm_dev)) { + /* This hw knows how to read the clock line, so we wait + * until it actually gets high. This is safer as some + * chips may hold it low ("clock stretching") while they + * are processing data internally. + */ + if (time_after(jiffies, start + 5)) { + /* Test one last time, as we may have been preempted + * between last check and timeout test. + */ + if (getscl(pslcm_dev)) + break; + return -1; + } + cpu_relax(); + } + + udelay(TIME_CLK); + return 0; +} + +static inline void scllo(bpctl_dev_t *pslcm_dev) +{ + setscl(pslcm_dev, 0); + udelay(TIME_CLK / 2); +} + + + +/* --- other auxiliary functions -------------------------------------- */ +static void i2c_start(bpctl_dev_t *pslcm_dev) +{ + /* assert: scl, sda are high */ + sdahi(pslcm_dev); + sclhi(pslcm_dev); + setsda(pslcm_dev, 0); + udelay(TIME_CLK); + scllo(pslcm_dev); +} + +static void i2c_repstart(bpctl_dev_t *pslcm_dev) +{ + /* assert: scl is low */ + sdahi(pslcm_dev); + sclhi(pslcm_dev); + setsda(pslcm_dev, 0); + udelay(TIME_CLK); + scllo(pslcm_dev); +} + + +static void i2c_stop(bpctl_dev_t *pslcm_dev) +{ + /* assert: scl is low */ + sdalo(pslcm_dev); + sclhi(pslcm_dev); + setsda(pslcm_dev, 1); + udelay(TIME_CLK); +} + + + +/* send a byte without start cond., look for arbitration, + check ackn. from slave */ +/* returns: + * 1 if the device acknowledged + * 0 if the device did not ack + * -ETIMEDOUT if an error occurred (while raising the scl line) + */ +static int i2c_outb(bpctl_dev_t *pslcm_dev, unsigned char c) +{ + int i; + int sb; + int ack; + + /* assert: scl is low */ + for (i = 7; i >= 0; i--) { + sb = (c >> i) & 1; + setsda(pslcm_dev, sb); + udelay((TIME_CLK + 1) / 2); + if (sclhi(pslcm_dev) < 0) { /* timed out */ + printk("bpmod: timed out\n"); + return -1; + } + /* FIXME do arbitration here: + * if (sb && !getsda(adap)) -> ouch! Get out of here. + * + * Report a unique code, so higher level code can retry + * the whole (combined) message and *NOT* issue STOP. + */ + scllo(pslcm_dev); + } + sdahi(pslcm_dev); + if (sclhi(pslcm_dev) < 0) { /* timeout */ + /*printk("bpmod: i2c_outb: 0x%02x, " + "timeout at ack\n", (int)c);*/ + return -1; + } + + /* read ack: SDA should be pulled down by slave, or it may + * NAK (usually to report problems with the data we wrote). + */ + ack = !getsda(pslcm_dev); /* ack: sda is pulled low -> success */ + /*printk("bpmod: i2c_outb: 0x%02x %s\n", (int)c, + ack ? "A" : "NA");*/ + + scllo(pslcm_dev); + return ack; + /* assert: scl is low (sda undef) */ +} + + +static int i2c_inb(bpctl_dev_t *pslcm_dev) +{ + /* read byte via i2c port, without start/stop sequence */ + /* acknowledge is sent in i2c_read. */ + int i; + unsigned char indata = 0; + + /* assert: scl is low */ + sdahi(pslcm_dev); + for (i = 0; i < 8; i++) { + if (sclhi(pslcm_dev) < 0) { /* timeout */ + /*printk("bpmod: i2c_inb: timeout at bit " + "#%d\n", 7 - i);*/ + return -1; + } + indata *= 2; + if (getsda(pslcm_dev)) + indata |= 0x01; + setscl(pslcm_dev, 0); + udelay(i == 7 ? TIME_CLK / 2 : TIME_CLK); + } + /* assert: scl is low */ + return indata; +} + +/* + * Sanity check for the adapter hardware - check the reaction of + * the bus lines only if it seems to be idle. + */ +#if 0 +static int test_bus(bpctl_dev_t *pslcm_dev) +{ + + int scl, sda; + + sda = getsda(pslcm_dev); + scl = getscl(pslcm_dev); + if (!scl || !sda) { + printk("bpmod: bus seems to be busy (scl=%d, sda=%d)\n", + scl, sda); + goto bailout; + } + + sdalo(pslcm_dev); + sda = getsda(pslcm_dev); + scl = getscl(pslcm_dev); + if (sda) { + printk("bpmod: SDA stuck high!\n"); + goto bailout; + } + if (!scl) { + printk("bpmod: SCL unexpected low " + "while pulling SDA low!\n"); + goto bailout; + } + + sdahi(pslcm_dev); + sda = getsda(pslcm_dev); + scl = getscl(pslcm_dev); + if (!sda) { + printk("bpmod: SDA stuck low!\n"); + goto bailout; + } + if (!scl) { + printk("bpmod: SCL unexpected low " + "while pulling SDA high!\n"); + goto bailout; + } + + scllo(pslcm_dev); + sda = getsda(pslcm_dev); + scl = getscl(pslcm_dev); + if (scl) { + printk("bpmod: SCL stuck high!\n"); + goto bailout; + } + if (!sda) { + printk("bpmod: SDA unexpected low " + "while pulling SCL low!\n"); + goto bailout; + } + + sclhi(pslcm_dev); + sda = getsda(pslcm_dev); + scl = getscl(pslcm_dev); + if (!scl) { + printk(KERN_WARNING "bpmod: SCL stuck low!\n"); + goto bailout; + } + if (!sda) { + printk("bpmod: SDA unexpected low " + "while pulling SCL high!\n"); + goto bailout; + } + + /*printk("bpmod: Test OK\n");*/ + return 0; +bailout: + sdahi(pslcm_dev); + sclhi(pslcm_dev); + + return -ENODEV; +} +#endif + +/* ----- Utility functions + */ + +/* try_address tries to contact a chip for a number of + * times before it gives up. + * return values: + * 1 chip answered + * 0 chip did not answer + * -x transmission error + */ +static int try_address(bpctl_dev_t *pslcm_dev, + unsigned char addr, int retries) +{ + int i, ret = 0; + + for (i = 0; i <= retries; i++) { + ret = i2c_outb(pslcm_dev, addr); + if (ret == 1 || i == retries) + break; + /*printk("bpmod: emitting stop condition\n");*/ + i2c_stop(pslcm_dev); + udelay(TIME_CLK); + yield(); + /*printk("bpmod: emitting start condition\n");*/ + i2c_start(pslcm_dev); + } + /*if (i && ret) + printk("bpmod: Used %d tries to %s client at " + "0x%02x: %s\n", i + 1, + addr & 1 ? "read from" : "write to", addr >> 1, + ret == 1 ? "success" : "failed, timeout?");*/ + return ret; +} + +static int sendbytes(bpctl_dev_t *pslcm_dev, unsigned char *value, + unsigned int num_byte) +{ + int count =0; + int retval; + int wrcount = 0; + + do { + retval = i2c_outb(pslcm_dev, value[count]); + + /* OK/ACK; or ignored NAK */ + if (retval > 0) { + count++; + wrcount++; + + /* A slave NAKing the master means the slave didn't like + * something about the data it saw. For example, maybe + * the SMBus PEC was wrong. + */ + } else if (retval == 0) { + printk("bpmod: sendbytes: NAK bailout.\n"); + return -1; + + /* Timeout; or (someday) lost arbitration + * + * FIXME Lost ARB implies retrying the transaction from + * the first message, after the "winning" master issues + * its STOP. As a rule, upper layer code has no reason + * to know or care about this ... it is *NOT* an error. + */ + } else { + printk("bpmod: sendbytes: error %d\n", + retval); + return retval; + } + }while(count < num_byte); + return wrcount; +} + +static int acknak(bpctl_dev_t *pslcm_dev, int is_ack) +{ + + /* assert: sda is high */ + if (is_ack) /* send ack */ + setsda(pslcm_dev, 0); + udelay((TIME_CLK + 1) / 2); + if (sclhi(pslcm_dev) < 0) { /* timeout */ + printk("bpmod: readbytes: ack/nak timeout\n"); + return -1; + } + scllo(pslcm_dev); + return 0; +} + +static int readbytes(bpctl_dev_t *pslcm_dev, unsigned char *value, + unsigned int num_byte) +{ + int inval; + int rdcount = 0; /* counts bytes read */ + int count = 0; + + do { + inval = i2c_inb(pslcm_dev); + if (inval >= 0) { + value[count] = inval; + rdcount++; + } else { /* read timed out */ + break; + } + + count++; + + + /*printk("bpmod: readbytes: 0x%02x %s\n", + inval, + (count ? "A" : "NA"));*/ + + if(count == num_byte) + inval = acknak(pslcm_dev, 0); + else + inval = acknak(pslcm_dev, count); + if (inval < 0) + return inval; + } while(count < num_byte); + return rdcount; +} + +/* doAddress initiates the transfer by generating the start condition (in + * try_address) and transmits the address in the necessary format to handle + * reads, writes as well as 10bit-addresses. + * returns: + * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set + * -x an error occurred (like: -ENXIO if the device did not answer, or + * -ETIMEDOUT, for example if the lines are stuck...) + */ +static int bit_doAddress(bpctl_dev_t *pslcm_dev, unsigned char rd, unsigned char addr) +{ + int ret, retries; + + retries = 1; + + { /* normal 7bit address */ + if (rd) + addr |= 1; + ret = try_address(pslcm_dev, addr, retries); + if (ret != 1) + return -1; + } + + return 0; +} + +static int bit_xfer(bpctl_dev_t *pslcm_dev, + unsigned char rd, + unsigned char addr, + unsigned char *value, + unsigned int num_byte) +{ + int i, ret, num =1; + + /*printk("bpmod: emitting start condition\n");*/ + i2c_start(pslcm_dev); + for (i = 0; i < num; i++) { + if (i) { + printk("bpmod: emitting " + "repeated start condition\n"); + i2c_repstart(pslcm_dev); + } + ret = bit_doAddress(pslcm_dev, rd, addr); + if (ret != 0) { + printk("bpmod: NAK from " + "device addr 0x%02x\n", + addr); + goto bailout; + } + if (rd) { + /* read bytes into buffer*/ + ret = readbytes(pslcm_dev, value, num_byte); + /*if (ret >= 1) + printk("bpmod:read %d byte%s\n", + ret, ret == 1 ? "" : "s");*/ + if (ret < num_byte) { + if (ret >= 0) + ret = -1; + goto bailout; + } + } else { + /* write bytes from buffer */ + ret = sendbytes(pslcm_dev, value, num_byte); + /*if (ret >= 1) + printk("bpmod:wrote %d byte%s\n", + ret, ret == 1 ? "" : "s");*/ + if (ret < num_byte) { + if (ret >= 0) + ret = -1; + goto bailout; + } + } + } + ret = i; + +bailout: + /*printk("bpmod:emitting stop condition\n");*/ + i2c_stop(pslcm_dev); + return ret; +} + + + + +s32 bp_write_i2c_bytes(bpctl_dev_t *pslcm_dev, unsigned int num_byte, unsigned char *value, + unsigned char dev_addr) +{ + if (pslcm_dev->bp_rang) { + int ret; + unsigned char *tmp_value = value; + + + tmp_value++; + ret = i2c_smbus_write_i2c_block_data(client, *value, (u8) (num_byte - 1), tmp_value); + return num_byte; + + } else + return (bit_xfer(pslcm_dev, + 0, + dev_addr, + value, + num_byte)); + +} + + + + +s32 bp_read_i2c_bytes(bpctl_dev_t *pslcm_dev, unsigned char *value, + unsigned int num_byte, + unsigned int dev_addr) +{ + if (pslcm_dev->bp_rang) { + int ret; + char tmp = *value; + + value[0] = 0; + + ret = i2c_smbus_read_i2c_block_data(client, + tmp, (u8) (num_byte), value); + +#if 0 + printk("bpmod: i2c_smbus_read_block_data ret = %d\n", ret); + if(ret > 0) { + unsigned char *tmp_value; + + tmp_value = value; + for(i = 0; i < ret; i++){ + printk("bpmod val = %d\n", *tmp_value); + tmp_value++; + } + } +#endif + return ret; + + } else + return (bit_xfer(pslcm_dev, + 1, + dev_addr, + value, + num_byte)); + +} + + + +#if 1 //Pavelk +int set_bp_bytes_fn(bpctl_dev_t *pbpctl_dev, char *add_param){ + unsigned int ret=0; + + /*test_bus(pbpctl_dev);*/ + ret=bp_write_i2c_bytes(pbpctl_dev, 7, add_param, 0xae); + + return ret; +} + +int get_bp_bytes_fn(bpctl_dev_t *pbpctl_dev, char *add_param){ + char value[6]; + int ret=0; + + memset(value, 0, 6); + + value[0] = add_param[0]; + + ret=bp_read_i2c_bytes(pbpctl_dev, value, 6, 0xae); + + if(pbpctl_dev->bp_rang) { + if ((ret!=0) && (ret == 6)) { + memcpy(&add_param[0], value, 6); + return 0; + } + } else if (ret!=0) { + memcpy(&add_param[0], value, 6); + + return 0; + } + + return -1; +} + +#endif + + +int bp_cmd_request(bpctl_dev_t *pbpctl_dev, bp_cmd_t *bp_cmd_buf, bp_cmd_rsp_t *bp_rsp_buf) { + int ret_val; + byte data[120]; + int try_num = 10; + + atomic_set(&pbpctl_dev->wdt_busy,1); + /* + * Send command + */ + while (try_num--) { + memset(bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + + memcpy(&data[0], bp_cmd_buf, sizeof(bp_cmd_t)); + usec_delay_bp(CMND_INTERVAL); + + + if ((ret_val = set_bp_bytes_fn(pbpctl_dev, (char *)data))<0) { + printk("bp_cmd_request(write): Not supported!\n"); + continue; + // return 0; + } + usec_delay_bp(CMND_INTERVAL); +#if 1 + /* + * Receive replay + */ + memcpy(&data[0], bp_cmd_buf, sizeof(bp_cmd_t)); + if ((ret_val = get_bp_bytes_fn(pbpctl_dev, (char *)data))<0) { + printk("bp_cmd_request(read): Not supported!\n"); + continue; + //return 0; + } +#endif + + // if (bp_rsp_buf->rsp.rsp_id != BP_ERR_OK) + // continue; + + + memcpy(bp_rsp_buf, &data[0], sizeof(bp_cmd_rsp_t)); + +#if 0 + 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 + if(pbpctl_dev->bp_rang) { + if((bp_rsp_buf->rsp.rsp_id == 8) || + (bp_rsp_buf->rsp.rsp_id == 2)) + bp_rsp_buf->rsp.rsp_id = BP_ERR_OK; + } + + if (bp_rsp_buf->rsp.rsp_id != BP_ERR_OK) + continue; + + + break; + } + atomic_set(&pbpctl_dev->wdt_busy,0); + + if(!try_num) + return 0; + return 1; +} + +/*******************I2C INTERFACE END*****************************************************/ + int wdt_time_left (bpctl_dev_t *pbpctl_dev); @@ -890,7 +1658,7 @@ static void write_reg(bpctl_dev_t *pbpctl_dev, unsigned char value, unsigned cha // writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; } - usec_delay_bp(CMND_INTERVAL*4); + usec_delay_bp(CMND_INTERVAL); if ((pbpctl_dev->wdt_status==WDT_STATUS_EN)&& @@ -913,19 +1681,22 @@ static void write_data(bpctl_dev_t *pbpctl_dev, unsigned char value){ static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr){ uint32_t ctrl_ext=0, ctrl=0 , ctrl_value=0; bpctl_dev_t *pbpctl_dev_c=NULL; - - - #ifdef BP_SYNC_FLAG unsigned long flags; - spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); -#else - atomic_set(&pbpctl_dev->wdt_busy,1); #endif + if (pbpctl_dev->bp_10g9) { if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) return -1; } + + +#ifdef BP_SYNC_FLAG + spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); +#else + atomic_set(&pbpctl_dev->wdt_busy,1); +#endif + if (pbpctl_dev->bp_10g9) { @@ -1107,7 +1878,7 @@ static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr){ } - usec_delay_bp(CMND_INTERVAL*4); + usec_delay_bp(CMND_INTERVAL); #ifdef BP_SYNC_FLAG spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); #else @@ -1120,22 +1891,101 @@ static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr){ static int wdt_pulse(bpctl_dev_t *pbpctl_dev){ uint32_t ctrl_ext=0, ctrl=0; bpctl_dev_t *pbpctl_dev_c=NULL; - #ifdef BP_SYNC_FLAG unsigned long flags; - - spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); -#else - - if ((atomic_read(&pbpctl_dev->wdt_busy))==1) - return -1; #endif - if (pbpctl_dev->bp_10g9) { + if (!(pbpctl_dev->bp_caps&BP_CAP)) + return -1; + + if ((pbpctl_dev->bp_10g9)|| + (pbpctl_dev->bp_40g)|| + (pbpctl_dev->bp_rang)) { if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) return -1; } +#ifdef BP_SYNC_FLAG + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) + spin_lock_irqsave(&pbpctl_dev_c->bypass_wr_lock, flags); + else + spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); +#else + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + if ((atomic_read(&pbpctl_dev_c->wdt_busy))==1) + return -1; + } else { + if ((atomic_read(&pbpctl_dev->wdt_busy))==1) + return -1; + } +#endif - if (pbpctl_dev->bp_10g9) { + if(pbpctl_dev->bp_rang) { + unsigned long value; + + if(!na_base) + return -1; + + value = inl(na_base + 0x80); + if(!(value & (BIT_17 | BIT_18))) { + value |= (BIT_17 | BIT_18); + outl(value, (na_base + 0x80)); + } + } + + if(pbpctl_dev->bp_rang) { + if(pbpctl_dev->func == 0) { + unsigned long value; + + value = inl(na_base + 0x84); + value &= ~BIT_17; + outl(value, (na_base + 0x84)); + value = inl(na_base + 0x88); + value |= BIT_17; + outl(value, (na_base + 0x88)); + + } else { + unsigned long value; + + value = inl(na_base + 0x84); + value &= ~BIT_18; + outl(value, (na_base + 0x84)); + value = inl(na_base + 0x88); + value |= BIT_18; + outl(value, (na_base + 0x88)); + + } + + } else if (pbpctl_dev->bp_40g) { + + + writel(0x3f80010, (void *)((pbpctl_dev_c->mem_map) + 0x88108)); + BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + writel(0x3f80010, (void *)((pbpctl_dev_c->mem_map) + 0x8810c)); + BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + + /* DATA 0 CLK 1 */ + if(pbpctl_dev->func == 0) { + unsigned char a; + + + writel(0x62, (void *)((pbpctl_dev_c->mem_map) + 0x88184)); + BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + a = BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + /* if(!(a & BIT_2)) + printk("!!SDP2 stuck low! 0x%x %x\n", a, BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT));*/ + } else { + unsigned char a; + + + writel(0x63, (void *)((pbpctl_dev_c->mem_map) + 0x88184)); + BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + + a = BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + /*if(!(a & BIT_3)) + printk("SDP3 stuck low! 0x%x %x\n", a, BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT));*/ + + } + + } else if (pbpctl_dev->bp_10g9) { ctrl_ext=BP10G_READ_REG(pbpctl_dev,I2CCTL); ctrl= BP10G_READ_REG(pbpctl_dev_c, ESDP); @@ -1180,7 +2030,59 @@ static int wdt_pulse(bpctl_dev_t *pbpctl_dev){ //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA)); } - if (pbpctl_dev->bp_10g9) { + if(pbpctl_dev->bp_rang) { + if(pbpctl_dev->func == 0) { + unsigned long value; + + value = inl(na_base + 0x84); + value &= ~BIT_17; + outl(value, (na_base + 0x84)); + value = inl(na_base + 0x88); + value &= ~BIT_17; + outl(value, (na_base + 0x88)); + + } else { + unsigned long value; + + value = inl(na_base + 0x84); + value &= ~BIT_18; + outl(value, (na_base + 0x84)); + value = inl(na_base + 0x88); + value &= ~BIT_18; + outl(value, (na_base + 0x88)); + + } + + } else if (pbpctl_dev->bp_40g) { + /*struct timeval tv; + printk("0x%x \n", BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT)); */ + + + /* DATA 0 CLK 0 */ + if(pbpctl_dev->func_p == 0) { + unsigned char a; + + writel(0x42, (void *)((pbpctl_dev_c->mem_map) + 0x88184)); + BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + a = BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + /*if(a & BIT_2) + printk("SDP2 stuck high! 0x%x %x\n", a, BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT));*/ + + } else { + unsigned char a; + + writel(0x43, (void *)((pbpctl_dev_c->mem_map) + 0x88184)); + BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + a = BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + /*if(a & BIT_3) + printk("SDP3 stuck high! 0x%x %x\n", a, BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT));*/ + + } + /* do_gettimeofday(&tv); + printk("0x%x %d\n", BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT), (long)tv.tv_usec);*/ + + + } else if (pbpctl_dev->bp_10g9) { /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MCLK_DATA_OUT9)&~BP10G_MDIO_DATA_OUT9));*/ /* DATA 0 CLK 1*/ BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~BP10G_MDIO_DATA_OUT9)); @@ -1224,7 +2126,78 @@ static int wdt_pulse(bpctl_dev_t *pbpctl_dev){ } usec_delay_bp(WDT_INTERVAL); - if (pbpctl_dev->bp_10g9) { +/*{ + struct timeval tv; + + + do_gettimeofday(&tv); + printk("0x%x %d\n", BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT), (long)tv.tv_usec); +} */ + if(pbpctl_dev->bp_rang) { + if(pbpctl_dev->func == 0) { + unsigned long value; +#if 0 + value = BPCTL_READ_REG(pbpctl_dev, CTRL); + /* Make SDP0 Pin Directonality to Output */ + value |= BPCTLI_CTRL_SDP0_DIR; + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value); + + value |= BPCTLI_CTRL_SDP0_DATA; + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value); +#endif + value = inl(na_base + 0x84); + value &= ~BIT_17; + outl(value, (na_base + 0x84)); + value = inl(na_base + 0x88); + value |= BIT_17; + outl(value, (na_base + 0x88)); + } else { + unsigned long value; +#if 0 + value = BPCTL_READ_REG(pbpctl_dev, CTRL); + /* Make SDP0 Pin Directonality to Output */ + value |= BPCTLI_CTRL_SDP1_DIR; + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value); + + value |= BPCTLI_CTRL_SDP1_DATA; + BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value); +#endif + + value = inl(na_base + 0x84); + value &= ~BIT_18; + outl(value, (na_base + 0x84)); + value = inl(na_base + 0x88); + value |= BIT_18; + outl(value, (na_base + 0x88)); + + } + + } else if (pbpctl_dev->bp_40g) { + /* DATA 0 CLK 1 */ + if(pbpctl_dev->func_p == 0) { + unsigned char a; + + writel(0x62, (void *)((pbpctl_dev_c->mem_map) + 0x88184)); + BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + a = BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + + /*if(! ( a & BIT_2)) + printk("!!!SDP2 stuck low! 0x%x %x\n", a, BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT));*/ + + } else { + unsigned char a; + + writel(0x63, (void *)((pbpctl_dev_c->mem_map) + 0x88184)); + BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + a = BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT); + + /* if(! ( a & BIT_3)) + printk("SDP3 stuck low! 0x%x %x\n", a, BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT));*/ + + } + /* printk("0x%x \n\n", BP40G_RD_REG(pbpctl_dev_c, GPIO_STAT)); */ + + } else if (pbpctl_dev->bp_10g9) { /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)));*/ /* DATA 0 CLK 0 */ BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~BP10G_MDIO_DATA_OUT9)); @@ -1266,9 +2239,12 @@ static int wdt_pulse(bpctl_dev_t *pbpctl_dev){ (pbpctl_dev->bp_ext_verbypass_wdt_on_time=jiffies; #ifdef BP_SYNC_FLAG - spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) + spin_unlock_irqrestore(&pbpctl_dev_c->bypass_wr_lock, flags); + else + spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); #endif - usec_delay_bp(CMND_INTERVAL*4); + /* usec_delay_bp(CMND_INTERVAL);*/ return 0; } @@ -1504,53 +2480,117 @@ int gpio6_clear_fn (bpctl_dev_t *pbpctl_dev){ } #endif /*BYPASS_DEBUG*/ -static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev) { + +static bpctl_dev_t *get_status40_port_fn(bpctl_dev_t *pbpctl_dev) { int idx_dev=0; if (pbpctl_dev==NULL) return NULL; - if ((pbpctl_dev->func==0)||(pbpctl_dev->func==2)) { - for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev!=NULL)&&(idx_devbus)&& - (bpctl_dev_arr[idx_dev].slot==pbpctl_dev->slot)&& - ((bpctl_dev_arr[idx_dev].func==1)&&(pbpctl_dev->func==0))) { + if (pbpctl_dev->func_p != 0) { + for (idx_dev = 0; ((idx_dev < device_num)&&(bpctl_dev_arr[idx_dev].pdev != NULL)); idx_dev++) { + if ((bpctl_dev_arr[idx_dev].bus_p == pbpctl_dev->bus_p)&& + (bpctl_dev_arr[idx_dev].slot_p == pbpctl_dev->slot_p)&& + (bpctl_dev_arr[idx_dev].func_p == 0)) { - 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].func==3)&&(pbpctl_dev->func==2))) { + return(&(bpctl_dev_arr[idx_dev])); + } + } + } else + return pbpctl_dev; + return NULL; +} - return(&(bpctl_dev_arr[idx_dev])); - } - } - } +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->bp_40g) || (pbpctl_dev->bp_rang)) { + if (pbpctl_dev->func_p != 0) { + for (idx_dev = 0; ((idx_dev < device_num)&&(bpctl_dev_arr[idx_dev].pdev != NULL)); idx_dev++) { + if ((bpctl_dev_arr[idx_dev].bus_p == pbpctl_dev->bus_p)&& + (bpctl_dev_arr[idx_dev].slot_p == pbpctl_dev->slot_p)&& + (bpctl_dev_arr[idx_dev].func_p == 0)) { + + return(&(bpctl_dev_arr[idx_dev])); + } + } + } else + return pbpctl_dev; + + } else if (pbpctl_dev->bp_10g9) { + if (pbpctl_dev->func_p==0) { + for (idx_dev = 0; ((idx_dev < device_num)&&(bpctl_dev_arr[idx_dev].pdev != NULL)); idx_dev++) { + if ((bpctl_dev_arr[idx_dev].bus_p == pbpctl_dev->bus_p)&& + (bpctl_dev_arr[idx_dev].slot_p == pbpctl_dev->slot_p)&& + ((bpctl_dev_arr[idx_dev].func_p == 1)&&(pbpctl_dev->func_p == 0))) { + + return(&(bpctl_dev_arr[idx_dev])); + } + } + } + + } else { + if ((pbpctl_dev->func_p==0)||(pbpctl_dev->func_p==2)) { + for (idx_dev = 0; ((idx_devbus_p)&& + (bpctl_dev_arr[idx_dev].slot_p==pbpctl_dev->slot_p)&& + ((bpctl_dev_arr[idx_dev].func_p==1)&&(pbpctl_dev->func_p==0))) { + + return(&(bpctl_dev_arr[idx_dev])); + } + if ((bpctl_dev_arr[idx_dev].bus_p==pbpctl_dev->bus_p)&& + (bpctl_dev_arr[idx_dev].slot_p==pbpctl_dev->slot_p)&& + ((bpctl_dev_arr[idx_dev].func_p==3)&&(pbpctl_dev->func_p==2))) { + + 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==NULL) { + return NULL; + } - if ((pbpctl_dev->func==1)||(pbpctl_dev->func==3)) { - for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev!=NULL)&&(idx_devbus)&& - (bpctl_dev_arr[idx_dev].slot==pbpctl_dev->slot)&& - ((bpctl_dev_arr[idx_dev].func==0)&&(pbpctl_dev->func==1))) { + if (pbpctl_dev->bp_10g9) { + if (pbpctl_dev->func_p == 1) { + for (idx_dev = 0; ((idx_dev < device_num)&&(bpctl_dev_arr[idx_dev].pdev != NULL)); idx_dev++) { + if ((bpctl_dev_arr[idx_dev].bus_p == pbpctl_dev->bus_p)&& + (bpctl_dev_arr[idx_dev].slot_p == pbpctl_dev->slot_p)&& + ((bpctl_dev_arr[idx_dev].func_p == 0)&&(pbpctl_dev->func_p == 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].func==2)&&(pbpctl_dev->func==3))) { + return(&(bpctl_dev_arr[idx_dev])); + } + } + } - return(&(bpctl_dev_arr[idx_dev])); - } - } - } + } else { + if ((pbpctl_dev->func_p==1)||(pbpctl_dev->func_p==3)) { + for (idx_dev = 0; ((idx_devbus_p)&& + (bpctl_dev_arr[idx_dev].slot_p==pbpctl_dev->slot_p)&& + ((bpctl_dev_arr[idx_dev].func_p==0)&&(pbpctl_dev->func_p==1))) { + + return(&(bpctl_dev_arr[idx_dev])); + } + if ((bpctl_dev_arr[idx_dev].bus_p==pbpctl_dev->bus_p)&& + (bpctl_dev_arr[idx_dev].slot_p==pbpctl_dev->slot_p)&& + ((bpctl_dev_arr[idx_dev].func_p==2)&&(pbpctl_dev->func_p==3))) { + + return(&(bpctl_dev_arr[idx_dev])); + } + } + } + } return NULL; } @@ -1668,6 +2708,7 @@ int bypass_on(bpctl_dev_t *pbpctl_dev){ write_data(pbpctl_dev,BYPASS_ON); if (pbpctl_dev->bp_ext_ver>=PXG2TBPI_VER) msec_delay_bp(LATCH_DELAY); + } else data_pulse(pbpctl_dev,BYPASS_ON); ret=0; @@ -1803,7 +2844,8 @@ int tpl_hw_on (bpctl_dev_t *pbpctl_dev){ if (pbpctl_dev->bp_caps_ex&TPL2_CAP_EX) { cmnd_on(pbpctl_dev); write_data(pbpctl_dev,TPL2_ON); - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + /*msec_delay_bp(LATCH_DELAY);*/ + msec_delay_bp(EEPROM_WR_DELAY); cmnd_off(pbpctl_dev); return ret; } @@ -1826,7 +2868,8 @@ int tpl_hw_off (bpctl_dev_t *pbpctl_dev){ if (pbpctl_dev->bp_caps_ex&TPL2_CAP_EX) { cmnd_on(pbpctl_dev); write_data(pbpctl_dev,TPL2_OFF); - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + /*msec_delay_bp(LATCH_DELAY);*/ + msec_delay_bp(EEPROM_WR_DELAY); cmnd_off(pbpctl_dev); return ret; } @@ -1977,7 +3020,7 @@ static void bp75_release_phy(bpctl_dev_t *pbpctl_dev) - if ((pbpctl_dev->func==1)||(pbpctl_dev->func==3)) + if ((pbpctl_dev->func_p==1)||(pbpctl_dev->func_p==3)) mask = BPCTLI_SWFW_PHY1_SM; while (bp75_get_hw_semaphore_generic(pbpctl_dev) != 0); @@ -2002,7 +3045,7 @@ static s32 bp75_acquire_phy(bpctl_dev_t *pbpctl_dev) s32 i = 0, timeout = 200; - if ((pbpctl_dev->func==1)||(pbpctl_dev->func==3)) + if ((pbpctl_dev->func_p==1)||(pbpctl_dev->func_p==3)) mask = BPCTLI_SWFW_PHY1_SM; swmask = mask; @@ -2397,7 +3440,7 @@ int bypass_state_pwron(bpctl_dev_t *pbpctl_dev){ write_data(pbpctl_dev,BYPASS_STATE_PWRON); if (pbpctl_dev->bp_ext_ver==PXG2BPI_VER) msec_delay_bp(DFLT_PWRON_DELAY); - else msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + else msec_delay_bp(EEPROM_WR_DELAY); return 0; } return BP_NOT_CAP; @@ -2409,7 +3452,7 @@ int normal_state_pwron(bpctl_dev_t *pbpctl_dev){ write_data(pbpctl_dev,NORMAL_STATE_PWRON); if (pbpctl_dev->bp_ext_ver==PXG2BPI_VER) msec_delay_bp(DFLT_PWRON_DELAY); - else msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + else msec_delay_bp(EEPROM_WR_DELAY); return 0; } return BP_NOT_CAP; @@ -2419,7 +3462,7 @@ int normal_state_pwron(bpctl_dev_t *pbpctl_dev){ int bypass_state_pwroff(bpctl_dev_t *pbpctl_dev){ if (pbpctl_dev->bp_caps&BP_PWOFF_CTL_CAP) { write_data(pbpctl_dev,BYPASS_STATE_PWROFF); - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + msec_delay_bp(EEPROM_WR_DELAY); return 0; } return BP_NOT_CAP; @@ -2429,7 +3472,7 @@ int bypass_state_pwroff(bpctl_dev_t *pbpctl_dev){ int normal_state_pwroff(bpctl_dev_t *pbpctl_dev){ if ((pbpctl_dev->bp_caps&BP_PWOFF_CTL_CAP)) { write_data(pbpctl_dev,NORMAL_STATE_PWROFF); - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + msec_delay_bp(EEPROM_WR_DELAY); return 0; } return BP_NOT_CAP; @@ -2439,7 +3482,7 @@ int normal_state_pwroff(bpctl_dev_t *pbpctl_dev){ int tap_state_pwron(bpctl_dev_t *pbpctl_dev){ if (pbpctl_dev->bp_caps&TAP_PWUP_CTL_CAP) { write_data(pbpctl_dev,TAP_STATE_PWRON); - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + msec_delay_bp(EEPROM_WR_DELAY); return 0; } return BP_NOT_CAP; @@ -2469,7 +3512,7 @@ int disc_state_pwron(bpctl_dev_t *pbpctl_dev){ if (pbpctl_dev->bp_caps&DISC_PWUP_CTL_CAP) { if (pbpctl_dev->bp_ext_ver>=0x8) { write_data(pbpctl_dev,DISC_STATE_PWRON); - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + msec_delay_bp(EEPROM_WR_DELAY); return BP_OK; } } @@ -2589,7 +3632,7 @@ int std_nic_on(bpctl_dev_t *pbpctl_dev){ write_data(pbpctl_dev,NORMAL_STATE_PWRON); if (pbpctl_dev->bp_ext_ver==PXG2BPI_VER) msec_delay_bp(DFLT_PWRON_DELAY); - else msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + else msec_delay_bp(EEPROM_WR_DELAY); if (pbpctl_dev->bp_caps&BP_DIS_CAP) { write_data(pbpctl_dev,DIS_BYPASS_CAP); @@ -2626,13 +3669,13 @@ int std_nic_off(bpctl_dev_t *pbpctl_dev){ if (pbpctl_dev->bp_caps&TAP_PWUP_CTL_CAP) { write_data(pbpctl_dev,TAP_STATE_PWRON); - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + msec_delay_bp(EEPROM_WR_DELAY); } if (pbpctl_dev->bp_caps&BP_PWUP_CTL_CAP) { write_data(pbpctl_dev,BYPASS_STATE_PWRON); if (pbpctl_dev->bp_ext_ver>PXG2BPI_VER) - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + msec_delay_bp(EEPROM_WR_DELAY); else msec_delay_bp(DFLT_PWRON_DELAY); } @@ -2663,14 +3706,43 @@ int wdt_time_left (bpctl_dev_t *pbpctl_dev) //unsigned long curr_time=((long long)(jiffies*1000))/HZ, delta_time=0,wdt_on_time=((long long)(pbpctl_dev->bypass_wdt_on_time*1000))/HZ; unsigned long curr_time=jiffies, delta_time=0, wdt_on_time=pbpctl_dev->bypass_wdt_on_time, delta_time_msec=0; - int time_left=0; + int time_left = 0; +#if 0 + int exp_flag = 0, ctrl_ext = 0; + + bpctl_dev_t *pbpctl_dev_b=NULL; + + + if ((pbpctl_dev->bp_40g) && + (pbpctl_dev_b=get_status_port_fn(pbpctl_dev))) { + if(pbpctl_dev->func_p == 0) { + ctrl_ext = BP40G_READ_GPIO_CTL(pbpctl_dev_b, 2); + BP40G_WRITE_GPIO_CTL(pbpctl_dev_b, 2, (ctrl_ext & + ~(BP40GB_GPIO_SDP_MODE_MASK | BP40GB_GPIO_OE))); + exp_flag = ((BP40G_RD_REG(pbpctl_dev_b, GPIO_STAT)) & BIT_2)!=0?0:1; + + } else if(pbpctl_dev->func_p == 2) { + ctrl_ext = BP40G_READ_GPIO_CTL(pbpctl_dev_b, 3); + BP40G_WRITE_GPIO_CTL(pbpctl_dev_b, 3, (ctrl_ext & + ~(BP40GB_GPIO_SDP_MODE_MASK | BP40GB_GPIO_OE))); + + exp_flag = ((BP40G_RD_REG(pbpctl_dev_b, GPIO_STAT)) & BIT_3)!=0?0:1; + + } + } + if (exp_flag) { + printk("bpmod: WDT expired!\n"); + pbpctl_dev->wdt_status = WDT_STATUS_EXP; + return -1; + } +#endif switch (pbpctl_dev->wdt_status) { case WDT_STATUS_DIS: time_left=0; break; case WDT_STATUS_EN: - delta_time=(curr_time>=wdt_on_time)?(curr_time-wdt_on_time):(~wdt_on_time+curr_time); + delta_time = (curr_time>=wdt_on_time)?(curr_time-wdt_on_time):(~wdt_on_time+curr_time); delta_time_msec=jiffies_to_msecs(delta_time); time_left= pbpctl_dev->bypass_timer_interval-delta_time_msec; if (time_left<0) { @@ -2690,6 +3762,7 @@ static int wdt_timer(bpctl_dev_t *pbpctl_dev, int *time_left){ int ret=0; if (pbpctl_dev->bp_caps&WD_CTL_CAP) { { + if (pbpctl_dev->wdt_status==WDT_STATUS_UNKNOWN) ret=BP_NOT_CAP; else @@ -2704,10 +3777,16 @@ static int wdt_timer_reload(bpctl_dev_t *pbpctl_dev){ int ret=0; + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + if (pbpctl_dev->bp_caps&WD_CTL_CAP) { + wdt_pulse(pbpctl_dev); + return 1; + } + else return BP_NOT_CAP; + } + if ((pbpctl_dev->bp_caps&WD_CTL_CAP)&& (pbpctl_dev->wdt_status!=WDT_STATUS_UNKNOWN)) { - if (pbpctl_dev->wdt_status==WDT_STATUS_DIS) - return 0; if (pbpctl_dev->bp_ext_ver>=PXG2BPI_VER) ret= wdt_pulse(pbpctl_dev); else if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) @@ -2721,12 +3800,16 @@ static int wdt_timer_reload(bpctl_dev_t *pbpctl_dev){ } +#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 #ifdef BP_SELF_TEST struct sk_buff *skb_tmp; -#endif - +#endif if ((pbpctl_dev->bp_ext_ver>=PXG2BPI_VER)&& ((atomic_read(&pbpctl_dev->wdt_busy))==1)) { @@ -2755,6 +3838,7 @@ static void wd_reset_timer(unsigned long param){ bp_timer_reload: #endif if (pbpctl_dev->reset_time) { + mod_timer(&pbpctl_dev->bp_timer, jiffies+(HZ*pbpctl_dev->reset_time)/1000); } } @@ -2767,7 +3851,7 @@ int bp_wait_at_pwup_en(bpctl_dev_t *pbpctl_dev){ if (pbpctl_dev->bp_caps&SW_CTL_CAP) { if (pbpctl_dev->bp_ext_ver>=BP_FW_EXT_VER8) { write_data(pbpctl_dev,BP_WAIT_AT_PWUP_EN); - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + msec_delay_bp(EEPROM_WR_DELAY); return BP_OK; } @@ -2782,7 +3866,7 @@ int bp_wait_at_pwup_dis(bpctl_dev_t *pbpctl_dev){ if (pbpctl_dev->bp_ext_ver>=BP_FW_EXT_VER8) { write_data(pbpctl_dev,BP_WAIT_AT_PWUP_DIS); - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + msec_delay_bp(EEPROM_WR_DELAY); return BP_OK; } @@ -2797,7 +3881,7 @@ int bp_hw_reset_en(bpctl_dev_t *pbpctl_dev){ if (pbpctl_dev->bp_caps&SW_CTL_CAP) { if (pbpctl_dev->bp_ext_ver>=BP_FW_EXT_VER8) { write_data(pbpctl_dev,BP_HW_RESET_EN); - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + msec_delay_bp(EEPROM_WR_DELAY); return BP_OK; } @@ -2812,7 +3896,7 @@ int bp_hw_reset_dis(bpctl_dev_t *pbpctl_dev){ if (pbpctl_dev->bp_caps&SW_CTL_CAP) { if (pbpctl_dev->bp_ext_ver>=BP_FW_EXT_VER8) { write_data(pbpctl_dev,BP_HW_RESET_DIS); - msec_delay_bp(LATCH_DELAY+EEPROM_WR_DELAY); + msec_delay_bp(EEPROM_WR_DELAY); return BP_OK; } @@ -2865,8 +3949,30 @@ int wdt_exp_mode(bpctl_dev_t *pbpctl_dev, int mode){ int bypass_fw_ver(bpctl_dev_t *pbpctl_dev){ - if (is_bypass_fn(pbpctl_dev)) - return((read_reg(pbpctl_dev,VER_REG_ADDR))); + if (is_bypass_fn(pbpctl_dev)) { + + if ((pbpctl_dev->bp_40g) || + (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_BYPASS_INFO; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) + return -1; + + 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; + + } else return((read_reg(pbpctl_dev,VER_REG_ADDR))); + } else return BP_NOT_CAP; } @@ -3053,7 +4159,54 @@ static int bypass_status(bpctl_dev_t *pbpctl_dev){ if (!(pbpctl_dev_b=get_status_port_fn(pbpctl_dev))) return BP_NOT_CAP; - if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { +#if 0 + if(pbpctl_dev->func_p == 0) { + ctrl_ext = BP40G_READ_GPIO_CTL(pbpctl_dev_b, 2); + BP40G_WRITE_GPIO_CTL(pbpctl_dev_b, 2, (ctrl_ext & + ~(BP40GB_GPIO_SDP_MODE_MASK | BP40GB_GPIO_OE))); + + + return(((BP40G_RD_REG(pbpctl_dev_b, GPIO_STAT)) & BIT_2)!=0?1:0); + + } else if(pbpctl_dev->func_p == 2) { + ctrl_ext = BP40G_READ_GPIO_CTL(pbpctl_dev_b, 3); + BP40G_WRITE_GPIO_CTL(pbpctl_dev_b, 3, (ctrl_ext & + ~(BP40GB_GPIO_SDP_MODE_MASK | BP40GB_GPIO_OE))); + + + return(((BP40G_RD_REG(pbpctl_dev_b, GPIO_STAT)) & BIT_3)!=0?1:0); + + } else + return BP_NOT_CAP; +#else + + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_BYPASS; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) + return -1; + + 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; +#endif + + } else if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { if (!pbpctl_dev->bp_status_un) return(((BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT)) & BPCTLI_CTRL_EXT_SDP7_DATA)!=0?1:0); @@ -3114,6 +4267,81 @@ static int bypass_status(bpctl_dev_t *pbpctl_dev){ } +static int wd_exp_status(bpctl_dev_t *pbpctl_dev){ + u32 ctrl_ext=0; + if (pbpctl_dev->bp_caps&BP_CAP) { + + bpctl_dev_t *pbpctl_dev_b=NULL; + + if ((pbpctl_dev->bp_rang) && (!na_base)) + return BP_NOT_CAP; + + if (!(pbpctl_dev_b=get_status_port_fn(pbpctl_dev))) + return BP_NOT_CAP; + + if(pbpctl_dev->bp_rang) { + unsigned long value; + + if(!na_base) + return BP_NOT_CAP; + + value = inl(na_base + 0x80); + if(!(value & (BIT_17 | BIT_18))) { + value |= (BIT_17 | BIT_18); + outl(value, (na_base + 0x80)); + } + } + + if (pbpctl_dev->bp_rang) { + + if(pbpctl_dev->func_p == 0) { + unsigned long value; + + value = inl(na_base + 0x84); + value |= BIT_17; + outl(value, (na_base + 0x84)); + return((inl(na_base + 0x88) & BIT_17) !=0 ? 0:1); + + + } else { + unsigned long value; + + value = inl(na_base + 0x84); + value |= BIT_18; + outl(value, (na_base + 0x84)); + return((inl(na_base + 0x88) & BIT_18) !=0 ? 0:1); + } + + } else if (pbpctl_dev->bp_40g) { +#if 1 + if(pbpctl_dev->func_p == 0) { + ctrl_ext = BP40G_READ_GPIO_CTL(pbpctl_dev_b, 2); + BP40G_WRITE_GPIO_CTL(pbpctl_dev_b, 2, (ctrl_ext & + ~(BP40GB_GPIO_SDP_MODE_MASK | BP40GB_GPIO_OE))); + + BP40G_RD_REG(pbpctl_dev_b, GPIO_STAT); + return(((BP40G_RD_REG(pbpctl_dev_b, GPIO_STAT)) & BIT_2)!=0?0:1); + + } else if(pbpctl_dev->func_p == 2) { + ctrl_ext = BP40G_READ_GPIO_CTL(pbpctl_dev_b, 3); + BP40G_WRITE_GPIO_CTL(pbpctl_dev_b, 3, (ctrl_ext & + ~(BP40GB_GPIO_SDP_MODE_MASK | BP40GB_GPIO_OE))); + + BP40G_RD_REG(pbpctl_dev_b, GPIO_STAT); + return(((BP40G_RD_REG(pbpctl_dev_b, GPIO_STAT)) & BIT_3)!=0?0:1); + + } else + return BP_NOT_CAP; +#endif + + + + } + } + return BP_NOT_CAP; +} + + int default_pwron_status(bpctl_dev_t *pbpctl_dev){ @@ -3619,7 +4847,7 @@ void bypass_caps_init (bpctl_dev_t *pbpctl_dev){ u_int32_t ctrl_ext=0; bpctl_dev_t *pbpctl_dev_m=NULL; - + #ifdef BYPASS_DEBUG int ret=0; if (!(INTEL_IF_SERIES(adapter->bp_device_block.subdevice))) { @@ -3641,6 +4869,12 @@ void bypass_caps_init (bpctl_dev_t *pbpctl_dev){ printk("TMRH_REG_ADDR=%x\n",ret); } #endif + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + pbpctl_dev->bp_caps=get_bypass_caps_fn(pbpctl_dev); + return; + } + if ((pbpctl_dev->bp_fiber5) ||(pbpctl_dev->bp_10g9)) { pbpctl_dev->media_type= bp_fiber; } else if (pbpctl_dev->bp_10gb) { @@ -3777,10 +5011,18 @@ void bypass_caps_init (bpctl_dev_t *pbpctl_dev){ pbpctl_dev->bp_caps|= (TX_CTL_CAP| TX_STATUS_CAP); } - } + } + } + if (pbpctl_dev->bp_ext_ver>=PXG2BPI_VER) { + int sta = read_reg(pbpctl_dev,STATUS_REG_ADDR); + if (sta & WD_EXP_FLAG_MASK) + pbpctl_dev->wdt_status=WDT_STATUS_EXP; + else if (sta & WDT_EN_MASK) + pbpctl_dev->wdt_status=WDT_STATUS_EN; + else pbpctl_dev->wdt_status=WDT_STATUS_DIS; } if (pbpctl_dev->bp_ext_ver>=PXG2BPI_VER) { if ((read_reg(pbpctl_dev,STATUS_REG_ADDR))&WDT_EN_MASK) @@ -3788,6 +5030,11 @@ void bypass_caps_init (bpctl_dev_t *pbpctl_dev){ else pbpctl_dev->wdt_status=WDT_STATUS_DIS; } + if ((PEG5_IF_SERIES(pbpctl_dev->subdevice)) || + (PEG80_IF_SERIES(pbpctl_dev->subdevice))) + pbpctl_dev->bp_caps |= TPL_CAP; + + } else if ((P2BPFI_IF_SERIES(pbpctl_dev->subdevice))|| (PEGF5_IF_SERIES(pbpctl_dev->subdevice))|| (PEGF80_IF_SERIES(pbpctl_dev->subdevice))|| @@ -3872,11 +5119,16 @@ void remove_bypass_wd_auto(bpctl_dev_t *pbpctl_dev){ } + 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; @@ -3890,7 +5142,7 @@ bp_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) int idx_dev=0; struct ethhdr *eth=(struct ethhdr *) skb->data; - for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].ndev!=NULL)&&(idx_devfunc==0)||(pbpctl_dev->func==2))?1:0); + + if (!pbpctl_dev) { + return -1; + } + + if (pbpctl_dev->bp_10g9) { + return((pbpctl_dev->func_p == 0) ? 1:0); + } + + return(((pbpctl_dev->func_p==0)||(pbpctl_dev->func_p==2))?1:0); } + + + int set_bypass_fn (bpctl_dev_t *pbpctl_dev, int bypass_mode){ int ret=0; - if (!(pbpctl_dev->bp_caps & BP_CAP)) - return BP_NOT_CAP; - if ((ret=cmnd_on(pbpctl_dev))<0) - return ret; - if (!bypass_mode) - ret=bypass_off(pbpctl_dev); - else - ret=bypass_on(pbpctl_dev); - cmnd_off(pbpctl_dev); + if (!(pbpctl_dev->bp_caps & BP_CAP)) + return BP_NOT_CAP; + + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_SET_BYPASS; + bp_cmd_buf.cmd.cmd_data.bypass_mode=bypass_mode?1:0; + + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) + return -1; + + 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; + + } else { + + if ((ret=cmnd_on(pbpctl_dev))<0) + return ret; + if (!bypass_mode) + ret=bypass_off(pbpctl_dev); + else + ret=bypass_on(pbpctl_dev); + cmnd_off(pbpctl_dev); + } return ret; } +int get_wd_expire_fn (bpctl_dev_t *pbpctl_dev){ + return(wd_exp_status(pbpctl_dev)); +} + int get_bypass_fn (bpctl_dev_t *pbpctl_dev){ return(bypass_status(pbpctl_dev)); } + + int get_bypass_change_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } + if (!(pbpctl_dev->bp_caps & BP_CAP)) { + return BP_NOT_CAP; + } - return(bypass_change_status(pbpctl_dev)); + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + + bp_cmd_buf.cmd.cmd_id=CMD_GET_BYPASS_CHANGE; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) + return -1; + + 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; + + } else + return(bypass_change_status(pbpctl_dev)); } -int set_dis_bypass_fn(bpctl_dev_t *pbpctl_dev, int dis_param){ + + +int set_dis_bypass_fn(bpctl_dev_t *pbpctl_dev, int dis_bypass){ int ret=0; - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps & BP_DIS_CAP)) { + return BP_NOT_CAP; + } - if (!(pbpctl_dev->bp_caps & BP_DIS_CAP)) - return BP_NOT_CAP; - if ((ret=cmnd_on(pbpctl_dev))<0) - return ret; - if (dis_param) - ret=dis_bypass_cap(pbpctl_dev); - else - ret=en_bypass_cap(pbpctl_dev); - cmnd_off(pbpctl_dev); - return ret; + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 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 (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + + if (!(pbpctl_dev->bp_caps & BP_DIS_CAP)) { + return BP_NOT_CAP; + } + if ((ret=cmnd_on(pbpctl_dev))<0) { + return ret; + } + if (dis_bypass) { + ret=dis_bypass_cap(pbpctl_dev); + } else { + ret=en_bypass_cap(pbpctl_dev); + } + cmnd_off(pbpctl_dev); + return ret; + } } + + int get_dis_bypass_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } - return(dis_bypass_cap_status(pbpctl_dev)); + if (!(pbpctl_dev->bp_caps & BP_DIS_CAP)) { + return BP_NOT_CAP; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + + bp_cmd_buf.cmd.cmd_id=CMD_GET_DIS_BYPASS; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + return(dis_bypass_cap_status(pbpctl_dev)); + } } + int set_bypass_pwoff_fn (bpctl_dev_t *pbpctl_dev, int bypass_mode){ int ret=0; - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } - if (!(pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) - return BP_NOT_CAP; - if ((ret=cmnd_on(pbpctl_dev))<0) - return ret; - if (bypass_mode) - ret=bypass_state_pwroff(pbpctl_dev); - else - ret=normal_state_pwroff(pbpctl_dev); - cmnd_off(pbpctl_dev); - return ret; + if (!(pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) { + return BP_NOT_CAP; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + int ret=-1; + bpctl_dev_t *pbpctl_dev_c; + + 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_p == 0)? 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 (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + } else { + if ((ret=cmnd_on(pbpctl_dev))<0) { + return ret; + } + if (bypass_mode) { + ret=bypass_state_pwroff(pbpctl_dev); + } else { + ret=normal_state_pwroff(pbpctl_dev); + } + cmnd_off(pbpctl_dev); + return ret; + } } int get_bypass_pwoff_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) { + return BP_NOT_CAP; + } - return(default_pwroff_status(pbpctl_dev)); + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_BYPASS_PWOFF; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + return(default_pwroff_status(pbpctl_dev)); + } } int set_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode){ int ret=0; - if (!pbpctl_dev) - return -1; + + if (!pbpctl_dev) { + return -1; + } - if (!(pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP)) - return BP_NOT_CAP; - if ((ret=cmnd_on(pbpctl_dev))<0) - return ret; - if (bypass_mode) - ret=bypass_state_pwron(pbpctl_dev); - else - ret=normal_state_pwron(pbpctl_dev); - cmnd_off(pbpctl_dev); - return ret; + if (!(pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP)) { + return BP_NOT_CAP; + } + + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 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 (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + if ((ret=cmnd_on(pbpctl_dev))<0) { + return ret; + } + if (bypass_mode) { + ret=bypass_state_pwron(pbpctl_dev); + } else { + ret=normal_state_pwron(pbpctl_dev); + } + cmnd_off(pbpctl_dev); + + return ret; + } } int get_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; - return(default_pwron_status(pbpctl_dev)); + if (!pbpctl_dev) { + return -1; + } + if (!(pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP)) { + return BP_NOT_CAP; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_BYPASS_PWUP; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + return(default_pwron_status(pbpctl_dev)); + } } + + + int set_bypass_wd_fn(bpctl_dev_t *pbpctl_dev, int timeout){ int ret=0; - if (!pbpctl_dev) - return -1; + + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps & WD_CTL_CAP)) { + return BP_NOT_CAP; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_SET_BYPASS_WD; + bp_cmd_buf.cmd.cmd_data.timeout=htonl(timeout); - if (!(pbpctl_dev->bp_caps & WD_CTL_CAP)) - return BP_NOT_CAP; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } - if ((ret=cmnd_on(pbpctl_dev))<0) - return ret; - if (!timeout) - ret=wdt_off(pbpctl_dev); - else { - wdt_on(pbpctl_dev,timeout); - ret = pbpctl_dev->bypass_timer_interval; - } - cmnd_off(pbpctl_dev); - return ret; + 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); + if(ret) { + pbpctl_dev->wdt_status=WDT_STATUS_EN; + } + } + } + return ret; + + } else { + + if ((ret=cmnd_on(pbpctl_dev))<0) { + return ret; + } + if (!timeout) { + ret=wdt_off(pbpctl_dev); + } else { + wdt_on(pbpctl_dev,timeout); + ret = pbpctl_dev->bypass_timer_interval; + } + cmnd_off(pbpctl_dev); + return ret; + } } + + int get_bypass_wd_fn(bpctl_dev_t *pbpctl_dev, int *timeout){ - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } - return wdt_programmed(pbpctl_dev, timeout); + if (!(pbpctl_dev->bp_caps & WD_CTL_CAP)) { + return BP_NOT_CAP; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_BYPASS_WD; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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); + if(*timeout) { + pbpctl_dev->wdt_status=WDT_STATUS_EN; + } + ret=0; + } + } + return ret; + + } else { + return wdt_programmed(pbpctl_dev, timeout); + } } -int get_wd_expire_time_fn(bpctl_dev_t *pbpctl_dev, int *time_left){ - if (!pbpctl_dev) - return -1; - return(wdt_timer(pbpctl_dev, time_left)); + +int get_wd_expire_time_fn(bpctl_dev_t *pbpctl_dev, int *time_left){ +#if 0 + bpctl_dev_t *pbpctl_dev_b = NULL; +#endif + + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps & WD_CTL_CAP)) { + return BP_NOT_CAP; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_WD_EXPIRE_TIME; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + return(wdt_timer(pbpctl_dev, time_left)); + } + } int reset_bypass_wd_timer_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; - + if (!pbpctl_dev) { + return -1; + } return(wdt_timer_reload(pbpctl_dev)); } + + int get_wd_set_caps_fn(bpctl_dev_t *pbpctl_dev){ int bp_status=0; - unsigned int step_value=TIMEOUT_MAX_STEP+1, bit_cnt=0; - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } - if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) - return BP_NOT_CAP; + if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { + return BP_NOT_CAP; + } + + if (!(pbpctl_dev->bp_caps & WD_CTL_CAP)) { + return BP_NOT_CAP; + } - while ((step_value>>=1)) - bit_cnt++; + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + bpctl_dev_t *pbpctl_dev_c; + int ret=-1; - if (is_bypass_fn(pbpctl_dev)) { - bp_status= WD_STEP_COUNT_MASK(bit_cnt)|WDT_STEP_TIME|WD_MIN_TIME_MASK(TIMEOUT_UNIT/100); - } else 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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_WD_SET_CAPS; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } - return bp_status; + 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; + + } else { + + while ((step_value>>=1)) { + bit_cnt++; + } + + if (is_bypass_fn(pbpctl_dev)) { + bp_status= WD_STEP_COUNT_MASK(bit_cnt)|WDT_STEP_TIME|WD_MIN_TIME_MASK(TIMEOUT_UNIT/100); + } else { + return -1; + } + + return bp_status; + } } + int set_std_nic_fn(bpctl_dev_t *pbpctl_dev, int nic_mode){ int ret=0; - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } - if (!(pbpctl_dev->bp_caps & STD_NIC_CAP)) - return BP_NOT_CAP; + if (!(pbpctl_dev->bp_caps & STD_NIC_CAP)) { + return BP_NOT_CAP; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; - if ((ret=cmnd_on(pbpctl_dev))<0) - return ret; - if (nic_mode) - ret=std_nic_on(pbpctl_dev); - else - ret=std_nic_off(pbpctl_dev); - cmnd_off(pbpctl_dev); - return ret; + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 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 (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + + if ((ret=cmnd_on(pbpctl_dev))<0) { + return ret; + } + if (nic_mode) { + ret=std_nic_on(pbpctl_dev); + } else { + ret=std_nic_off(pbpctl_dev); + } + cmnd_off(pbpctl_dev); + return ret; + } } -int get_std_nic_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; - return(std_nic_status(pbpctl_dev)); +int get_std_nic_fn(bpctl_dev_t *pbpctl_dev){ + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps&STD_NIC_CAP)) { + return -1; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_STD_NIC; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + return(std_nic_status(pbpctl_dev)); + } } int set_tap_fn (bpctl_dev_t *pbpctl_dev, int tap_mode){ - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } if ((pbpctl_dev->bp_caps & TAP_CAP)&&((cmnd_on(pbpctl_dev))>=0)) { - if (!tap_mode) - tap_off(pbpctl_dev); - else - tap_on(pbpctl_dev); + if (!tap_mode) { + tap_off(pbpctl_dev); + } else { + tap_on(pbpctl_dev); + } cmnd_off(pbpctl_dev); return 0; } @@ -4232,254 +5983,639 @@ int set_tap_fn (bpctl_dev_t *pbpctl_dev, int tap_mode){ } int get_tap_fn (bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; - + if (!pbpctl_dev) { + return -1; + } return(tap_status(pbpctl_dev)); } int set_tap_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode){ int ret=0; - if (!pbpctl_dev) - return -1; + + if (!pbpctl_dev) { + return -1; + } if ((pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP)&&((cmnd_on(pbpctl_dev))>=0)) { - if (tap_mode) - ret=tap_state_pwron(pbpctl_dev); - else - ret=normal_state_pwron(pbpctl_dev); + if (tap_mode) { + ret=tap_state_pwron(pbpctl_dev); + } else { + ret=normal_state_pwron(pbpctl_dev); + } cmnd_off(pbpctl_dev); - } else ret=BP_NOT_CAP; + } else { + ret=BP_NOT_CAP; + } return ret; } int get_tap_pwup_fn(bpctl_dev_t *pbpctl_dev){ int ret=0; - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } - if ((ret=default_pwron_tap_status(pbpctl_dev))<0) - return ret; + if ((ret=default_pwron_tap_status(pbpctl_dev))<0) { + return ret; + } return((ret==0)?1:0); } int get_tap_change_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } return(tap_change_status(pbpctl_dev)); } int set_dis_tap_fn(bpctl_dev_t *pbpctl_dev, int dis_param){ int ret=0; - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } if ((pbpctl_dev->bp_caps & TAP_DIS_CAP)&&((cmnd_on(pbpctl_dev))>=0)) { - if (dis_param) - ret=dis_tap_cap(pbpctl_dev); - else - ret=en_tap_cap(pbpctl_dev); + if (dis_param) { + ret=dis_tap_cap(pbpctl_dev); + } else { + ret=en_tap_cap(pbpctl_dev); + } cmnd_off(pbpctl_dev); return ret; - } else - return BP_NOT_CAP; + } else { + return BP_NOT_CAP; + } } int get_dis_tap_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } return(dis_tap_cap_status(pbpctl_dev)); } + + int set_disc_fn (bpctl_dev_t *pbpctl_dev, int disc_mode){ - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } - if ((pbpctl_dev->bp_caps & DISC_CAP)&&((cmnd_on(pbpctl_dev))>=0)) { - if (!disc_mode) - disc_off(pbpctl_dev); - else - disc_on(pbpctl_dev); - cmnd_off(pbpctl_dev); + if (!(pbpctl_dev->bp_caps & DISC_CAP)) { + return BP_NOT_CAP; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; - return BP_OK; - } - return BP_NOT_CAP; + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_SET_DISC; + bp_cmd_buf.cmd.cmd_data.disc_mode=disc_mode?1:0; + + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + + if ((cmnd_on(pbpctl_dev)>=0)) { + if (!disc_mode) { + disc_off(pbpctl_dev); + } else { + disc_on(pbpctl_dev); + } + cmnd_off(pbpctl_dev); + + return BP_OK; + } + return BP_NOT_CAP; + } } + + int get_disc_fn (bpctl_dev_t *pbpctl_dev){ int ret=0; - if (!pbpctl_dev) - return -1; - ret=disc_status(pbpctl_dev); + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps&DISC_CAP)) { + return -1; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_DISC; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + ret=disc_status(pbpctl_dev); + } return ret; } + + int set_disc_pwup_fn(bpctl_dev_t *pbpctl_dev, int disc_mode){ int ret=0; - if (!pbpctl_dev) - return -1; + + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP)) { + return BP_NOT_CAP; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-1; - if ((pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP)&&((cmnd_on(pbpctl_dev))>=0)) { - if (disc_mode) - ret=disc_state_pwron(pbpctl_dev); - else - ret=normal_state_pwron(pbpctl_dev); - cmnd_off(pbpctl_dev); - } else ret=BP_NOT_CAP; - 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= (pbpctl_dev->func_p == 0)? 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 (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + if ((cmnd_on(pbpctl_dev)>=0)) { + if (disc_mode) { + ret=disc_state_pwron(pbpctl_dev); + } else { + ret=normal_state_pwron(pbpctl_dev); + } + cmnd_off(pbpctl_dev); + } else { + ret=BP_NOT_CAP; + } + + return ret; + } } + + int get_disc_pwup_fn(bpctl_dev_t *pbpctl_dev){ int ret=0; - if (!pbpctl_dev) - return -1; - ret=default_pwron_disc_status(pbpctl_dev); - return(ret==0?1:(ret<0?BP_NOT_CAP:0)); + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP)) { + return BP_NOT_CAP; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_DISC_PWUP; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + ret=default_pwron_disc_status(pbpctl_dev); + return(ret==0?1:(ret<0?BP_NOT_CAP:0)); + } } + + int get_disc_change_fn(bpctl_dev_t *pbpctl_dev){ int ret=0; - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } - ret=disc_change_status(pbpctl_dev); - return ret; + if (!(pbpctl_dev->bp_caps&DISC_CAP)) { + return -1; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_DISC_CHANGE; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) + return -1; + + 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; + + } else { + ret=disc_change_status(pbpctl_dev); + return ret; + } } + int set_dis_disc_fn(bpctl_dev_t *pbpctl_dev, int dis_param){ int ret=0; - if (!pbpctl_dev) - return -1; - if ((pbpctl_dev->bp_caps & DISC_DIS_CAP)&&((cmnd_on(pbpctl_dev))>=0)) { - if (dis_param) - ret=dis_disc_cap(pbpctl_dev); - else - ret=en_disc_cap(pbpctl_dev); - cmnd_off(pbpctl_dev); - return ret; - } else - return BP_NOT_CAP; -} + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps&DISC_DIS_CAP)) { + return -1; + } + + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 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 (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + + if ((cmnd_on(pbpctl_dev)>=0)) { + if (dis_param) { + ret=dis_disc_cap(pbpctl_dev); + } else { + ret=en_disc_cap(pbpctl_dev); + } + cmnd_off(pbpctl_dev); + return ret; + } else + return BP_NOT_CAP; + } +} int get_dis_disc_fn(bpctl_dev_t *pbpctl_dev){ int ret=0; - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } - ret=dis_disc_cap_status(pbpctl_dev); + if (((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) && + (pbpctl_dev->bp_caps&DISC_DIS_CAP)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; - return ret; + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_DIS_DISC; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + ret=dis_disc_cap_status(pbpctl_dev); + return ret; + } } int set_disc_port_fn (bpctl_dev_t *pbpctl_dev, int disc_mode){ int ret=BP_NOT_CAP; - if (!pbpctl_dev) - return -1; - if (!disc_mode) - ret=disc_port_off(pbpctl_dev); - else - ret=disc_port_on(pbpctl_dev); + if (!pbpctl_dev) { + return -1; + } + if (!disc_mode) { + ret=disc_port_off(pbpctl_dev); + } else { + ret=disc_port_on(pbpctl_dev); + } return ret; } int get_disc_port_fn (bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; + + if (!pbpctl_dev) { + return -1; + } return(disc_port_status(pbpctl_dev)); } int set_disc_port_pwup_fn(bpctl_dev_t *pbpctl_dev, int disc_mode){ int ret=BP_NOT_CAP; - if (!pbpctl_dev) - return -1; - if (!disc_mode) - ret=normal_port_state_pwron(pbpctl_dev); - else - ret=disc_port_state_pwron(pbpctl_dev); + if (!pbpctl_dev) { + return -1; + } + + if (!disc_mode) { + ret=normal_port_state_pwron(pbpctl_dev); + } else { + ret=disc_port_state_pwron(pbpctl_dev); + } return ret; } int get_disc_port_pwup_fn(bpctl_dev_t *pbpctl_dev){ int ret=0; + if (!pbpctl_dev) return -1; - if ((ret=default_pwron_disc_port_status(pbpctl_dev))<0) - return ret; + if ((ret=default_pwron_disc_port_status(pbpctl_dev))<0) { + return ret; + } return((ret==0)?1:0); } int get_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; - return(wdt_exp_mode_status(pbpctl_dev)); -} + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps & WD_CTL_CAP)) { + return BP_NOT_CAP; + } + + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_WD_EXP_MODE; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + return(wdt_exp_mode_status(pbpctl_dev)); + } +} + + int set_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev, int param){ - if (!pbpctl_dev) - return -1; - return(wdt_exp_mode(pbpctl_dev,param)); + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps & WD_CTL_CAP)) { + return BP_NOT_CAP; + } + + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_SET_WD_EXP_MODE; + bp_cmd_buf.cmd.cmd_data.wd_exp_mode=param; + + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + return(wdt_exp_mode(pbpctl_dev,param)); + } } int reset_cont_fn (bpctl_dev_t *pbpctl_dev){ - int ret=0; - if (!pbpctl_dev) - return -1; + int ret=0; - if ((ret=cmnd_on(pbpctl_dev))<0) - return ret; + if (!pbpctl_dev) { + return -1; + } + + if ((ret=cmnd_on(pbpctl_dev))<0) { + return ret; + } return(reset_cont(pbpctl_dev)); } - int set_tx_fn(bpctl_dev_t *pbpctl_dev, int tx_state){ bpctl_dev_t *pbpctl_dev_b=NULL; - if (!pbpctl_dev) - return -1; - if ((pbpctl_dev->bp_caps&TPL_CAP)&& - (pbpctl_dev->bp_caps&SW_CTL_CAP) ) { - if ((pbpctl_dev->bp_tpl_flag)) - return BP_NOT_CAP; - } else if ((pbpctl_dev_b=get_master_port_fn(pbpctl_dev))) { - if ((pbpctl_dev_b->bp_caps&TPL_CAP)&& - (pbpctl_dev_b->bp_tpl_flag)) - return BP_NOT_CAP; - } - return(set_tx(pbpctl_dev,tx_state)); + if (!pbpctl_dev) { + return -1; + } + + if (!(pbpctl_dev->bp_caps&TX_CTL_CAP)) { + return -1; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + bpctl_dev_t *pbpctl_dev_c, *pbpctl_dev_m; + int ret=-1; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + if(is_bypass_fn(pbpctl_dev)) { + pbpctl_dev_m = pbpctl_dev; + } else { + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + } + + if (!pbpctl_dev_m) { + return -1; + } + + bp_cmd_buf.cmd.cmd_dev_num= (pbpctl_dev_m->func_p == 0)? 0: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; + bp_cmd_buf.cmd.cmd_data.tx_dis.port_num= + (pbpctl_dev_m->func_p == 0)?pbpctl_dev->func_p:(pbpctl_dev->func_p-2); + + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + + if ((pbpctl_dev->bp_caps&TPL_CAP)&& + (pbpctl_dev->bp_caps&SW_CTL_CAP) ) { + if ((pbpctl_dev->bp_tpl_flag)) { + return BP_NOT_CAP; + } + } else if ((pbpctl_dev_b=get_master_port_fn(pbpctl_dev))) { + if ((pbpctl_dev_b->bp_caps&TPL_CAP)&& + (pbpctl_dev_b->bp_tpl_flag)) { + return BP_NOT_CAP; + } + } + return(set_tx(pbpctl_dev,tx_state)); + } } int set_bp_force_link_fn(int dev_num, int tx_state){ static bpctl_dev_t *bpctl_dev_curr; - - if ((dev_num<0)||(dev_num>device_num)||(bpctl_dev_arr[dev_num].pdev==NULL)) - return -1; + if ((dev_num<0)||(dev_num>device_num)||(bpctl_dev_arr[dev_num].pdev==NULL)) { + return -1; + } bpctl_dev_curr=&bpctl_dev_arr[dev_num]; return(set_bp_force_link(bpctl_dev_curr,tx_state)); @@ -4488,30 +6624,35 @@ int set_bp_force_link_fn(int dev_num, int tx_state){ int set_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev, int param){ - if (!pbpctl_dev) - return -1; + + if (!pbpctl_dev) { + return -1; + } return(set_bypass_wd_auto(pbpctl_dev, param)); } int get_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; + + if (!pbpctl_dev) { + return -1; + } return(get_bypass_wd_auto(pbpctl_dev)); } #ifdef BP_SELF_TEST int set_bp_self_test_fn(bpctl_dev_t *pbpctl_dev, int param){ - if (!pbpctl_dev) - return -1; - + if (!pbpctl_dev) { + return -1; + } return(set_bp_self_test(pbpctl_dev, param)); } int get_bp_self_test_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } return(get_bp_self_test(pbpctl_dev)); } @@ -4520,98 +6661,247 @@ int get_bp_self_test_fn(bpctl_dev_t *pbpctl_dev){ int get_bypass_caps_fn(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; - return(pbpctl_dev->bp_caps); + if (!pbpctl_dev) { + return -1; + } + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + bpctl_dev_t *pbpctl_dev_c, *pbpctl_dev_m; + int ret=-1; + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + + if(is_bypass_fn(pbpctl_dev)) { + pbpctl_dev_m = pbpctl_dev; + } else { + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + } + + + bp_cmd_buf.cmd.cmd_dev_num= (pbpctl_dev_m->func_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_BYPASS_CAPS; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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_fn(pbpctl_dev))!=1) { + int ret1=0; + if(ret&TX_CTL_CAP) { + ret1=(TX_CTL_CAP|TX_STATUS_CAP); + } + return ret1; + + } + } + } + return ret; + + } else { + return(pbpctl_dev->bp_caps); + } +} + + +int get_bypass_caps_ex_fn(bpctl_dev_t *pbpctl_dev){ + + if (!pbpctl_dev) { + return -1; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_BYPASS_CAPS_EX; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + return(pbpctl_dev->bp_caps); + } } int get_bypass_slave_fn(bpctl_dev_t *pbpctl_dev,bpctl_dev_t **pbpctl_dev_out){ int idx_dev=0; - if (!pbpctl_dev) - return -1; - if ((pbpctl_dev->func==0)||(pbpctl_dev->func==2)) { - for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev!=NULL)&&(idx_devbus)&& - (bpctl_dev_arr[idx_dev].slot==pbpctl_dev->slot)) { - if ((pbpctl_dev->func==0)&& - (bpctl_dev_arr[idx_dev].func==1)) { - *pbpctl_dev_out=&bpctl_dev_arr[idx_dev]; - return 1; - } - if ((pbpctl_dev->func==2)&& - (bpctl_dev_arr[idx_dev].func==3)) { - *pbpctl_dev_out=&bpctl_dev_arr[idx_dev]; - return 1; - } - } - } - return -1; - } else return 0; + if (!pbpctl_dev) { + return -1; + } + + if (pbpctl_dev->bp_10g9) { + if (pbpctl_dev->func_p == 0) { + for (idx_dev = 0; ((idx_devbus_p)&& + (bpctl_dev_arr[idx_dev].slot_p == pbpctl_dev->slot_p)) { + if ((pbpctl_dev->func_p == 0)&& + (bpctl_dev_arr[idx_dev].func_p == 1)) { + *pbpctl_dev_out = &bpctl_dev_arr[idx_dev]; + return 1; + } + } + } + return -1; + } else { + return 0; + } + + } else { + + if ((pbpctl_dev->func_p==0)||(pbpctl_dev->func_p==2)) { + for (idx_dev = 0; ((idx_devbus_p)&& + (bpctl_dev_arr[idx_dev].slot_p==pbpctl_dev->slot_p)) { + if ((pbpctl_dev->func_p==0)&& + (bpctl_dev_arr[idx_dev].func_p==1)) { + *pbpctl_dev_out=&bpctl_dev_arr[idx_dev]; + return 1; + } + if ((pbpctl_dev->func_p==2)&& + (bpctl_dev_arr[idx_dev].func_p==3)) { + *pbpctl_dev_out=&bpctl_dev_arr[idx_dev]; + return 1; + } + } + } + return -1; + } else { + return 0; + } + } } -int is_bypass(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; - if ((pbpctl_dev->func==0)||(pbpctl_dev->func==2)) - return 1; - else return 0; -} int get_tx_fn(bpctl_dev_t *pbpctl_dev){ bpctl_dev_t *pbpctl_dev_b=NULL; - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev){ + return -1; + } - if ((pbpctl_dev->bp_caps&TPL_CAP)&& - (pbpctl_dev->bp_caps&SW_CTL_CAP)) { - if ((pbpctl_dev->bp_tpl_flag)) - return BP_NOT_CAP; - } else if ((pbpctl_dev_b=get_master_port_fn(pbpctl_dev))) { - if ((pbpctl_dev_b->bp_caps&TPL_CAP)&& - (pbpctl_dev_b->bp_tpl_flag)) - return BP_NOT_CAP; - } - return(tx_status(pbpctl_dev)); + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + bpctl_dev_t *pbpctl_dev_c, *pbpctl_dev_m; + int ret=-1; + + if (!(pbpctl_dev->bp_caps&TX_CTL_CAP)) { + return -1; + } + + memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf)); + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t)); + if(is_bypass_fn(pbpctl_dev)) { + pbpctl_dev_m = pbpctl_dev; + } else { + pbpctl_dev_m = get_master_port_fn(pbpctl_dev); + } + + if (!pbpctl_dev_m) { + return -1; + } + + bp_cmd_buf.cmd.cmd_dev_num= (pbpctl_dev_m->func_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_data.tx_dis.port_num= + (pbpctl_dev_m->func_p == 0)?pbpctl_dev->func_p:(pbpctl_dev->func_p-2); + + bp_cmd_buf.cmd.cmd_id=CMD_GET_TX; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + if ((pbpctl_dev->bp_caps&TPL_CAP)&& + (pbpctl_dev->bp_caps&SW_CTL_CAP)) { + if ((pbpctl_dev->bp_tpl_flag)) { + return BP_NOT_CAP; + } + } else if ((pbpctl_dev_b=get_master_port_fn(pbpctl_dev))) { + if ((pbpctl_dev_b->bp_caps&TPL_CAP)&& + (pbpctl_dev_b->bp_tpl_flag)) { + return BP_NOT_CAP; + } + } + return(tx_status(pbpctl_dev)); + } } int get_bp_force_link_fn(int dev_num){ static bpctl_dev_t *bpctl_dev_curr; - if ((dev_num<0)||(dev_num>device_num)||(bpctl_dev_arr[dev_num].pdev==NULL)) + if ((dev_num<0)||(dev_num>device_num)||(bpctl_dev_arr[dev_num].pdev==NULL)) { return -1; + } bpctl_dev_curr=&bpctl_dev_arr[dev_num]; - - return(bp_force_link_status(bpctl_dev_curr)); } static int get_bypass_link_status (bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; - if (pbpctl_dev->media_type == bp_fiber) - return((BPCTL_READ_REG(pbpctl_dev, CTRL) & BPCTLI_CTRL_SWDPIN1)); - else - return((BPCTL_READ_REG(pbpctl_dev, STATUS) & BPCTLI_STATUS_LU)); + if (!pbpctl_dev) { + return -1; + } + + if (pbpctl_dev->media_type == bp_fiber) { + return((BPCTL_READ_REG(pbpctl_dev, CTRL) & BPCTLI_CTRL_SWDPIN1)); + } else { + return((BPCTL_READ_REG(pbpctl_dev, STATUS) & BPCTLI_STATUS_LU)); + } } +#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_b=get_status_port_fn(pbpctl_dev))) { + return; + } if (!pbpctl_dev->bp_tpl_flag) { set_tx(pbpctl_dev_b,1); @@ -4621,22 +6911,45 @@ static void bp_tpl_timer_fn(unsigned long param){ link1 = get_bypass_link_status(pbpctl_dev); link2 = get_bypass_link_status(pbpctl_dev_b); + + + if(link1) { + pbpctl_dev->tpl_wait = 0; + } + if(link2) { + pbpctl_dev_b->tpl_wait = 0; + } + + if ((link1)&&(tx_status(pbpctl_dev))) { if ((!link2)&&(tx_status(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(pbpctl_dev,0); } else if (!tx_status(pbpctl_dev_b)) { + pbpctl_dev_b->tpl_wait = 1; set_tx(pbpctl_dev_b,1); } } else if ((!link1)&&(tx_status(pbpctl_dev))) { if ((link2)&&(tx_status(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(pbpctl_dev_b,0); } } else if ((link1)&&(!tx_status(pbpctl_dev))) { if ((link2)&&(tx_status(pbpctl_dev_b))) { + pbpctl_dev->tpl_wait = 1; set_tx(pbpctl_dev,1); } } else if ((!link1)&&(!tx_status(pbpctl_dev))) { if ((link2)&&(tx_status(pbpctl_dev_b))) { + pbpctl_dev->tpl_wait = 1; set_tx(pbpctl_dev,1); } } @@ -4647,34 +6960,44 @@ static void bp_tpl_timer_fn(unsigned long param){ int get_tpl_fn(bpctl_dev_t *pbpctl_dev); void remove_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev){ bpctl_dev_t *pbpctl_dev_b=NULL; - if (!pbpctl_dev) - return; - if (pbpctl_dev->bp_caps_ex&TPL2_CAP_EX) - return; + + if (!pbpctl_dev) { + return; + } + if (pbpctl_dev->bp_caps_ex&TPL2_CAP_EX) { + return; + } pbpctl_dev_b=get_status_port_fn(pbpctl_dev); if (pbpctl_dev->bp_caps&TPL_CAP) { if (get_tpl_fn(pbpctl_dev)) { - del_timer_sync(&pbpctl_dev->bp_tpl_timer); pbpctl_dev->bp_tpl_flag=0; pbpctl_dev_b=get_status_port_fn(pbpctl_dev); - if (pbpctl_dev_b) - set_tx(pbpctl_dev_b,1); + if (pbpctl_dev_b) { + set_tx(pbpctl_dev_b,1); + } set_tx(pbpctl_dev,1); } } return; } + int init_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; + + if (!pbpctl_dev) { + return -1; + } if (pbpctl_dev->bp_caps&TPL_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; } return BP_NOT_CAP; @@ -4689,8 +7012,9 @@ int set_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev, unsigned int param){ mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+1); return BP_OK; }; - if ((!param)&&(pbpctl_dev->bp_tpl_flag)) - remove_bypass_tpl_auto(pbpctl_dev); + if ((!param)&&(pbpctl_dev->bp_tpl_flag)) { + remove_bypass_tpl_auto(pbpctl_dev); + } return BP_OK; } @@ -4698,162 +7022,446 @@ int set_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev, unsigned int param){ } int get_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev){ - if (!pbpctl_dev) - return -1; + + if (!pbpctl_dev) { + return -1; + } + if (pbpctl_dev->bp_caps&TPL_CAP) { return pbpctl_dev->bp_tpl_flag; } return BP_NOT_CAP; } + int set_tpl_fn(bpctl_dev_t *pbpctl_dev, int tpl_mode){ + bpctl_dev_t *pbpctl_dev_b=NULL; - bpctl_dev_t *pbpctl_dev_b=NULL; - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } - pbpctl_dev_b=get_status_port_fn(pbpctl_dev); + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + bpctl_dev_t *pbpctl_dev_c; + int ret=-1; - if (pbpctl_dev->bp_caps&TPL_CAP) { - if (tpl_mode) { - if ((pbpctl_dev_b=get_status_port_fn(pbpctl_dev))) - set_tx(pbpctl_dev_b,1); - set_tx(pbpctl_dev,1); - } - if ((TPL_IF_SERIES(pbpctl_dev->subdevice))|| - (pbpctl_dev->bp_caps_ex&TPL2_CAP_EX)) { - pbpctl_dev->bp_tpl_flag=tpl_mode; - if (!tpl_mode) - tpl_hw_off(pbpctl_dev); - else - tpl_hw_on(pbpctl_dev); - } else - set_bypass_tpl_auto(pbpctl_dev, tpl_mode); - return 0; - } - return BP_NOT_CAP; + if (!(pbpctl_dev->bp_caps&TPL_CAP)) { + 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_p == 0)? 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 (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + pbpctl_dev_b=get_status_port_fn(pbpctl_dev); + + if (pbpctl_dev->bp_caps&TPL_CAP) { + if (tpl_mode) { + if ((pbpctl_dev_b=get_status_port_fn(pbpctl_dev))) + set_tx(pbpctl_dev_b,1); + set_tx(pbpctl_dev,1); + } + if ((TPL_IF_SERIES(pbpctl_dev->subdevice))|| + (pbpctl_dev->bp_caps_ex&TPL2_CAP_EX)) { + pbpctl_dev->bp_tpl_flag=tpl_mode; + if (!tpl_mode) { + tpl_hw_off(pbpctl_dev); + } else { + tpl_hw_on(pbpctl_dev); + } + } else { + set_bypass_tpl_auto(pbpctl_dev, tpl_mode); + } + return 0; + } + return BP_NOT_CAP; + } } + int get_tpl_fn(bpctl_dev_t *pbpctl_dev){ int ret=BP_NOT_CAP; - if (!pbpctl_dev) - return -1; + if (!pbpctl_dev) { + return -1; + } + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; - if (pbpctl_dev->bp_caps&TPL_CAP) { - if (pbpctl_dev->bp_caps_ex&TPL2_CAP_EX) - return(tpl2_flag_status(pbpctl_dev)); - ret=pbpctl_dev->bp_tpl_flag; - } + bpctl_dev_t *pbpctl_dev_c; + int ret=-1; + + if (!(pbpctl_dev->bp_caps&TPL_CAP)) { + 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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_TPL; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + if (pbpctl_dev->bp_caps&TPL_CAP) { + if (pbpctl_dev->bp_caps_ex&TPL2_CAP_EX) { + return(tpl2_flag_status(pbpctl_dev)); + } + ret=pbpctl_dev->bp_tpl_flag; + } + } return ret; } + + //#ifdef PMC_FIX_FLAG -int set_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode){ - if (!pbpctl_dev) - return -1; +int set_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev, int bp_wait_at_pwup){ + if (!pbpctl_dev) { + return -1; + } - if (pbpctl_dev->bp_caps & SW_CTL_CAP) { - //bp_lock(pbp_device_block); - cmnd_on(pbpctl_dev); - if (!tap_mode) - bp_wait_at_pwup_dis(pbpctl_dev); - else - bp_wait_at_pwup_en(pbpctl_dev); - cmnd_off(pbpctl_dev); + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + bpctl_dev_t *pbpctl_dev_c; + int ret=-1; - // bp_unlock(pbp_device_block); - return BP_OK; - } - return BP_NOT_CAP; + if (!(pbpctl_dev->bp_caps&BP_CAP)) { + 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_p == 0)? 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 (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + //bp_lock(pbp_device_block); + cmnd_on(pbpctl_dev); + if (!bp_wait_at_pwup) { + bp_wait_at_pwup_dis(pbpctl_dev); + } else { + bp_wait_at_pwup_en(pbpctl_dev); + } + cmnd_off(pbpctl_dev); + // bp_unlock(pbp_device_block); + return BP_OK; + } + return BP_NOT_CAP; + } } + + int get_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev){ int ret=0; - if (!pbpctl_dev) - return -1; - // bp_lock(pbp_device_block); - ret=bp_wait_at_pwup_status(pbpctl_dev); - // bp_unlock(pbp_device_block); + if (!pbpctl_dev) { + return -1; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-1; + + if (!(pbpctl_dev->bp_caps&BP_CAP)) { + 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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_BP_WAIT_AT_PWUP; + + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + // bp_lock(pbp_device_block); + ret=bp_wait_at_pwup_status(pbpctl_dev); + // bp_unlock(pbp_device_block); + return ret; + } - return ret; } -int set_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev, int tap_mode){ - if (!pbpctl_dev) - return -1; +int set_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev, int bp_hw_reset){ - if (pbpctl_dev->bp_caps & SW_CTL_CAP) { - // bp_lock(pbp_device_block); - cmnd_on(pbpctl_dev); + if (!pbpctl_dev) { + return -1; + } - if (!tap_mode) - bp_hw_reset_dis(pbpctl_dev); - else - bp_hw_reset_en(pbpctl_dev); - cmnd_off(pbpctl_dev); - // bp_unlock(pbp_device_block); - return BP_OK; - } - return BP_NOT_CAP; + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-1; + + if (!(pbpctl_dev->bp_caps&BP_CAP)) { + 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_p == 0)? 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 (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + + if (pbpctl_dev->bp_caps & SW_CTL_CAP) { + // bp_lock(pbp_device_block); + cmnd_on(pbpctl_dev); + + if (!bp_hw_reset) { + bp_hw_reset_dis(pbpctl_dev); + } else { + bp_hw_reset_en(pbpctl_dev); + } + cmnd_off(pbpctl_dev); + // bp_unlock(pbp_device_block); + return BP_OK; + } + return BP_NOT_CAP; + } } + + int get_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev){ int ret=0; - if (!pbpctl_dev) - return -1; - //bp_lock(pbp_device_block); - ret=bp_hw_reset_status(pbpctl_dev); + if (!pbpctl_dev) { + return -1; + } - //bp_unlock(pbp_device_block); + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; - return ret; + bpctl_dev_t *pbpctl_dev_c; + ret=-1; + + if (!(pbpctl_dev->bp_caps&BP_CAP)) { + 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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_BP_HW_RESET; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + + //bp_lock(pbp_device_block); + ret=bp_hw_reset_status(pbpctl_dev); + + //bp_unlock(pbp_device_block); + + return ret; + } } //#endif /*PMC_FIX_FLAG*/ + int get_bypass_info_fn(bpctl_dev_t *pbpctl_dev, char *dev_name, char *add_param){ - if (!pbpctl_dev) - return -1; - if (!is_bypass_fn(pbpctl_dev)) - return -1; - strcpy(dev_name,pbpctl_dev->name); - *add_param= pbpctl_dev->bp_fw_ver; - return 0; + + if (!pbpctl_dev) { + return -1; + } + + if (!is_bypass_fn(pbpctl_dev)) { + return -1; + } + + if ((pbpctl_dev->bp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + int ret=-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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_GET_BYPASS_INFO; + + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + ret=0; + } + return ret; + + } else { + strcpy(dev_name,pbpctl_dev->name); + *add_param= pbpctl_dev->bp_fw_ver; + return 0; + } } int get_dev_idx_bsf(int bus, int slot, int func){ int idx_dev=0; //if_scan(); - for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev!=NULL)&&(idx_devbp_40g) || (pbpctl_dev->bp_rang)) { + bp_cmd_t bp_cmd_buf; + bp_cmd_rsp_t bp_rsp_buf; + + bpctl_dev_t *pbpctl_dev_c; + ret=-1; + + if (!(pbpctl_dev->bp_caps&BP_CAP)) { + 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_p == 0)? 0:1; + bp_cmd_buf.cmd.cmd_id=CMD_SET_BP_MANUF; + if (!(pbpctl_dev_c=get_status_port_fn(pbpctl_dev))) { + return -1; + } + + 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; + + } else { + + //bp_lock(pbp_device_block); + + //bp_unlock(pbp_device_block); + + return ret; + } +} + + + static int get_dev_idx(int ifindex){ int idx_dev=0; - for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev!=NULL)&&(idx_devheader_ops = ð_header_ops; + dev->type = ARPHRD_ETHER; + random_ether_addr(dev->dev_addr); */ + + memcpy(dev->dev_addr, &str[0], 6); + ether_setup(dev); +#ifdef BPVM_VMWARE + dev->hard_header_len = ETH_HLEN; + dev->mtu = ETH_DATA_LEN; + dev->addr_len = ETH_ALEN; + dev->tx_queue_len = 1000; /* Ethernet wants good queues */ + dev->flags = IFF_BROADCAST|IFF_MULTICAST; + memset(dev->broadcast, 0xFF, ETH_ALEN); +#endif + +} + + +int bpvm_open(struct net_device *netdev) +{ + /* struct bpvm_priv *adapter = netdev_priv(netdev); + tweak tx_queue_len according to speed/duplex + and adjust the timeout factor + netdev->tx_queue_len = adapter->tx_queue_len; */ + netdev->features &= ~NETIF_F_TSO; + netif_carrier_on(netdev); +#ifdef CONFIG_NETDEVICES_MULTIQUEUE + netif_wake_subqueue(netdev, 0); +#endif + netif_wake_queue(netdev); + + return 0; +} + +int bpvm_close(struct net_device *netdev) +{ +#ifdef NETIF_F_LLTX +#ifdef CONFIG_NETDEVICES_MULTIQUEUE + netif_stop_subqueue(netdev, 0); +#else + netif_stop_queue(netdev); +#endif +#else + netif_tx_disable(netdev); +#endif + netif_carrier_off(netdev); + return 0; +} + + + + +s32 bpvm_poll_eerd_eewr_done(bpctl_dev_t *pbpctl_dev, int ee_reg) +{ + u32 attempts = 100000; + u32 i, reg = 0; + s32 ret_val = -BPCTL_ERR_NVM; + + for (i = 0; i < attempts; i++) { + if (ee_reg == BPCTL_NVM_POLL_READ) { + reg = BPCTL_READ_REG(pbpctl_dev, EERD); + } else { + reg = BPCTL_READ_REG(pbpctl_dev, EEWR); + } + + if (reg & BPCTL_NVM_RW_REG_DONE) { + ret_val = BPCTL_SUCCESS; + break; + } + + usec_delay_bp(5); + } + + return ret_val; +} + + + +s32 bpvm_read_nvm_eerd(bpctl_dev_t *pbpctl_dev, u16 offset, u16 words, u16 *data) +{ + u32 i, eerd = 0; + s32 ret_val = BPCTL_SUCCESS; + for (i = 0; i < words; i++) { + eerd = ((offset+i) << BPCTL_NVM_RW_ADDR_SHIFT) + + BPCTL_NVM_RW_REG_START; + + BPCTL_WRITE_REG(pbpctl_dev, EERD, eerd); + ret_val = bpvm_poll_eerd_eewr_done(pbpctl_dev, BPCTL_NVM_POLL_READ); + if (ret_val) + break; + + data[i] = (BPCTL_READ_REG(pbpctl_dev, EERD) >> + BPCTL_NVM_RW_REG_DATA); + } + + return ret_val; +} + + +static int32_t +bpvm_id_led_init(bpctl_dev_t *pbpctl_dev) +{ + uint32_t ledctl; + const uint32_t ledctl_mask = 0x000000FF; + const uint32_t ledctl_on = BPCTLI_LEDCTL_MODE_LED_ON; + const uint32_t ledctl_off = BPCTLI_LEDCTL_MODE_LED_OFF; + uint16_t i, temp; + const uint16_t led_mask = 0x0F; + uint16_t eeprom_data; + + if ((pbpctl_dev->bp_10g)||(pbpctl_dev->bp_10g9)||(pbpctl_dev->bp_10gb)) { + return 0; + } + + ledctl = BPCTL_READ_REG(pbpctl_dev, LEDCTL); + pbpctl_dev->ledctl_default = ledctl; + pbpctl_dev->ledctl_mode1 = pbpctl_dev->ledctl_default; + pbpctl_dev->ledctl_mode2 = pbpctl_dev->ledctl_default; +#if 1 + if (pbpctl_dev->bp_i80) { + + + if (bpvm_read_nvm_eerd(pbpctl_dev, BPCTLI_EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) { + printk("bpvm: EEPROM Read Error\n"); + return -1; + } + if ((eeprom_data == ID_LED_RESERVED_0000) || + (eeprom_data == ID_LED_RESERVED_FFFF)) { + eeprom_data = /*ID_LED_DEFAULT*/ 0x8918; + } + } + else +#endif + eeprom_data = /*ID_LED_DEFAULT*/ 0x8818; + for (i = 0; i < 4; i++) { + temp = (eeprom_data >> (i << 2)) & led_mask; + switch (temp) { + case ID_LED_ON1_DEF2: + case ID_LED_ON1_ON2: + case ID_LED_ON1_OFF2: + pbpctl_dev->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); + pbpctl_dev->ledctl_mode1 |= ledctl_on << (i << 3); + break; + case ID_LED_OFF1_DEF2: + case ID_LED_OFF1_ON2: + case ID_LED_OFF1_OFF2: + pbpctl_dev->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); + pbpctl_dev->ledctl_mode1 |= ledctl_off << (i << 3); + break; + default: + /* Do nothing */ + break; + } + switch (temp) { + case ID_LED_DEF1_ON2: + case ID_LED_ON1_ON2: + case ID_LED_OFF1_ON2: + pbpctl_dev->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); + pbpctl_dev->ledctl_mode2 |= ledctl_on << (i << 3); + break; + case ID_LED_DEF1_OFF2: + case ID_LED_ON1_OFF2: + case ID_LED_OFF1_OFF2: + pbpctl_dev->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); + pbpctl_dev->ledctl_mode2 |= ledctl_off << (i << 3); + break; + default: + /* Do nothing */ + break; + } + } + return 0; +} + + +s32 bpvm1_led_on(bpctl_dev_t *pbpctl_dev) +{ + + BPCTL_WRITE_REG(pbpctl_dev, LEDCTL, pbpctl_dev->ledctl_mode2); + + return 0; +} + +s32 bpvm1_led_off(bpctl_dev_t *pbpctl_dev) +{ + + BPCTL_WRITE_REG(pbpctl_dev, LEDCTL, pbpctl_dev->ledctl_mode1); + return 0; +} + +/** + * ixgbe_led_on_generic - Turns on the software controllable LEDs. + * @hw: pointer to hardware structure + * @index: led number to turn on + **/ +s32 bpvm10_led_on(bpctl_dev_t *pbpctl_dev) +{ + u32 led_reg = BP10G_READ_REG(pbpctl_dev, LEDCTL); + /* To turn on the LED, set mode to ON. */ + led_reg &= ~0xf0000; + led_reg |= 0xe0000; + BP10G_WRITE_REG(pbpctl_dev, LEDCTL, led_reg); + BP10G_WRITE_FLUSH(pbpctl_dev); + + return 0; +} + +/** + * ixgbe_led_off_generic - Turns off the software controllable LEDs. + * @hw: pointer to hardware structure + * @index: led number to turn off + **/ +s32 bpvm10_led_off(bpctl_dev_t *pbpctl_dev) +{ + u32 led_reg = BP10G_READ_REG(pbpctl_dev, LEDCTL); + + + led_reg &= ~0xf0000; + led_reg |= 0xf0000; + + + /* To turn off the LED, set mode to OFF. */ + BP10G_WRITE_REG(pbpctl_dev, LEDCTL, led_reg); + BP10G_WRITE_FLUSH(pbpctl_dev); + + return 0; +} + +void bpvm_led_on(bpctl_dev_t *pbpctl_dev){ + + + if ((pbpctl_dev->bp_10g)||(pbpctl_dev->bp_10g9)) { + bpvm10_led_on(pbpctl_dev); + } else { + bpvm1_led_on(pbpctl_dev); + } +} + + + +void bpvm_led_off(bpctl_dev_t *pbpctl_dev){ + + + if ((pbpctl_dev->bp_10g)||(pbpctl_dev->bp_10g9)) { + bpvm10_led_off(pbpctl_dev); + } else { + bpvm1_led_off(pbpctl_dev); + } +} + +int32_t +bpvm_cleanup_led(bpctl_dev_t *pbpctl_dev) +{ + if ((pbpctl_dev->bp_10g)||(pbpctl_dev->bp_10g9)) { + BP10G_WRITE_REG(pbpctl_dev, LEDCTL, pbpctl_dev->ledctl_default); + } else { + BPCTL_WRITE_REG(pbpctl_dev, LEDCTL, pbpctl_dev->ledctl_default); + } + + return 0; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) +static void bpvm_led_blink_callback(unsigned long data) +{ + + bpctl_dev_t *pbpctl_dev = (bpctl_dev_t *) data; +#else +static void bpvm_led_blink_callback(struct timer_list *t) +{ + bpctl_dev_t *pbpctl_dev = from_timer(pbpctl_dev, t, blink_timer); +#endif + + if (test_and_change_bit(0, (volatile unsigned long *)&pbpctl_dev->led_status)) { + bpvm_led_off(pbpctl_dev); + } else { + bpvm_led_on(pbpctl_dev); + } + + mod_timer(&pbpctl_dev->blink_timer, jiffies + BPVM_ID_INTERVAL); +} + +static void +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) +wait_callback(unsigned long data) +{ + bpctl_dev_t *pbpctl_dev = (bpctl_dev_t *) data; +#else +wait_callback(struct timer_list *t) +{ + bpctl_dev_t *pbpctl_dev = from_timer(pbpctl_dev, t, wait_timer); +#endif + + del_timer_sync(&pbpctl_dev->blink_timer); + + bpvm_led_off(pbpctl_dev); + clear_bit(0, (volatile unsigned long *)&pbpctl_dev->led_status); + bpvm_cleanup_led(pbpctl_dev); +} + +int32_t +bpvm_setup_led(bpctl_dev_t *pbpctl_dev) +{ + if ((pbpctl_dev->bp_10g)||(pbpctl_dev->bp_10g9)) { + pbpctl_dev->ledctl_default= BP10G_READ_REG(pbpctl_dev, LEDCTL); + } else { +#if 0 + if (pbpctl_dev->media_type == bp_fiber) { + ledctl = BPCTL_READ_REG(pbpctl_dev, LEDCTL); + /* Save current LEDCTL settings */ + pbpctl_dev->ledctl_default = ledctl; + /* Turn off LED0 */ + ledctl &= ~(BPCTLI_LEDCTL_LED0_IVRT | + BPCTLI_LEDCTL_LED0_BLINK | + BPCTLI_LEDCTL_LED0_MODE_MASK); + ledctl |= (BPCTLI_LEDCTL_MODE_LED_OFF << + BPCTLI_LEDCTL_LED0_MODE_SHIFT); + + + ledctl &= ~(BPCTLI_LEDCTL_LED1_IVRT | + BPCTLI_LEDCTL_LED1_BLINK | + BPCTLI_LEDCTL_LED1_MODE_MASK); + ledctl |= (BPCTLI_LEDCTL_MODE_LED_OFF << + BPCTLI_LEDCTL_LED1_MODE_SHIFT); + + ledctl &= ~(BPCTLI_LEDCTL_LED2_IVRT | + BPCTLI_LEDCTL_LED2_BLINK | + BPCTLI_LEDCTL_LED2_MODE_MASK); + ledctl |= (BPCTLI_LEDCTL_MODE_LED_OFF << + BPCTLI_LEDCTL_LED2_MODE_SHIFT); + + ledctl &= ~(BPCTLI_LEDCTL_LED3_IVRT | + BPCTLI_LEDCTL_LED3_BLINK | + BPCTLI_LEDCTL_LED3_MODE_MASK); + ledctl |= (BPCTLI_LEDCTL_MODE_LED_OFF << + BPCTLI_LEDCTL_LED3_MODE_SHIFT); + BPCTL_WRITE_REG(pbpctl_dev, LEDCTL, ledctl); + } else if (pbpctl_dev->media_type == bp_copper) +#endif + BPCTL_WRITE_REG(pbpctl_dev, LEDCTL, pbpctl_dev->ledctl_mode1); + } + return 0; +} + +#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 + + + + +static int +bpvm_blink(bpctl_dev_t *pbpctl_dev, uint32_t data) +{ + + if (!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ)) { + data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ); + } + + if (pbpctl_dev->blink_timer.function) { + del_timer_sync(&pbpctl_dev->wait_timer); + del_timer_sync(&pbpctl_dev->blink_timer); + bpvm_led_off(pbpctl_dev); + clear_bit(0, (volatile unsigned long *)&pbpctl_dev->led_status); + bpvm_cleanup_led(pbpctl_dev); + } + + + if (!pbpctl_dev->wait_timer.function) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) + init_timer(&pbpctl_dev->wait_timer); + pbpctl_dev->wait_timer.function = wait_callback; + pbpctl_dev->wait_timer.data = (unsigned long) pbpctl_dev; +#else + timer_setup(&pbpctl_dev->wait_timer, wait_callback, 0); +#endif + } + + if (!pbpctl_dev->blink_timer.function) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)) + init_timer(&pbpctl_dev->blink_timer); + pbpctl_dev->blink_timer.function = bpvm_led_blink_callback; + pbpctl_dev->blink_timer.data = (unsigned long) pbpctl_dev; +#else + timer_setup(&pbpctl_dev->blink_timer, bpvm_led_blink_callback, 0); +#endif + } + + bpvm_setup_led(pbpctl_dev); + mod_timer(&pbpctl_dev->blink_timer, jiffies); + mod_timer(&pbpctl_dev->wait_timer, jiffies+data*HZ); + + return 0; +} + +int set_bp_blink_fn(int dev_num, int timeout){ + int ret=0; + static bpctl_dev_t *pbpctl_dev; + + if ((dev_num<0)||(dev_num>device_num)||(bpctl_dev_arr[dev_num].pdev==NULL)) { + return -1; + } + pbpctl_dev=&bpctl_dev_arr[dev_num]; + + bpvm_blink(pbpctl_dev,timeout); + return ret; +} + + +int get_bp_vmnic_info_fn(int dev_num, char *add_param){ + static bpctl_dev_t *bpctl_dev_curr; + + if ((dev_num<0)||(dev_num>device_num)||(bpctl_dev_arr[dev_num].pdev==NULL)) { + return -1; + } + bpctl_dev_curr=&bpctl_dev_arr[dev_num]; + add_param[0]=dev_num+1; + + if (bpctl_dev_curr->ndev) { + memcpy(&add_param[1],bpctl_dev_curr->ndev->name, 12); + } + return 0; +} + +int get_bp_oem_data_fn(int dev_num, unsigned int key, char *add_param){ + static bpctl_dev_t *bpctl_dev_curr; + + if ((dev_num<0)||(dev_num>device_num)||(bpctl_dev_arr[dev_num].pdev==NULL)) { + return -1; + } + add_param[0]=dev_num+1; + if (key!=7335) { + return 0; + } + bpctl_dev_curr=&bpctl_dev_arr[dev_num]; + memcpy(&add_param[1],bpctl_dev_curr->oem_data, 20); + return 0; +} + +int get_bp_pci_info_fn(int dev_num, char *add_param){ + + if ((dev_num<0)||(dev_num>device_num)||(bpctl_dev_arr[dev_num].pdev==NULL)) { + return -1; + } + add_param[0]=dev_num+1; + add_param[1]= bpctl_dev_arr[dev_num].bus; + add_param[2]= bpctl_dev_arr[dev_num].slot; + add_param[3]= bpctl_dev_arr[dev_num].func; + return 0; +} + +int get_bp_all_info_fn(int dev_num, char *add_param){ + static bpctl_dev_t *bpctl_dev_curr; + + if ((dev_num<0)||(dev_num>device_num)||(bpctl_dev_arr[dev_num].pdev==NULL)) { + return -1; + } + bpctl_dev_curr=&bpctl_dev_arr[dev_num]; + add_param[0]=dev_num+1; + add_param[1]= bpctl_dev_arr[dev_num].bus; + add_param[2]= bpctl_dev_arr[dev_num].slot; + add_param[3]= bpctl_dev_arr[dev_num].func; + + if (bpctl_dev_curr->ndev) { + memcpy(&add_param[4], bpctl_dev_curr->ndev->dev_addr, 6); + } + return 0; +} + +int get_bypass_slave_fn_vm(int dev_num,int *dev_idx_slave){ + int idx_dev=0; + static bpctl_dev_t *bpctl_dev_curr; + + if ((dev_num<0)||(dev_num>device_num)||(bpctl_dev_arr[dev_num].pdev==NULL)) { + return -1; + } + + bpctl_dev_curr=&bpctl_dev_arr[dev_num]; + if ((bpctl_dev_curr->func_p==0)||(bpctl_dev_curr->func_p==2)) { + for (idx_dev = 0; ((idx_devbus_p)&& + (bpctl_dev_arr[idx_dev].slot_p==bpctl_dev_curr->slot_p)) { + if ((bpctl_dev_curr->func_p==0)&& + (bpctl_dev_arr[idx_dev].func_p==1)) { + *dev_idx_slave= idx_dev; + return 1; + } + if ((bpctl_dev_curr->func_p==2)&& + (bpctl_dev_arr[idx_dev].func_p==3)) { + *dev_idx_slave= idx_dev; + return 1; + } + } + } + return -1; + } else return 0; +} + + +int get_bypass_slave_sd_vm(int dev_idx){ + int dev_idx_slave=0; + + int ret=get_bypass_slave_fn_vm(dev_idx, &dev_idx_slave); + if (ret==1) { + return(dev_idx_slave+1) ; + } + return -1; + +} + + + +static int bpvm_xmit_frame_ring(struct sk_buff *skb, + struct net_device *netdev) +{ + unsigned long flags; + struct bpvm_priv *adapter = netdev_priv(netdev); + bp_cmd_vm_t *bp_cmd_vm_buf; + bp_cmd_vm_rsp_t bp_rsp_buf; + int dev_idx=0; + struct sk_buff *skb_tmp; + unsigned int cmd_vm_id=0; + static bpctl_dev_t *pbpctl_dev; + + if (unlikely(skb->len <= 0)) { + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + if (!spin_trylock_irqsave(&bypass_wr_lock, flags)) { + /* Collision - tell upper layer to requeue */ + return NETDEV_TX_LOCKED; + } + memset(&bp_rsp_buf, 0, sizeof(bp_cmd_vm_rsp_t)); + + + bp_rsp_buf.rsp.rsp_id = -1; + + if (skb->len == sizeof(bp_cmd_vm_t) ) { + memset(&adapter->bp_cmd_vm_buf, 0, sizeof(bp_cmd_vm_t)); + memcpy(&adapter->bp_cmd_vm_buf, skb->data, sizeof(bp_cmd_vm_t)); + + if (!(memcmp(&adapter->bp_cmd_vm_buf.cmd_vm.str, &str, 6))) { + dev_kfree_skb_any(skb); +#if 0 + printk("cmd_vm_dev_num=%d\n",adapter->bp_cmd_vm_buf.cmd_vm.cmd_vm_dev_num); + printk("cmd_vm_id=%d\n", adapter->bp_cmd_vm_buf.cmd_vm.cmd_vm_id); + printk("!!!bypass_mode=%d\n", adapter->bp_cmd_vm_buf.cmd_vm.cmd_vm_data); +#endif + bp_cmd_vm_buf = &adapter->bp_cmd_vm_buf; + dev_idx = adapter->bp_cmd_vm_buf.cmd_vm.cmd_vm_dev_num-1; + bp_rsp_buf.rsp.rsp_id = 0; + cmd_vm_id=bp_cmd_vm_buf->cmd_vm.cmd_vm_id; + if (cmd_vm_id != CMD_VM_GET_BP_DEV_NUM) { + if (dev_idx>=device_num) { + bp_rsp_buf.rsp.rsp_id=-1; + printk("bpvm: Device number error!\n"); + goto bpvm_out; + } + } + +#ifdef BPVM_VMWARE + if (!netif_queue_stopped(bpctl_dev_arr[dev_idx].ndev)) { + printk("bpvm: netif queue started!!!\n"); + } else { + printk("bpvm: netif queue stopped!!!\n"); + } + netif_carrier_on(bpctl_dev_arr[dev_idx].ndev); + netif_tx_start_all_queues(bpctl_dev_arr[dev_idx].ndev); + netif_carrier_off(bpctl_dev_arr[dev_idx].ndev); + if (!netif_queue_stopped(bpctl_dev_arr[dev_idx].ndev)) { + printk("bpvm: netif queue started!!!\n"); + } else { + printk("bpvm: netif queue stopped!!!\n"); + } + printk("bpvm: name=%s %lx %x\n", bpctl_dev_arr[dev_idx].ndev->name, bpctl_dev_arr[dev_idx].ndev->state, + bpctl_dev_arr[dev_idx].ndev->flags); + if (unlikely(test_bit(__LINK_STATE_BLOCKED,&bpctl_dev_arr[dev_idx].ndev->state))) { + printk("bpvm: _LINK_STATE_BLOCKED!!!!!\n"); + } +#endif + + pbpctl_dev=&bpctl_dev_arr[dev_idx]; + + + switch (bp_cmd_vm_buf->cmd_vm.cmd_vm_id) { + + case CMD_VM_SET_BYPASS_PWOFF : + bp_rsp_buf.rsp.rsp_id= set_bypass_pwoff_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_BYPASS_PWOFF : + bp_rsp_buf.rsp.rsp_data= get_bypass_pwoff_fn(pbpctl_dev); + break; + + case CMD_VM_SET_BYPASS_PWUP : + bp_rsp_buf.rsp.rsp_id= set_bypass_pwup_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_BYPASS_PWUP : + + bp_rsp_buf.rsp.rsp_data= get_bypass_pwup_fn(pbpctl_dev); + break; + + case CMD_VM_SET_BYPASS_WD : + bp_rsp_buf.rsp.rsp_data= set_bypass_wd_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_SET_BP_BLINK : + bp_rsp_buf.rsp.rsp_data= set_bp_blink_fn(dev_idx, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + + case CMD_VM_GET_BYPASS_WD : + bp_rsp_buf.rsp.rsp_id= get_bypass_wd_fn(pbpctl_dev,(int *)&(bp_rsp_buf.rsp.rsp_data)); + break; + + case CMD_VM_GET_WD_EXPIRE_TIME : + bp_rsp_buf.rsp.rsp_id= get_wd_expire_time_fn(pbpctl_dev, (int *)&(bp_rsp_buf.rsp.rsp_data)); + break; + + case CMD_VM_RESET_BYPASS_WD_TIMER : + bp_rsp_buf.rsp.rsp_data= reset_bypass_wd_timer_fn(pbpctl_dev); + break; + + case CMD_VM_GET_WD_SET_CAPS : + bp_rsp_buf.rsp.rsp_data= get_wd_set_caps_fn(pbpctl_dev); + break; + + case CMD_VM_SET_STD_NIC : + bp_rsp_buf.rsp.rsp_id= set_std_nic_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_STD_NIC : + bp_rsp_buf.rsp.rsp_data= get_std_nic_fn(pbpctl_dev); + break; + + case CMD_VM_SET_TAP : + bp_rsp_buf.rsp.rsp_id= set_tap_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_TAP : + bp_rsp_buf.rsp.rsp_data= get_tap_fn(pbpctl_dev); + break; + + case CMD_VM_GET_TAP_CHANGE : + bp_rsp_buf.rsp.rsp_data= get_tap_change_fn(pbpctl_dev); + break; + + case CMD_VM_SET_DIS_TAP : + bp_rsp_buf.rsp.rsp_id= set_dis_tap_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_DIS_TAP : + bp_rsp_buf.rsp.rsp_data= get_dis_tap_fn(pbpctl_dev); + break; + + case CMD_VM_SET_TAP_PWUP : + bp_rsp_buf.rsp.rsp_id= set_tap_pwup_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_TAP_PWUP : + bp_rsp_buf.rsp.rsp_data= get_tap_pwup_fn(pbpctl_dev); + break; + + case CMD_VM_SET_WD_EXP_MODE: + bp_rsp_buf.rsp.rsp_id= set_wd_exp_mode_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_WD_EXP_MODE: + bp_rsp_buf.rsp.rsp_data= get_wd_exp_mode_fn(pbpctl_dev); + break; + + case CMD_VM_GET_DIS_BYPASS: + bp_rsp_buf.rsp.rsp_data= get_dis_bypass_fn(pbpctl_dev); + break; + + case CMD_VM_SET_DIS_BYPASS: + bp_rsp_buf.rsp.rsp_id= set_dis_bypass_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_BYPASS_CHANGE: + bp_rsp_buf.rsp.rsp_data= get_bypass_change_fn(pbpctl_dev); + break; + + case CMD_VM_GET_BYPASS: + bp_rsp_buf.rsp.rsp_data= get_bypass_fn(pbpctl_dev); + break; + + case CMD_VM_SET_BYPASS: + bp_rsp_buf.rsp.rsp_id= set_bypass_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_BYPASS_CAPS: + bp_rsp_buf.rsp.rsp_data= get_bypass_caps_fn(pbpctl_dev); + break; + + case CMD_VM_SET_WD_AUTORESET: + bp_rsp_buf.rsp.rsp_id= set_wd_autoreset_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + + break; + case CMD_VM_GET_WD_AUTORESET: + + bp_rsp_buf.rsp.rsp_data= get_wd_autoreset_fn(pbpctl_dev); + break; + + + case CMD_VM_GET_BYPASS_SLAVE: + bp_rsp_buf.rsp.rsp_data= get_bypass_slave_sd_vm(dev_idx); + break; + + case CMD_VM_IS_BYPASS: + if (adapter->bp_cmd_vm_buf.cmd_vm.cmd_vm_dev_num==0) { + bp_rsp_buf.rsp.rsp_data= 2; + } else + bp_rsp_buf.rsp.rsp_data= is_bypass_fn(pbpctl_dev); + break; + case CMD_VM_SET_TX: + bp_rsp_buf.rsp.rsp_id= set_tx_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + case CMD_VM_GET_TX: + bp_rsp_buf.rsp.rsp_data= get_tx_fn(pbpctl_dev); + break; + + case CMD_VM_SET_DISC : + bp_rsp_buf.rsp.rsp_id=set_disc_fn(pbpctl_dev,bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + + case CMD_VM_GET_DISC : + bp_rsp_buf.rsp.rsp_data=get_disc_fn(pbpctl_dev); + break; + case CMD_VM_GET_DISC_CHANGE : + bp_rsp_buf.rsp.rsp_data=get_disc_change_fn(pbpctl_dev); + break; + case CMD_VM_SET_DIS_DISC : + bp_rsp_buf.rsp.rsp_id=set_dis_disc_fn(pbpctl_dev,bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + case CMD_VM_GET_DIS_DISC : + bp_rsp_buf.rsp.rsp_data=get_dis_disc_fn(pbpctl_dev); + break; + case CMD_VM_SET_DISC_PWUP : + bp_rsp_buf.rsp.rsp_id=set_disc_pwup_fn(pbpctl_dev,bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + case CMD_VM_GET_DISC_PWUP : + bp_rsp_buf.rsp.rsp_data=get_disc_pwup_fn(pbpctl_dev); + break; + case CMD_VM_GET_BYPASS_INFO: + + bp_rsp_buf.rsp.rsp_id= get_bypass_info_fn(pbpctl_dev, (char *)&bp_rsp_buf.rsp_info.info, (char *)&bp_rsp_buf.rsp_info.fw_ver); + break; + case CMD_VM_GET_BP_DRV_VER: + bp_rsp_buf.rsp.rsp_id=0; + memcpy(&bp_rsp_buf.rsp_info.info, BP_MOD_VER, sizeof(BP_MOD_VER)); + break; + + case CMD_VM_GET_BP_DEV_NUM: + + bp_rsp_buf.rsp.rsp_id= device_num; + break; + + case CMD_VM_GET_BP_VMNIC_INFO: + if (adapter->bp_cmd_vm_buf.cmd_vm.cmd_vm_dev_num==0) { + bp_rsp_buf.rsp_info.info[0]=0; + memcpy(&bp_rsp_buf.rsp_info.info[1],netdev->name, 12); + bp_rsp_buf.rsp.rsp_id=0; + } else + bp_rsp_buf.rsp.rsp_id= get_bp_vmnic_info_fn(dev_idx, (char *)&bp_rsp_buf.rsp_info.info); + break; + + case CMD_VM_GET_BP_OEM_DATA: + + bp_rsp_buf.rsp.rsp_id= get_bp_oem_data_fn(dev_idx, bp_cmd_vm_buf->cmd_vm.cmd_vm_data, + (char *)&bp_rsp_buf.rsp_info.info); + break; + + case CMD_VM_GET_BP_PCI_INFO: + + bp_rsp_buf.rsp.rsp_id= get_bp_pci_info_fn(dev_idx, (char *)&bp_rsp_buf.rsp_info.info); + break; + + case CMD_VM_GET_BP_ALL_INFO: + bp_rsp_buf.rsp.rsp_id= get_bp_all_info_fn(dev_idx, (char *)&bp_rsp_buf.rsp_info.info); + break; + + case CMD_VM_SET_TPL : + bp_rsp_buf.rsp.rsp_id= set_tpl_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_TPL : + bp_rsp_buf.rsp.rsp_data= get_tpl_fn(pbpctl_dev); + break; + case CMD_VM_SET_BP_WAIT_AT_PWUP : + bp_rsp_buf.rsp.rsp_id= set_bp_wait_at_pwup_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_BP_WAIT_AT_PWUP : + bp_rsp_buf.rsp.rsp_data= get_bp_wait_at_pwup_fn(pbpctl_dev); + break; + case CMD_VM_SET_BP_HW_RESET : + bp_rsp_buf.rsp.rsp_id= set_bp_hw_reset_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + break; + + case CMD_VM_GET_BP_HW_RESET : + bp_rsp_buf.rsp.rsp_data= get_bp_hw_reset_fn(pbpctl_dev); + break; +#ifdef BP_SELF_TEST + case CMD_VM_SET_BP_SELF_TEST: + bp_rsp_buf.rsp.rsp_id= set_bp_self_test_fn(pbpctl_dev, bp_cmd_vm_buf->cmd_vm.cmd_vm_data); + + break; + case CMD_VM_GET_BP_SELF_TEST: + bp_rsp_buf.rsp.rsp_data= get_bp_self_test_fn(pbpctl_dev); + break; +#endif + default: + bp_rsp_buf.rsp.rsp_id=-1; + break; + /* return -EOPNOTSUPP;*/ + }; + /* schedule_work(&adapter->bpvm_task); */ + } else goto bpvm_out1; + } else goto bpvm_out1; + bpvm_out: + /* response->rsp.multiplex_id==request->cmd_vm.multiplex_id)&& + (response->rsp.request_id==request->cmd_vm.request_id*/ + + skb_tmp=netdev_alloc_skb(netdev,sizeof(bp_rsp_buf)+2); + if (skb_tmp) { + /* memset(&bp_rsp_buf.rsp.str, 0xff, 6); + memcpy(&bp_rsp_buf.rsp.str1,&str,6); */ + memcpy(&bp_rsp_buf.rsp.str1,&str,6); + + memset(&bp_rsp_buf.rsp.type, 0xba, 2); + memcpy(&bp_rsp_buf.rsp.str,&adapter->bp_cmd_vm_buf.cmd_vm.str1,6); + bp_rsp_buf.rsp.multiplex_id= adapter->bp_cmd_vm_buf.cmd_vm.multiplex_id; + bp_rsp_buf.rsp.request_id= adapter->bp_cmd_vm_buf.cmd_vm.request_id; + /* memset(&bp_rsp_buf.rsp.str, 0xff, 6); + bp_rsp_buf.rsp.rsp_id=-1; */ + if (cmd_vm_id!=CMD_VM_GET_BP_DEV_NUM) + bp_rsp_buf.rsp.rsp_id= bp_rsp_buf.rsp.rsp_id==0?BP_ERR_OK:BP_ERR_NOT_CAP; + memcpy(skb_put(skb_tmp,sizeof(bp_rsp_buf)),&bp_rsp_buf,sizeof(bp_cmd_vm_rsp_t)); + + skb_tmp->protocol=eth_type_trans(skb_tmp,netdev); + skb_tmp->ip_summed=CHECKSUM_UNNECESSARY; + /* netif_rx(skb_tmp); */ + netif_receive_skb(skb_tmp); + } + + /* schedule_work(&adapter->bpvm_task); */ + spin_unlock_irqrestore(&bypass_wr_lock, flags); + return NETDEV_TX_OK; + bpvm_out1: + dev_kfree_skb_any(skb); + spin_unlock_irqrestore(&bypass_wr_lock, flags); + return NETDEV_TX_OK; +} + +int bpvm_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +{ + return (bpvm_xmit_frame_ring(skb, netdev)); +} + + +int bpvm_change_mtu(struct net_device *netdev, int new_mtu) +{ + if ((new_mtu < 68)) { + printk("bpvm: Invalid MTU setting\n"); + return -EINVAL; + } + + netdev->mtu = new_mtu; + return 0; +} + + +static int bpvm_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd_vm) +{ + switch (cmd_vm) { +/*#ifdef ETHTOOL_OPS_COMPAT + case SIOCETHTOOL: + return ethtool_ioctl(ifr); +#endif*/ + default: + return -EOPNOTSUPP; + } +} + +static void bpvm_work_task(struct work_struct *work){ + bp_cmd_vm_t *bp_cmd_vm_buf; + + bp_cmd_vm_rsp_t bp_rsp_buf; + struct bpvm_priv *adapter; + /* int dev_idx; */ + struct sk_buff *skb_tmp; + + + adapter = container_of(work, struct bpvm_priv, bpvm_task); + + bp_cmd_vm_buf=&adapter->bp_cmd_vm_buf; + + + skb_tmp=netdev_alloc_skb(netdev,sizeof(bp_rsp_buf)+2); + if (skb_tmp) { + memset(&bp_rsp_buf, 0xff, sizeof(bp_rsp_buf)); + /* memset(skb_put(skb_tmp,sizeof(bp_rsp_buf)),0xff,sizeof(bp_rsp_buf)); */ + memcpy(skb_put(skb_tmp,sizeof(bp_rsp_buf)),&bp_rsp_buf,sizeof(bp_cmd_vm_rsp_t)); + + skb_tmp->protocol=eth_type_trans(skb_tmp,netdev); + + + skb_tmp->ip_summed=CHECKSUM_UNNECESSARY; + netif_rx(skb_tmp); + } + +} + + +void bpvm_set_rx_mode(struct net_device *netdev) +{ +} + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) ) +static const struct net_device_ops bpvm_netdev_ops = { + .ndo_open = bpvm_open, + .ndo_stop = bpvm_close, + .ndo_start_xmit = bpvm_xmit_frame, + .ndo_change_mtu = bpvm_change_mtu, + .ndo_do_ioctl = bpvm_ioctl, + .ndo_set_rx_mode = bpvm_set_rx_mode, +}; +#endif + + +static u32 bpvm_get_link(struct net_device *netdev){ + return 1; +} + +static int bpvm_get_settings(struct net_device *netdev, + struct ethtool_cmd *ecmd) +{ + ecmd->speed = 100; + ecmd->duplex = 1; + + return 0; +} + +static void bpvm_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) +{ + strncpy(drvinfo->driver, bpvm_driver_name, 32); + strncpy(drvinfo->version, bpvm_driver_version, 32); + strcpy(drvinfo->fw_version, "N/A"); +} + + +static struct ethtool_ops bpvm_ethtool_ops = { + .get_settings = bpvm_get_settings, + .get_drvinfo = bpvm_get_drvinfo, + /* .get_link = ethtool_op_get_link, */ + .get_link = bpvm_get_link, + +}; + + +static inline struct device *pci_dev_to_dev(struct pci_dev *pdev) +{ + return &pdev->dev; +} + +void bpvm_set_ethtool_ops(struct net_device *netdev) +{ + SET_ETHTOOL_OPS(netdev, &bpvm_ethtool_ops); +} + +int bpvm_probe(void) +{ + struct bpvm_priv *adapter; + int err; + char dev_name[16]; + err = -EIO; + + sprintf(dev_name,"bpvm0"); + netdev = alloc_netdev(sizeof(struct bpvm_priv), dev_name, bpvm_setup); + /* netdev = alloc_etherdev(sizeof(struct bpvm_priv)); */ + + if (!netdev) { + return 0; + } + memcpy(netdev->dev_addr, &str[0], 6); + + /* SET_MODULE_OWNER(netdev); */ + SET_NETDEV_DEV(netdev, pci_dev_to_dev(bpctl_dev_arr[0].pdev)); + + adapter = netdev_priv(netdev); + adapter->netdev = netdev; + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) ) + netdev->netdev_ops = &bpvm_netdev_ops; +#else /* HAVE_NET_DEVICE_OPS */ + netdev->open = &bpvm_open; + netdev->stop = &bpvm_close; + netdev->hard_start_xmit = &bpvm_xmit_frame; +#endif + + /* memcpy(&request->cmd.str[0], &str, 6); + memcpy(netdev->dev_addr, &str[0], 6); */ + { + int i; + + printk(KERN_INFO "bpvm addr: "); + for (i = 0; i < 6; i++) + printk("%2.2x%c", + netdev->dev_addr[i], i == 5 ? '\n' : ':'); + } + + /* netdev->get_stats = &bpvm_get_stats; + netdev->set_multicast_list = &bpvm_set_multi; + netdev->set_mac_address = &bpvm_set_mac; */ + netdev->mtu=1500; + /* netdev->do_ioctl = &bpvm_ioctl; */ + + bpvm_set_ethtool_ops(netdev); + + INIT_WORK(&adapter->bpvm_task, bpvm_work_task); + + + /* tell the stack to leave us alone until bpvm_open() is called */ + netif_carrier_off(netdev); + netif_stop_queue(netdev); + +#if !defined(__VMKLNX__) + /* strcpy(netdev->name, "eth%d"); */ +#else /* defined(__VMKLNX__) */ + /* strcpy(netdev->name, " "); */ +#endif /* !defined(__VMKLNX__) */ + + printk(KERN_INFO "bpvm netdev name %s\n", netdev->name); + err = register_netdev(netdev); + if (err) { + return 0; + } + +#ifdef NETIF_F_LLTX + netdev->features |= NETIF_F_LLTX; +#else + +#endif + + /* bpvm_pkt_type.type=cpu_to_be16(ETH_P_ARP); + bpvm_pkt_type.func=bpvm_packet_rcv; + __dev_remove_pack(&bpvm_pkt_type); */ + +#ifdef BPVM_SEP_VER + { + struct net_device *dev_c=NULL; + int idx_dev=0; + rtnl_lock(); + + + /* Find Teton devices */ +#if (LINUX_VERSION_CODE >= 0x020618) + for_each_netdev(&init_net, dev_c) +#elif (LINUX_VERSION_CODE >= 0x20616) + for_each_netdev(dev) +#else + for (dev_c = dev_base; dev_c; dev_c = dev_c->next) +#endif + { + //printk("!!!!bpvm: dev_c->name=%s\n", dev_c->name); + for (idx_dev = 0; ((idx_devpdev) { + printk("bpvm: %s is bypass adapter!\n", dev_c->name); + bpctl_dev_arr[idx_dev].ndev=dev_c; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) + if (dev_c->hard_start_xmit) { + bpctl_dev_arr[idx_dev].hard_start_xmit_save=dev_c->hard_start_xmit; + // printk("bpvm: module_id =%x\n", dev_c->module_id); + dev_c->hard_start_xmit=bpvms_hard_start_xmit; + } +#else + if (pbpctl_dev_sl->ndev->netdev_ops) { + + pbpctl_dev_sl->old_ops = pbpctl_dev_sl->ndev->netdev_ops; + pbpctl_dev_sl->new_ops = *pbpctl_dev_sl->old_ops; + pbpctl_dev_sl->new_ops.ndo_start_xmit = bpvms_hard_start_xmit; + pbpctl_dev_sl->ndev->netdev_ops = &pbpctl_dev_sl->new_ops; + + } +#endif + + } + } + + + } + rtnl_unlock(); + } +#endif /* BPVM_SEP_VER */ + + return 0; + +} + +#endif + + + @@ -4923,23 +8668,13 @@ static long device_ioctl(struct file *file, /* ditto */ bpctl_dev_t *pbpctl_dev_out; void __user *argp = (void __user *)ioctl_param; int ret=0; - unsigned long flags; - - static bpctl_dev_t *pbpctl_dev; + bpctl_dev_t *pbpctl_dev; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) //lock_kernel(); #endif lock_bpctl(); - //local_irq_save(flags); - /*if(!spin_trylock_irqsave(&bpvm_lock)){ - local_irq_restore(flags); - //unlock_bpctl(); - //unlock_kernel(); - return -1; - }*/ - //spin_lock_irqsave(&bpvm_lock, flags); /* * Switch according to the ioctl called @@ -4966,18 +8701,21 @@ static long device_ioctl(struct file *file, /* ditto */ } - //lock_bpctl(); - //preempt_disable(); - local_irq_save(flags); - if (!spin_trylock(&bpvm_lock)) { - local_irq_restore(flags); - unlock_bpctl(); - //unlock_kernel(); - return -1; + if (ioctl_num==IOCTL_TX_MSG(RESET_BYPASS_WD_TIMER)) { + if (bpctl_cmd.in_param[0]==-1) { + int idx_dev=0; + + for (idx_dev = 0; ((idx_devdevice_num) { - //unlock_bpctl(); - //preempt_enable(); ret= -EOPNOTSUPP; - //preempt_enable(); - //rcu_read_unlock(); - spin_unlock_irqrestore(&bpvm_lock,flags); goto bp_exit; } @@ -5007,9 +8740,6 @@ static long device_ioctl(struct file *file, /* ditto */ printk("Please load network driver for %s adapter!\n",bpctl_dev_arr[dev_idx].name); bpctl_cmd.status=-1; ret= SUCCESS; - /*preempt_enable();*/ - //rcu_read_unlock(); - spin_unlock_irqrestore(&bpvm_lock,flags); goto bp_exit; } @@ -5020,9 +8750,6 @@ static long device_ioctl(struct file *file, /* ditto */ bpctl_dev_arr[dev_idx].name); bpctl_cmd.status=-1; ret= SUCCESS; - /*preempt_enable();*/ - //rcu_read_unlock(); - spin_unlock_irqrestore(&bpvm_lock,flags); goto bp_exit; } @@ -5131,6 +8858,10 @@ static long device_ioctl(struct file *file, /* ditto */ bpctl_cmd.status= get_bypass_change_fn(pbpctl_dev); break; + case IOCTL_TX_MSG(GET_WD_EXPIRE): + bpctl_cmd.status= get_wd_expire_fn(pbpctl_dev); + break; + case IOCTL_TX_MSG(GET_BYPASS): bpctl_cmd.status= get_bypass_fn(pbpctl_dev); break; @@ -5141,12 +8872,7 @@ static long device_ioctl(struct file *file, /* ditto */ case IOCTL_TX_MSG(GET_BYPASS_CAPS): bpctl_cmd.status= get_bypass_caps_fn(pbpctl_dev); - /*preempt_enable();*/ - //rcu_read_unlock(); - spin_unlock_irqrestore(&bpvm_lock, flags); if (copy_to_user(argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) { - //unlock_bpctl(); - //preempt_enable(); ret= -EFAULT; goto bp_exit; } @@ -5163,7 +8889,7 @@ static long device_ioctl(struct file *file, /* ditto */ break; case IOCTL_TX_MSG(IS_BYPASS): - bpctl_cmd.status= is_bypass(pbpctl_dev); + bpctl_cmd.status= is_bypass_fn(pbpctl_dev); break; case IOCTL_TX_MSG(SET_TX): bpctl_cmd.status= set_tx_fn(pbpctl_dev, bpctl_cmd.in_param[2]); @@ -5265,33 +8991,24 @@ static long device_ioctl(struct file *file, /* ditto */ bpctl_cmd.status= get_bp_force_link_fn(dev_idx); break; - - + case IOCTL_TX_MSG(SET_BP_MANUF) : + bpctl_cmd.status= set_bp_manuf_fn(pbpctl_dev); + break; + default: - // unlock_bpctl(); ret= -EOPNOTSUPP; - /*preempt_enable();*/ - //rcu_read_unlock(); - spin_unlock_irqrestore(&bpvm_lock,flags); goto bp_exit; } - //unlock_bpctl(); - /*preempt_enable(); */ bpcmd_exit: - //rcu_read_unlock(); - spin_unlock_irqrestore(&bpvm_lock, flags); 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)) - //unlock_kernel(); #endif - //spin_unlock_irqrestore(&bpvm_lock, flags); unlock_bpctl(); - //unlock_kernel(); return ret; } @@ -5315,7 +9032,7 @@ struct file_operations Fops = { #endif -#define SILICOM_E1000BP_ETHERNET_DEVICE(device_id) {\ +#define SILICOM_BPCTLBP_ETHERNET_DEVICE(device_id) {\ PCI_DEVICE(SILICOM_VID, device_id)} @@ -5418,12 +9135,16 @@ typedef enum { M1EG4BPFI6ZX, M1EG6BPI6, M1E2G4BPi80, + M4E2G4BPi80CP, + M4E2G4BPi80CQ, M1E2G4BPFi80, M1E2G4BPFi80LX, M1E2G4BPFi80ZX, PE210G2SPI9, M1E10G2BPI9CX4, - M1E10G2BPI9SR, + M1E10G2BPI9SR, + M4E210G2BPI9SRCP, + M4E210G2BPI9SRCQ, M1E10G2BPI9LR, PE210G2BPI9CX4, PE210G2BPI9SR, @@ -5447,7 +9168,8 @@ typedef enum { PEG2DBFI6, PEG2DBFI6LX, PEG2DBFI6ZX, - PE2G4BPi80, + PE2G4BPi80, + PE2G4BPi80RB1, PE2G4BPFi80, PE2G4BPFi80LX, PE2G4BPFi80ZX, @@ -5472,6 +9194,7 @@ typedef enum { PE2G4BPFi35ZX, PE2G6BPi35, + PE2G6BPi35RB2, PE2G6BPi35CX, @@ -5524,7 +9247,16 @@ typedef enum { PE310G4DBi9T, - + PE310G4BPI71, + PE340G2BPI71, + PE310G4BPI71SRD, + PE310G4BPI71LRD, + PE310G2BPI71SRD, + PE310G2BPI71LRD, + PE340G2BPI71QS4, + PE340G2BPI71QS43, + PE340G2BPI71QL4, + ADI_RANGELEY, } board_t; typedef struct _bpmod_info_t { @@ -5642,6 +9374,8 @@ dev_desc_t dev_desc[]={ {"Silicom Bypass MxEG4BPFI6ZX series adapter"}, {"Silicom Bypass MxEG6BPI6 series adapter"}, {"Silicom Bypass MxE2G4BPi80 series adapter"}, + {"Silicom Bypass M4E2G4BPi80CP series adapter"}, + {"Silicom Bypass M4E2G4BPi80CQ series adapter"}, {"Silicom Bypass MxE2G4BPFi80 series adapter"}, {"Silicom Bypass MxE2G4BPFi80LX series adapter"}, {"Silicom Bypass MxE2G4BPFi80ZX series adapter"}, @@ -5652,6 +9386,8 @@ dev_desc_t dev_desc[]={ {"Silicom Bypass MxE210G2BPI9CX4 series adapter"}, {"Silicom Bypass MxE210G2BPI9SR series adapter"}, + {"Silicom Bypass M4E210G2BPI9SRCP series adapter"}, + {"Silicom Bypass M4E210G2BPI9SRCQ series adapter"}, {"Silicom Bypass MxE210G2BPI9LR series adapter"}, {"Silicom Bypass MxE210G2BPI9T series adapter"}, @@ -5684,7 +9420,8 @@ dev_desc_t dev_desc[]={ {"Silicom Bypass PEG2DBFI6ZX series adapter"}, - {"Silicom Bypass PE2G4BPi80 series adapter"}, + {"Silicom Bypass PE2G4BPi80 series adapter"}, + {"Silicom Bypass PE2G4BPi80RB1 series adapter"}, {"Silicom Bypass PE2G4BPFi80 series adapter"}, {"Silicom Bypass PE2G4BPFi80LX series adapter"}, {"Silicom Bypass PE2G4BPFi80ZX series adapter"}, @@ -5716,6 +9453,7 @@ dev_desc_t dev_desc[]={ {"Silicom Bypass PE2G4BPFi35ZX series adapter"}, {"Silicom Bypass PE2G6BPi35 series adapter"}, + {"Silicom Bypass PE2G6BPi35RB2 series adapter"}, {"Silicom Bypass PE2G6BPi35CX series adapter"}, @@ -5759,6 +9497,16 @@ dev_desc_t dev_desc[]={ {"Silicom Bypass PE310G4DBi9T series adapter"}, + {"Silicom Bypass PE310G4BPI71 series adapter"}, + {"Silicom Bypass PE340G2BPI71 series adapter"}, + {"Silicom Bypass PE310G4BPI71SRD series adapter"}, + {"Silicom Bypass PE310G4BPI71LRD series adapter"}, + {"Silicom Bypass PE310G2BPI71SRD series adapter"}, + {"Silicom Bypass PE310G2BPI71LRD series adapter"}, + {"Silicom Bypass PE340G2BPI71QS4 series adapter"}, + {"Silicom Bypass PE340G2BPI71QL4 series adapter"}, + {"Silicom Bypass ADI_RANGELEY series adapter"}, + {0}, }; @@ -5874,15 +9622,13 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { {0x8086, 0x150e, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M1E2G4BPi80_SSID /*PCI_ANY_ID*/, M1E2G4BPi80, "MxE2G4BPi80"}, + {0x8086, 0x150e, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M4E2G4BPi80CP_SSID /*PCI_ANY_ID*/, M4E2G4BPi80CP, "M4E2G4BPi80CP"}, + {0x8086, 0x150e, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M4E2G4BPi80CQ_SSID /*PCI_ANY_ID*/, M4E2G4BPi80CQ, "M4E2G4BPi80CQ"}, {0x8086, 0x150f, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M1E2G4BPFi80_SSID /*PCI_ANY_ID*/, M1E2G4BPFi80, "MxE2G4BPFi80"}, {0x8086, 0x150f, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M1E2G4BPFi80LX_SSID /*PCI_ANY_ID*/, M1E2G4BPFi80LX, "MxE2G4BPFi80LX"}, {0x8086, 0x150f, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M1E2G4BPFi80ZX_SSID /*PCI_ANY_ID*/, M1E2G4BPFi80ZX, "MxE2G4BPFi80ZX"}, - - - - {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M2EG2BPFI6_SSID /*PCI_ANY_ID*/, M2EG2BPFI6, "M2EG2BPFI6"}, {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M2EG2BPFI6LX_SSID /*PCI_ANY_ID*/, M2EG2BPFI6LX, "M2EG2BPFI6LX"}, {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M2EG2BPFI6ZX_SSID /*PCI_ANY_ID*/, M2EG2BPFI6ZX, "M2EG2BPFI6ZX"}, @@ -5940,6 +9686,7 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { {0x8086, 0x150e, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE2G4BPi80_SSID /*PCI_ANY_ID*/, PE2G4BPi80, "PE2G4BPi80"}, + {0x8086, 0x150e, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE2G4BPi80RB1_SSID /*PCI_ANY_ID*/, PE2G4BPi80RB1, "PE2G4BPi80RB1"}, {0x8086, 0x150f, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE2G4BPFi80_SSID /*PCI_ANY_ID*/, PE2G4BPFi80, "PE2G4BPFi80"}, {0x8086, 0x150f, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE2G4BPFi80LX_SSID /*PCI_ANY_ID*/, PE2G4BPFi80LX, "PE2G4BPFi80LX"}, {0x8086, 0x150f, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE2G4BPFi80ZX_SSID /*PCI_ANY_ID*/, PE2G4BPFi80ZX, "PE2G4BPFi80ZX"}, @@ -5995,6 +9742,7 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { {0x8086, 0x1521, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE2G6BPi35_SSID /*PCI_ANY_ID*/, PE2G6BPi35, "PE2G6BPi35"}, + {0x8086, 0x1521, 0x1B2E /*PCI_ANY_ID*/, SILICOM_PE2G6BPi35_SSID /*PCI_ANY_ID*/, PE2G6BPi35RB2, "PE2G6BPi35RB2"}, // {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa0,PE2G6BPi35CX,"PE2G6BPi35CX"}, // {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa1,PE2G6BPi35CX,"PE2G6BPi35CX"}, @@ -6109,9 +9857,7 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE2G2BPFi80ZX_SSID /*PCI_ANY_ID*/, PE2G2BPFi80ZX, "PE2G2BPFi80ZX"}, {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_MEG2BPI6_SSID /*PCI_ANY_ID*/, MEG2BPI6, "MEG2BPI6"}, - {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID*/, XEG2BPI6, "XEG2BPI6"}, - - + {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID*/, XEG2BPI6, "XEG2BPI6"}, #if 0 {0x8086, 0x10fb, 0x8086, INTEL_PE210G2SPI9_SSID, PE210G2SPI9, "PE210G2SPI9"}, @@ -6120,10 +9866,13 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M1E10G2BPI9SR_SSID /*PCI_ANY_ID*/, M1E10G2BPI9SR, "MxE210G2BPI9SR"}, {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M1E10G2BPI9LR_SSID /*PCI_ANY_ID*/, M1E10G2BPI9LR, "MxE210G2BPI9LR"}, + {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M4E210G2BPI9SRCP_SSID /*PCI_ANY_ID*/, M4E210G2BPI9SRCP, "M4E210G2BPI9SRCP"}, + {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M4E210G2BPI9SRCQ_SSID /*PCI_ANY_ID*/, M4E210G2BPI9SRCQ, "M4E210G2BPI9SRCQ"}, + {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M2E10G2BPI9CX4_SSID /*PCI_ANY_ID*/, M2E10G2BPI9CX4, "M2E10G2BPI9CX4"}, {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M2E10G2BPI9SR_SSID /*PCI_ANY_ID*/, M2E10G2BPI9SR, "M2E10G2BPI9SR"}, {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M2E10G2BPI9LR_SSID /*PCI_ANY_ID*/, M2E10G2BPI9LR, "M2E10G2BPI9LR"}, - {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M2E10G2BPI9T_SSID /*PCI_ANY_ID*/, M2E10G2BPI9T, "M2E10G2BPI9T"}, + // {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M2E10G2BPI9T_SSID /*PCI_ANY_ID*/, M2E10G2BPI9T, "M2E10G2BPI9T"}, @@ -6139,10 +9888,6 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { {0x8086, 0x10fb, 0x1304, SILICOM_M1E210G2BPI9SRDJP1_SSID, M1E210G2BPI9SRDJP1, "M1E210G2BPI9SRDJP1"}, {0x8086, 0x10fb, 0x1304, SILICOM_M1E210G2BPI9LRDJP_SSID, M1E210G2BPI9LRDJP, "M1E210G2BPI9LRDJP"}, {0x8086, 0x10fb, 0x1304, SILICOM_M1E210G2BPI9LRDJP1_SSID, M1E210G2BPI9LRDJP1, "M1E210G2BPI9LRDJP1"}, - - - - #if 0 {0x1374, 0x2c, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI, "PXG4BPI-SD"}, @@ -6169,6 +9914,22 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { {0x8086, 0x1528, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_M1E210G2BPI40T_SSID /*PCI_ANY_ID*/, M1E210G2BPI40T, "M1E210G2BPi40T"}, + {0x8086, 0x1572, SILICOM_SVID, SILICOM_PE310G4BPI71SRD_SSID, PE310G4BPI71SRD, "PE310G4BPI71SRD"}, + {0x8086, 0x1572, SILICOM_SVID, SILICOM_PE310G4BPI71LRD_SSID, PE310G4BPI71LRD, "PE310G4BPI71LRD"}, + + {0x8086, 0x1572, SILICOM_SVID, SILICOM_PE310G2BPI71SRD_SSID, PE310G2BPI71SRD, "PE310G2BPI71SRD"}, + {0x8086, 0x1572, SILICOM_SVID, SILICOM_PE310G2BPI71LRD_SSID, PE310G2BPI71LRD, "PE310G2BPI71LRD"}, + + {0x8086, 0x1572, SILICOM_SVID, 0x0, PE310G4BPI71, "PE310G4BPI71"}, + + {0x8086, 0x1583, SILICOM_SVID, SILICOM_PE340G2BPI71QS4_SSID, PE340G2BPI71QS4, "PE340G2BPI71QS4"}, + {0x8086, 0x1583, SILICOM_SVID, SILICOM_PE340G2BPI71QS43_SSID, PE340G2BPI71QS43, "PE340G2BPI71QS43"}, + {0x8086, 0x1583, SILICOM_SVID, SILICOM_PE340G2BPI71QL4_SSID, PE340G2BPI71QL4, "PE340G2BPI71QL4"}, + + {0x8086, 0x1583, SILICOM_SVID, 0x0, PE340G2BPI71, "PE340G2BPI71"}, + + {0x8086, 0x1f41, 0x8086, 0x1f41, ADI_RANGELEY, "ADI_RANGELEY"}, + /* required last entry */ {0,} @@ -6179,13 +9940,15 @@ static bpmod_info_t tx_ctl_pci_tbl[] = { * Initialize the module - Register the character device */ -static int __init bypass_init_module(void) +static int v2_bypass_init_module(void) { int ret_val, idx, idx_dev=0; struct pci_dev *pdev1=NULL; unsigned long mmio_start, mmio_len; - printk(BP_MOD_DESCR" v"BP_MOD_VER"\n"); +#ifdef BPVM_KVM + printk("bpvm supported\n"); +#endif ret_val = register_chrdev (major_num, DEVICE_NAME, &Fops); if (ret_val < 0) { printk("%s failed with %d\n",DEVICE_NAME,ret_val); @@ -6198,8 +9961,11 @@ static int __init bypass_init_module(void) tx_ctl_pci_tbl[idx].subvendor, tx_ctl_pci_tbl[idx].subdevice, pdev1))) { - - device_num++; + if (BPRANG_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice)) { + if(!client) + continue; + } + device_num++; } } if (!device_num) { @@ -6226,13 +9992,15 @@ static int __init bypass_init_module(void) tx_ctl_pci_tbl[idx].subdevice, pdev1))) { - - + if (BPRANG_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice)) { + if(!client) + continue; + } mmio_start = pci_resource_start (pdev1, 0); mmio_len = pci_resource_len (pdev1, 0); if((!mmio_len)||(!mmio_start)) - continue; - bpctl_dev_arr[idx_dev].pdev=pdev1; + continue; + bpctl_dev_arr[idx_dev].pdev=pdev1; bpctl_dev_arr[idx_dev].desc=dev_desc[tx_ctl_pci_tbl[idx].index].name; bpctl_dev_arr[idx_dev].name=tx_ctl_pci_tbl[idx].bp_name; @@ -6245,10 +10013,12 @@ static int __init bypass_init_module(void) bpctl_dev_arr[idx_dev].slot= PCI_SLOT(pdev1->devfn); bpctl_dev_arr[idx_dev].bus=pdev1->bus->number; bpctl_dev_arr[idx_dev].mem_map=(unsigned long)ioremap(mmio_start,mmio_len); -#ifdef BP_SYNC_FLAG - spin_lock_init(&bpctl_dev_arr[idx_dev].bypass_wr_lock); -#endif + spin_lock_init(&bpctl_dev_arr[idx_dev].bypass_wr_lock); + + if (BPRANG_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice)) + bpctl_dev_arr[idx_dev].bp_rang=1; + if (BP10G9_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) bpctl_dev_arr[idx_dev].bp_10g9=1; if (BP10G_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) @@ -6269,6 +10039,73 @@ static int __init bypass_init_module(void) bpctl_dev_arr[idx_dev].bp_fiber5=1; if ((bpctl_dev_arr[idx_dev].subdevice&0xfe0)==0xaa0) bpctl_dev_arr[idx_dev].bp_i80=1; + if (BP40_IF_SERIES(pdev1->subsystem_device)) { + bpctl_dev_arr[idx_dev].bp_40g=1; + } + + if (bpctl_dev_arr[idx_dev].bp_10g9) { + unsigned int ctrl= 0; + + + ctrl = BP10G_READ_REG(&bpctl_dev_arr[idx_dev], DCA_ID); + + bpctl_dev_arr[idx_dev].func_p = ctrl & 0x7; + bpctl_dev_arr[idx_dev].slot_p = (ctrl >> 3) & 0x1f; + bpctl_dev_arr[idx_dev].bus_p = (ctrl >> 8) & 0xff; + + } else if (bpctl_dev_arr[idx_dev].bp_i80) { + + unsigned int ctrl= 0; + + ctrl = BPCTL_READ_REG(&bpctl_dev_arr[idx_dev], DCA_ID); + + bpctl_dev_arr[idx_dev].func_p = ctrl & 0x7; + bpctl_dev_arr[idx_dev].slot_p = (ctrl >> 3) & 0x1f; + bpctl_dev_arr[idx_dev].bus_p = (ctrl >> 8) & 0xff; + + } + + else if (bpctl_dev_arr[idx_dev].bp_40g) { + unsigned int ctrl= 0; + + + ctrl = BP40G_RD_REG(&bpctl_dev_arr[idx_dev], PF_FUNC_RID); + + bpctl_dev_arr[idx_dev].func_p = ctrl & 0x7; + bpctl_dev_arr[idx_dev].slot_p = (ctrl >> 3) & 0x1f; + bpctl_dev_arr[idx_dev].bus_p = (ctrl >> 8) & 0xff; + + + } else { + bpctl_dev_arr[idx_dev].func_p = bpctl_dev_arr[idx_dev].func; + bpctl_dev_arr[idx_dev].slot_p = bpctl_dev_arr[idx_dev].slot; + bpctl_dev_arr[idx_dev].bus_p = bpctl_dev_arr[idx_dev].bus; + + } +#ifdef BPVM_KVM + if ((PEGF5_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))|| + (PEG5_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))|| + (BP71_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))|| + (bpctl_dev_arr[idx_dev].bp_i80==1)) { + int k=0; + u8 data_cmp[]={0xf3, 0xb4, 0x26, 0x4b, 0x90, 0x25, 0x98, 0x9f, 0x12, 0x7f, 0x8e, 0x82, 0x99, 0x83, 0x23, 0x30, 0xef, 0xe0, 0x68, 0x8a}; + u16 offset= (BP71_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))?0x400:0x1000; + + bpvm_read_nvm_eerd(&bpctl_dev_arr[idx_dev], offset, 10, (u16 *)&bpctl_dev_arr[idx_dev].oem_data); + + if (!memcmp(&bpctl_dev_arr[idx_dev].oem_data, &data_cmp, 20)) + bpctl_dev_arr[idx_dev].rb_oem=1; + + printk("bpvm oem data reading: "); + for (k=0;k<20;k++) { + printk("%x ", bpctl_dev_arr[idx_dev].oem_data[k]); + } + printk("\n"); + } + + + bpvm_id_led_init(&bpctl_dev_arr[idx_dev]); + #endif /* BPVM_KVM */ if (BP10GB_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) { if (bpctl_dev_arr[idx_dev].ifindex==0) { @@ -6291,48 +10128,6 @@ static int __init bypass_init_module(void) bpctl_dev_arr[idx_dev].bp_10gb=1; } - if (!bpctl_dev_arr[idx_dev].bp_10g9) { - - if (is_bypass_fn(&bpctl_dev_arr[idx_dev])) { - printk(KERN_INFO "%s found, ", bpctl_dev_arr[idx_dev].name); - if ((OLD_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))|| - (INTEL_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))) - bpctl_dev_arr[idx_dev].bp_fw_ver=0xff; - else - bpctl_dev_arr[idx_dev].bp_fw_ver=bypass_fw_ver(&bpctl_dev_arr[idx_dev]); - if ((bpctl_dev_arr[idx_dev].bp_10gb==1)&& - (bpctl_dev_arr[idx_dev].bp_fw_ver==0xff)) { - int cnt=100; - while (cnt--) { - iounmap ((void *)(bpctl_dev_arr[idx_dev].mem_map)); - mmio_start = pci_resource_start (pdev1, 0); - mmio_len = pci_resource_len (pdev1, 0); - - bpctl_dev_arr[idx_dev].mem_map=(unsigned long)ioremap(mmio_start,mmio_len); - - bpctl_dev_arr[idx_dev].bp_fw_ver=bypass_fw_ver(&bpctl_dev_arr[idx_dev]); - if (bpctl_dev_arr[idx_dev].bp_fw_ver==0xa8) - break; - - } - } - //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; - - - - bypass_caps_init(&bpctl_dev_arr[idx_dev]); - - init_bypass_wd_auto(&bpctl_dev_arr[idx_dev]); - init_bypass_tpl_auto(&bpctl_dev_arr[idx_dev]); - if (NOKIA_SERIES(bpctl_dev_arr[idx_dev].subdevice)) - reset_cont(&bpctl_dev_arr[idx_dev]) ; - } #ifdef BP_SELF_TEST if ((bpctl_dev_arr[idx_dev].bp_tx_data=kmalloc(BPTEST_DATA_LEN, GFP_KERNEL))) { @@ -6362,34 +10157,97 @@ static int __init bypass_init_module(void) if_scan_init(); sema_init (&bpctl_sema, 1); - spin_lock_init(&bpvm_lock); +#ifdef BPVM_KVM + spin_lock_init(&bypass_wr_lock); +#endif + { - bpctl_dev_t *pbpctl_dev_c=NULL ; - for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev!=NULL)&&(idx_dev> 3) & 0x1f; + bpctl_dev_arr[idx_dev].bus_p = (ctrl >> 8) & 0xff; } - 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; - bypass_caps_init(&bpctl_dev_arr[idx_dev]); - init_bypass_wd_auto(&bpctl_dev_arr[idx_dev]); - init_bypass_tpl_auto(&bpctl_dev_arr[idx_dev]); + + pbpctl_dev_c = get_status40_port_fn(&bpctl_dev_arr[idx_dev]); + + if ((bpctl_dev_arr[idx_dev].func_p!=0)&&(pbpctl_dev_c)) { + + if(pbpctl_dev_c->bp_40g) { + bpctl_dev_arr[idx_dev].bp_40g=1; + bpctl_dev_arr[idx_dev].desc=pbpctl_dev_c->desc; + bpctl_dev_arr[idx_dev].name=pbpctl_dev_c->name; + } + } + } + + + + if (is_bypass_fn(&bpctl_dev_arr[idx_dev])) { + printk(KERN_INFO "%s found, ", bpctl_dev_arr[idx_dev].name); + if (bpctl_dev_arr[idx_dev].bp_rang==1) { + bpctl_dev_arr[idx_dev].bp_fw_ver=bypass_fw_ver(&bpctl_dev_arr[idx_dev]); + // printk("firmware version: 0x%x\n",bpctl_dev_arr[idx_dev].bp_fw_ver); + //return 0; + } + else if (bpctl_dev_arr[idx_dev].bp_40g==1) + bpctl_dev_arr[idx_dev].bp_fw_ver=bypass_fw_ver(&bpctl_dev_arr[idx_dev]); + else if ((OLD_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))|| + (INTEL_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))) + bpctl_dev_arr[idx_dev].bp_fw_ver=0xff; + else + bpctl_dev_arr[idx_dev].bp_fw_ver=bypass_fw_ver(&bpctl_dev_arr[idx_dev]); + if ((bpctl_dev_arr[idx_dev].bp_10gb==1)&& + (bpctl_dev_arr[idx_dev].bp_fw_ver==0xff)) { + int cnt=100; + while (cnt--) { + iounmap ((void *)(bpctl_dev_arr[idx_dev].mem_map)); + mmio_start = pci_resource_start (pdev1, 0); + mmio_len = pci_resource_len (pdev1, 0); + + bpctl_dev_arr[idx_dev].mem_map=(unsigned long)ioremap(mmio_start,mmio_len); + + bpctl_dev_arr[idx_dev].bp_fw_ver=bypass_fw_ver(&bpctl_dev_arr[idx_dev]); + if (bpctl_dev_arr[idx_dev].bp_fw_ver==0xa8) + break; + + } + } + //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; + + + bypass_caps_init(&bpctl_dev_arr[idx_dev]); + get_tpl_fn(&bpctl_dev_arr[idx_dev]); + init_bypass_wd_auto(&bpctl_dev_arr[idx_dev]); + init_bypass_tpl_auto(&bpctl_dev_arr[idx_dev]); + if (NOKIA_SERIES(bpctl_dev_arr[idx_dev].subdevice)) + reset_cont(&bpctl_dev_arr[idx_dev]) ; } - } +} @@ -6446,26 +10304,21 @@ static int __init bypass_init_module(void) #endif register_netdevice_notifier(&bp_notifier_block); + register_reboot_notifier(&bp_reboot_block); #ifdef BP_PROC_SUPPORT { int i=0; - //unsigned long flags; - //rcu_read_lock(); bp_proc_create(); for (i = 0; i < device_num; i++) { if (bpctl_dev_arr[i].ifindex) { - //spin_lock_irqsave(&bpvm_lock, flags); bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]); bypass_proc_create_dev_sd(&bpctl_dev_arr[i]); - //spin_unlock_irqrestore(&bpvm_lock, flags); } } - //rcu_read_unlock(); } #endif - //register_netdevice_notifier(&bp_notifier_block); return 0; } /* @@ -6478,6 +10331,7 @@ static void __exit bypass_cleanup_module(void) 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_sd"); @@ -6529,17 +10383,22 @@ static void __exit bypass_cleanup_module(void) for (i = 0; i < device_num; i++) { //unsigned long flags; #ifdef BP_PROC_SUPPORT -//spin_lock_irqsave(&bpvm_lock, flags); -//rcu_read_lock(); bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]); -//spin_unlock_irqrestore(&bpvm_lock, flags); -//rcu_read_unlock(); #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 + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ) + remove_proc_entry(BP_PROC_DIR, proc_net); +#else + remove_proc_entry(BP_PROC_DIR, init_net.proc_net); +#endif + +#endif /* unmap all devices */ @@ -6552,9 +10411,9 @@ static void __exit bypass_cleanup_module(void) } /* free all devices space */ - if (bpctl_dev_arr) - kfree (bpctl_dev_arr); - + if (bpctl_dev_arr) { + kfree (bpctl_dev_arr); + } /* @@ -6565,20 +10424,150 @@ static void __exit bypass_cleanup_module(void) /* * If there's an error, report it */ - if (ret < 0) - printk("Error in module_unregister_chrdev: %d\n", ret); + if (ret < 0) { + printk("Error in module_unregister_chrdev: %d\n", ret); + } #else unregister_chrdev(major_num, DEVICE_NAME); #endif } + +#ifdef ADI_RANGELEY_SUPPORT + +static int sib_i2c_scan(struct device *dev, void *dummy) +{ + struct i2c_adapter *adap; + int status = 0; + struct i2c_client *tmp_client = NULL; + + if (dev->type != &i2c_adapter_type) { + return 0; + } + + adap = to_i2c_adapter(dev); + tmp_client = kzalloc(sizeof(*client), GFP_KERNEL); + + if (!tmp_client) { + return -ENOMEM; + } + snprintf(tmp_client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr); + tmp_client->adapter = adap; + tmp_client->addr = 0x57; + status = i2c_smbus_read_byte(tmp_client); + if(status > 0) { + client = tmp_client; + } else { + kfree(tmp_client); + } + return 0; +} + +static void init_i2c_scan(void) +{ + i2c_for_each_dev(NULL, sib_i2c_scan); +} + +#endif /* ADI_RANGELEY_SUPPORT */ + +static int __init bypass_init_module(void) +{ + int ret; + + printk(KERN_INFO BP_MOD_DESCR" v"BP_MOD_VER"\n"); + +#ifdef ADI_RANGELEY_SUPPORT + + init_i2c_scan(); + + if(client) { + struct pci_dev *pdev1 = NULL; + unsigned int mmio_start = 0; + int ret_val = 0; + + while ((pdev1 = pci_get_device(0x8086, + PCI_ANY_ID, + pdev1))) { + if ((pdev1->bus->number == 0)&&(PCI_SLOT(pdev1->devfn) == 31)&&(PCI_FUNC(pdev1->devfn) == 0)) { + na_device_num++; + break; + } + } + + if (na_device_num != 1) + goto v2_init; + + pdev1 = pci_get_device(0x8086, 0x1f38, NULL); + if(!pdev1) + goto v2_init; + + ret_val = pci_read_config_dword(pdev1, 0x48, &(mmio_start)); + if(!mmio_start) { + goto v2_init; + } + // pci_dev_put(pdev1); + mmio_start&= 0x0000ff80; + + na_base = mmio_start; + + + /* obtain exclusive access to GPIO memory space */ + // printk("!!!mmio_start=%x, ret_val=%d\n", mmio_start,ret_val); + +#if 0 +#define BPNAG_WRITE_REG(a, reg, value) ({ \ + outl((unsigned long)value,(((a)->na_base)+reg));}) + + +#define BPNAG_READ_REG(a, reg, value) ({ \ + value=inl(((a)->na_base)+reg);}) + + printk("bpmod SC_USE_SEL = 0x%x\n", inl(na_base + 0)); + printk("bpmod SC_IO_SEL = 0x%x\n", inl(na_base + 0x4)); + printk("bpmod SC_GP_LVL = 0x%x\n", inl(na_base + 0x8)); + + printk("bpmod SUS_USE_SEL = 0x%x\n", inl(na_base + 0x80)); + outl((unsigned long)(BIT_17 | BIT_18),(na_base + 0x84)); + printk("bpmod SUS_IO_SEL = 0x%x\n", inl(na_base + 0x84)); + printk("bpmod SUS_GP_LVL = 0x%x\n", inl(na_base + 0x88)); +#endif + + } + +v2_init: +#endif /* ADI_RANGELEY_SUPPORT */ + ret=v2_bypass_init_module(); +#ifdef BPVM_KVM + if (!ret) { + ret=bpvm_probe(); + } +#endif + return ret; +} + + +static void __exit bypass_exit_module(void) +{ +/* pci_unregister_driver(&bpvm_driver); */ + bypass_cleanup_module(); +#ifdef BPVM_KVM + unregister_netdev(netdev); + free_netdev(netdev); +#endif /* BPVM_KVM */ +#ifdef ADI_RANGELEY_SUPPORT + if(client) { + kfree(client); + } +#endif /* ADI_RANGELEY_SUPPORT */ +} + +module_exit(bypass_exit_module); module_init(bypass_init_module); -module_exit(bypass_cleanup_module); int is_bypass_sd(int ifindex){ - return(is_bypass(get_dev_idx_p(ifindex))); + return(is_bypass_fn(get_dev_idx_p(ifindex))); } int set_bypass_sd (int ifindex, int bypass_mode){ @@ -6592,6 +10581,12 @@ int get_bypass_sd (int ifindex){ return(get_bypass_fn(get_dev_idx_p(ifindex))); } +int get_wd_expire_sd (int ifindex){ + + return(get_wd_expire_fn(get_dev_idx_p(ifindex))); +} + + int get_bypass_change_sd(int ifindex){ return(get_bypass_change_fn(get_dev_idx_p(ifindex))); @@ -6629,7 +10624,7 @@ int get_bypass_pwup_sd(int ifindex){ } int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set){ - if ((is_bypass(get_dev_idx_p(if_index)))<=0) + if ((is_bypass_fn(get_dev_idx_p(if_index)))<=0) return BP_NOT_CAP; *ms_timeout_set= set_bypass_wd_fn(get_dev_idx_p(if_index),ms_timeout); return 0; @@ -6859,60 +10854,8 @@ EXPORT_SYMBOL_NOVERS(set_bp_disc_pwup_sd); EXPORT_SYMBOL_NOVERS(get_bp_disc_pwup_sd); EXPORT_SYMBOL_NOVERS(get_bypass_info_sd); EXPORT_SYMBOL_NOVERS(bp_if_scan_sd); + #ifdef BP_PROC_SUPPORT - #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" - - - - - static struct proc_dir_entry *bp_procfs_dir; @@ -7328,6 +11271,8 @@ set_bypass_wd_pfs(struct file *file, const char *buffer, unsigned int timeout=0; char *timeout_ptr=kbuf; + if (count>(sizeof(kbuf)-1)) + return -1; if (copy_from_user(&kbuf,buffer,count)) { return -1; @@ -7493,6 +11438,9 @@ set_dis_bypass_pfs(struct file *file, const char *buffer, int bypass_param=0, length=0; + if (count>(sizeof(kbuf)-1)) + return -1; + if (copy_from_user(&kbuf,buffer,count)) { return -1; } @@ -7525,6 +11473,9 @@ set_dis_tap_pfs(struct file *file, const char *buffer, int tap_param=0, length=0; + if (count>(sizeof(kbuf)-1)) + return -1; + if (copy_from_user(&kbuf,buffer,count)) { return -1; } @@ -7557,6 +11508,9 @@ set_dis_disc_pfs(struct file *file, const char *buffer, int tap_param=0, length=0; + if (count>(sizeof(kbuf)-1)) + return -1; + if (copy_from_user(&kbuf,buffer,count)) { return -1; } @@ -7651,6 +11605,9 @@ set_bypass_pwup_pfs(struct file *file, const char *buffer, int bypass_param=0, length=0; + if (count>(sizeof(kbuf)-1)) + return -1; + if (copy_from_user(&kbuf,buffer,count)) { return -1; } @@ -7681,6 +11638,9 @@ set_bypass_pwoff_pfs(struct file *file, const char *buffer, int bypass_param=0, length=0; + if (count>(sizeof(kbuf)-1)) + return -1; + if (copy_from_user(&kbuf,buffer,count)) { return -1; } @@ -7713,6 +11673,9 @@ set_tap_pwup_pfs(struct file *file, const char *buffer, int tap_param=0, length=0; + if (count>(sizeof(kbuf)-1)) + return -1; + if (copy_from_user(&kbuf,buffer,count)) { return -1; } @@ -7744,6 +11707,9 @@ set_disc_pwup_pfs(struct file *file, const char *buffer, int tap_param=0, length=0; + if (count>(sizeof(kbuf)-1)) + return -1; + if (copy_from_user(&kbuf,buffer,count)) { return -1; } @@ -7860,6 +11826,9 @@ set_std_nic_pfs(struct file *file, const char *buffer, int bypass_param=0, length=0; + if (count>(sizeof(kbuf)-1)) + return -1; + if (copy_from_user(&kbuf,buffer,count)) { return -1; } @@ -7991,6 +11960,8 @@ set_wd_autoreset_pfs(struct file *file, const char *buffer, u32 timeout=0; char *timeout_ptr=kbuf; + if (count>(sizeof(kbuf)-1)) + return -1; if (copy_from_user(&kbuf,buffer,count)) { return -1; @@ -8167,13 +12138,15 @@ 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_fn(dev); - if (!slave) - slave = dev; - if (!slave) - seq_printf(m, "fail\n"); - else if (slave->ndev) + bpctl_dev_t *slave; + int ret = get_bypass_slave_fn(dev, &slave); + + if ((ret==1) && (slave) && (slave->ndev)) { seq_printf(m, "%s\n", slave->ndev->name); + } else { + seq_printf(m, "fail\n"); + } + return 0; } RO_FOPS(bypass_slave) diff --git a/bp_mod.h b/bp_mod.h index a5cb03f..815d419 100755 --- a/bp_mod.h +++ b/bp_mod.h @@ -54,6 +54,56 @@ POSSIBILITY OF SUCH DAMAGE. #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" + + @@ -265,6 +315,7 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #define SILICOM_PE2G4BPFi80ZX_SSID 0x0383 #define SILICOM_PE2G4BPi80_SSID 0x0388 +#define SILICOM_PE2G4BPi80RB1_SSID 0x0389 #define SILICOM_PE2G2BPi80_SSID 0x0390 #define SILICOM_PE2G2BPFi80_SSID 0x0391 @@ -322,6 +373,8 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #define SILICOM_M1EG6BPI6_SSID 0x0440 #define SILICOM_M1E2G4BPi80_SSID 0x0460 +#define SILICOM_M4E2G4BPi80CP_SSID 0x0464 +#define SILICOM_M4E2G4BPi80CQ_SSID 0x0465 #define SILICOM_M1E2G4BPFi80_SSID 0x0461 #define SILICOM_M1E2G4BPFi80LX_SSID 0x0462 #define SILICOM_M1E2G4BPFi80ZX_SSID 0x0463 @@ -445,23 +498,23 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #define BP10GB_CX4_SERIES(pid) \ (pid==SILICOM_PE10G2BPTCX4_SSID) - - - +#define BPRANG_IF_SERIES(pid) \ + (pid==0X1f41) -#define SILICOM_M2EG2BPFI6_SSID 0x0501 -#define SILICOM_M2EG2BPFI6LX_SSID 0x0502 -#define SILICOM_M2EG2BPFI6ZX_SSID 0x0503 -#define SILICOM_M2EG4BPI6_SSID 0x0520 -#define SILICOM_M2EG4BPFI6_SSID 0x0521 -#define SILICOM_M2EG4BPFI6LX_SSID 0x0522 -#define SILICOM_M2EG4BPFI6ZX_SSID 0x0523 +#define SILICOM_M2EG2BPFI6_SSID 0x0401 +#define SILICOM_M2EG2BPFI6LX_SSID 0x0402 +#define SILICOM_M2EG2BPFI6ZX_SSID 0x0403 +#define SILICOM_M2EG4BPI6_SSID 0x0420 -#define SILICOM_M2EG6BPI6_SSID 0x0540 +#define SILICOM_M2EG4BPFI6_SSID 0x0421 +#define SILICOM_M2EG4BPFI6LX_SSID 0x0422 +#define SILICOM_M2EG4BPFI6ZX_SSID 0x0423 + +#define SILICOM_M2EG6BPI6_SSID 0x0440 @@ -472,10 +525,13 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #define SILICOM_M1E10G2BPI9LR_SSID 0x483 //#define SILICOM_M1E10G2BPI9T_SSID 0x480 -#define SILICOM_M2E10G2BPI9CX4_SSID 0x581 -#define SILICOM_M2E10G2BPI9SR_SSID 0x582 -#define SILICOM_M2E10G2BPI9LR_SSID 0x583 -#define SILICOM_M2E10G2BPI9T_SSID 0x580 +#define SILICOM_M4E210G2BPI9SRCP_SSID 0x486 +#define SILICOM_M4E210G2BPI9SRCQ_SSID 0x487 + +#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 @@ -489,9 +545,27 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #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_PE310G2BPI71SRD_SSID 0x050A +#define SILICOM_PE310G2BPI71LRD_SSID 0x050B + +#define SILICOM_PE340G2BPI71QS43_SSID 0x0511 + +#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_PE310G2BPI71SRD_SSID)|| \ +(pid== SILICOM_PE310G2BPI71LRD_SSID)|| \ +(pid==SILICOM_PE340G2BPI71QS4_SSID)|| \ +(pid==SILICOM_PE340G2BPI71QS43_SSID)|| \ +(pid==SILICOM_PE340G2BPI71QL4_SSID)) #define DBI_IF_SERIES(pid) \ @@ -550,11 +624,21 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (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_M4E2G4BPi80CP_SSID)|| \ +(pid==SILICOM_M4E2G4BPi80CQ_SSID)|| \ (pid==SILICOM_M6E2G8BPi80_SSID)|| \ (pid==SILICOM_PE2G4BPi80L_SSID)|| \ (pid==SILICOM_M6E2G8BPi80A_SSID)|| \ @@ -568,6 +652,7 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (pid==SILICOM_PE2G6BPi35_SSID)|| \ (pid==SILICOM_PE2G2BPi80_SSID)|| \ (pid==SILICOM_PE2G4BPi80_SSID)|| \ +(pid==SILICOM_PE2G4BPi80RB1_SSID)|| \ (pid==SILICOM_PE2G4BPFi80_SSID)|| \ (pid==SILICOM_PE2G4BPFi80LX_SSID)|| \ (pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \ @@ -614,11 +699,12 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) ((pid==INTEL_PE210G2SPI9_SSID)|| \ (pid==SILICOM_M1E10G2BPI9CX4_SSID)|| \ (pid==SILICOM_M1E10G2BPI9SR_SSID)|| \ +(pid==SILICOM_M4E210G2BPI9SRCP_SSID)|| \ +(pid==SILICOM_M4E210G2BPI9SRCQ_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)|| \ @@ -645,6 +731,21 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) (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)) @@ -655,21 +756,31 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) /* Intel Registers */ #define BPCTLI_CTRL 0x00000 +#define BPCTLI_LEDCTL 0x00E00 #define BPCTLI_CTRL_SWDPIO0 0x00400000 #define BPCTLI_CTRL_SWDPIN0 0x00040000 +#define BPCTLI_TSS 0x3C + +#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_SDP1_DATA 0x00080000 + #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 @@ -683,6 +794,14 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #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 @@ -768,6 +887,7 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #define BP10G_ESDP 0x20 +#define BP10G_DCA_ID 0x11070 #define BP10G_SDP0_DIR 0x100 #define BP10G_SDP1_DIR 0x200 @@ -815,6 +935,29 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #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 @@ -879,12 +1022,65 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #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 BP40G_PF_FUNC_RID 0x0009C000 + +#define TIME_CLK 10 //40 //20 //10 +#define TIME_DET //10 // 5 #define BP10GB_WRITE_REG(a, reg, value) \ @@ -893,6 +1089,25 @@ static inline unsigned int jiffies_to_msecs(const unsigned long j) #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 index f17d512..90780bb 100755 --- a/bp_msg.h +++ b/bp_msg.h @@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE. #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" @@ -62,11 +63,12 @@ POSSIBILITY OF SUCH DAMAGE. #define BYPASS_DISABLE "off" #define TAP_MODE "tap" #define BYPASS_MODE "bypass" -#define DISC_MODE "disc" +#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" diff --git a/bp_util.c b/bp_util.c index c79711f..ecccc67 100755 --- a/bp_util.c +++ b/bp_util.c @@ -98,6 +98,7 @@ static void bp_usage(void){ 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"); @@ -177,17 +178,43 @@ static void bp_usage(void){ 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 (struct bpctl_cmd *bpctl_cmd){ + + +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 ((bpctl_cmd->out_param[2]==1)||(bpctl_cmd->out_param[2]==3)) { + + 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; @@ -229,7 +256,7 @@ void set_dis_bypass_cmd(int file_desc,int if_index,int bp_mode, int bus, int slo } } -void set_dis_bypass_all_cmd(int file_desc,int dev_num, int bp_mode){ +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)); @@ -243,7 +270,7 @@ void set_dis_bypass_all_cmd(int file_desc,int dev_num, int bp_mode){ ret_val = ioctl(file_desc, IOCTL_TX_MSG(SET_DIS_BYPASS), &bpctl_cmd); if (ret_val==0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status==0) printf("ok\n"); @@ -309,7 +336,7 @@ void set_bypass_all_cmd(int file_desc,int dev_num,int tx_state){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(SET_BYPASS), &bpctl_cmd); if (ret_val==0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status==0) printf("ok\n"); @@ -354,15 +381,11 @@ void set_tx_all_cmd(int file_desc,int dev_num, int tx_state){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(SET_TX), &bpctl_cmd); if (ret_val==0) { - ret_info=if_infox_msg(&bpctl_cmd); if (bpctl_cmd.status==0) printf("ok\n"); - else { - if (ret_info==0) - printf("slave\n"); - else printf("fail\n"); - } + else + printf("fail\n"); } } } @@ -1090,7 +1113,7 @@ void get_dis_bypass_all_cmd(int file_desc,int dev_num){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(GET_DIS_BYPASS), &bpctl_cmd); if (ret_val == 0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status==0) { @@ -1142,7 +1165,7 @@ void get_bypass_change_all_cmd(int file_desc,int dev_num){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(GET_BYPASS_CHANGE), &bpctl_cmd); if (ret_val == 0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status==0) @@ -1198,7 +1221,7 @@ void get_bypass_all_cmd(int file_desc,int dev_num){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(GET_BYPASS), &bpctl_cmd); if (ret_val == 0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status==0) @@ -1210,6 +1233,62 @@ void get_bypass_all_cmd(int file_desc,int dev_num){ } } +void get_wd_expire_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), &bpctl_cmd))<0) { + printf(NOT_SUPP_BPCTL_MSG); + return; + } + + if (bpctl_cmd.status<0) { + printf(NOT_SUPP_BP_SLAVE_UN_MSG); + return; + } + if (bpctl_cmd.status==0) + printf("not expired\n"); + else if (bpctl_cmd.status==1) + printf("expired\n"); + else printf("fail\n"); +} + +void get_wd_expire_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)&&(if_indextoname(bpctl_cmd.out_param[7], (char *)&if_name)!=NULL)) printf("%s",if_name); - printf("\n"); - - + printf("\n"); } - - } } } @@ -1365,7 +1440,7 @@ void is_bypass_all_cmd(int file_desc,int dev_num){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(IS_BYPASS), &bpctl_cmd); if (ret_val == 0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status<0) @@ -1442,7 +1517,7 @@ void get_wd_set_caps_all_cmd(int file_desc, int dev_num){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(GET_WD_SET_CAPS), &bpctl_cmd); if (ret_val==0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status<0) printf("fail\n"); @@ -1488,7 +1563,7 @@ void set_bypass_pwoff_all_cmd(int file_desc, int dev_num, int bypass_mode){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(SET_BYPASS_PWOFF), &bpctl_cmd); if (ret_val == 0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status==0) @@ -1540,7 +1615,7 @@ void get_bypass_pwoff_all_cmd(int file_desc, int dev_num){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(GET_BYPASS_PWOFF), &bpctl_cmd); if (ret_val == 0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status==0) @@ -1592,7 +1667,7 @@ void set_bypass_pwup_all_cmd(int file_desc, int dev_num,int bypass_mode){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(SET_BYPASS_PWUP), &bpctl_cmd); if (ret_val == 0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status==0) @@ -1644,7 +1719,7 @@ void get_bypass_pwup_all_cmd(int file_desc, int dev_num){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(GET_BYPASS_PWUP), &bpctl_cmd); if (ret_val == 0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status==0) @@ -1696,7 +1771,7 @@ void set_bypass_wd_all_cmd(int file_desc, int dev_num, int timeout){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(SET_BYPASS_WD), &bpctl_cmd); if (ret_val==0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status<0) @@ -1750,7 +1825,7 @@ void get_bypass_wd_all_cmd(int file_desc, int dev_num){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(GET_BYPASS_WD), &bpctl_cmd); if (ret_val==0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status<0) @@ -1803,7 +1878,7 @@ void get_wd_expire_time_all_cmd(int file_desc, int dev_num){ bpctl_cmd.in_param[0]=i; ret_val = ioctl(file_desc, IOCTL_TX_MSG(GET_WD_EXPIRE_TIME), &bpctl_cmd); if (ret_val == 0) { - if (if_info_msg(&bpctl_cmd)==0) + if (if_info_msg(file_desc, &bpctl_cmd)==0) continue; if (bpctl_cmd.status<0) @@ -1851,19 +1926,52 @@ void reset_bypass_wd_all_cmd(int file_desc, int dev_num){ struct bpctl_cmd bpctl_cmd; memset(&bpctl_cmd, 0, sizeof(bpctl_cmd)); + bpctl_cmd.in_param[0] = -1; + ret_val = ioctl(file_desc, IOCTL_TX_MSG(RESET_BYPASS_WD_TIMER), &bpctl_cmd); + + if (ret_val == 0) + printf("ok\n"); + else + printf("fail\n"); + +} + + +void set_bp_manuf_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(SET_BP_MANUF), &bpctl_cmd))<0) { + printf(NOT_SUPP_BPCTL_MSG); + return; + } + if (bpctl_cmd.status<0) + printf("fail\n"); + else printf("ok\n"); +} + +void set_bp_manuf_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 +# 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_sd.h b/libbp_sd.h index fdd6abe..bea705b 100755 --- a/libbp_sd.h +++ b/libbp_sd.h @@ -65,7 +65,7 @@ POSSIBILITY OF SUCH DAMAGE. struct bp_info { - char prod_name[14]; + char prod_name[32]; unsigned char fw_ver; }; diff --git a/release.txt b/release.txt index 629c832..4dbb0c4 100755 --- a/release.txt +++ b/release.txt @@ -1,7 +1,113 @@ Release Notes Silicom Linux Bypass-SD Control Utility - Version 5.0.65 - 09/06/2014 + Version 5.2.0.41 + 18/06/2019 + +v5.2.0.41 +- Removed M2E10G2BPI9T +- Fixed M2 IDs + +v5.2.0.40 +- Added support for kernel 5.1.6 + +v5.2.0.39 +- Fixed proc interface for bypass_slave command + +v5.2.0.38 +- Added support for M4E2G4BPi80-SD-CP, +M4E2G4BPi80-SD-CQ, M4E210G2BPI9-SR-SD-CP, +M4E210G2BPI9-SR-SD-CQ + +v5.2.0.37 +- Added support for kernel 4.15 + +v5.2.0.36 +- Added support for PE2G6BPi35-SD-RB2. + +v5.2.0.35 +- Added KVM passthrough support for intel i350/i80. + +v5.2.0.34 +- Added KVM passthrough support for intel 71. + +v5.2.0.33 +- Added support for PE2G4BPI80-SD-RB1, +PE340G2BPI71-QS43. +- Fixed prod_name size. + +v5.2.0.31 +- Added support for Ubuntu 17. +- Fixed memory issue. + +v5.2.0.30 +- Fixed get_dis_disc for ADI RANGELEY + +v5.2.0.29 +- Fixed M1 IDs + +v5.2.0.28.1 +- Added support for ADI RANGELEY Bypass + +v5.2.0.27 +- Added support for PE310G2BPi71-SR, + PE310G2BPi71-LR + +v5.2.0.26 +- Added TPL for i80 +- Removed delay log + +v5.2.0.25 +- Added TPL log. +- Added reset_bypass_wd_all IOCTL support. + +v5.2.0.24 +- Added support for 3.2.81. + +v5.2.0.23 +- Fixed 71 71LRD, added copper tpl. + +v5.2.0.22 +- Fixed reset for non-71 adapters. + +v5.2.0.21 +- Some protocol changes for updated intel 71. + +v5.2.0.19 +- Some interface changes for updated intel 71. + +v5.2.0.19 +- Some interface changes for updated intel 71. + +v5.2.0.18 +- Added support for updated Intel 71. + +v5.2.0.15 +- Added support for initial Intel 71. + +v5.1.5 +- Fixed sleep for KVM. + +v5.1.4 +- Added support for KVM. + +v5.1.3 +- Fixed output message for switch "all". +- Changed bpctl_util return code. + +v5.1.2 +- Added KVM passthrough support for 82599. + +v5.1.1 +- Added reboot notifier. + +v5.0.66 +- Moved to BSD license. + +v5.0.65.1v2 +- Fixed some warnings. + +v5.0.65.1v +- Latch delay free version. v5.0.65 - Fixed problem with event notifier