[PATCH] Silicom Bypass driver

DanielC puff65537 at bansheeslibrary.com
Fri Sep 7 02:59:06 UTC 2012



The Silicom Bypass Network Interface Cards (NICs) are network cards with paired ports (2 or 4). 
The pairs either act as a "wire" allowing the network packets to pass or insert the device in 
between the two ports.  When paired with the on-board hardware watchdog or other failsafe, 
they provide high availability for the network in the face of software outages or maintenance.

Signed-off-by: Daniel Cotey <puff65537 at bansheeslibrary.com>


diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/Kconfig working/drivers/staging/Kconfig
--- linux-2.6/drivers/staging/Kconfig	2012-08-05 23:58:27.145027922 -0700
+++ working/drivers/staging/Kconfig	2012-09-06 18:33:22.465062022 -0700
@@ -136,4 +136,6 @@ source "drivers/staging/csr/Kconfig"
 
 source "drivers/staging/omap-thermal/Kconfig"
 
+source "drivers/staging/silicom/Kconfig"
+
 endif # STAGING
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/Makefile working/drivers/staging/Makefile
--- linux-2.6/drivers/staging/Makefile	2012-08-05 23:58:27.145027922 -0700
+++ working/drivers/staging/Makefile	2012-09-06 18:34:29.020063808 -0700
@@ -60,3 +60,4 @@ obj-$(CONFIG_USB_G_CCG)		+= ccg/
 obj-$(CONFIG_WIMAX_GDM72XX)	+= gdm72xx/
 obj-$(CONFIG_CSR_WIFI)		+= csr/
 obj-$(CONFIG_OMAP_BANDGAP)	+= omap-thermal/
+obj-$(CONFIG_NET_VENDOR_SILICOM)	+= silicom/
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/bits.h working/drivers/staging/silicom/bits.h
--- linux-2.6/drivers/staging/silicom/bits.h	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/bits.h	2012-09-06 18:24:28.348047744 -0700
@@ -0,0 +1,56 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2004 Broadcom  */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/*    02/25/00 Hav Khauv        Initial version.                              */
+/******************************************************************************/
+
+#ifndef BITS_H
+#define BITS_H
+
+/******************************************************************************/
+/* Bit Mask definitions */
+/******************************************************************************/
+
+#define BIT_NONE            0x00
+#define BIT_0               0x01
+#define BIT_1               0x02
+#define BIT_2               0x04
+#define BIT_3               0x08
+#define BIT_4               0x10
+#define BIT_5               0x20
+#define BIT_6               0x40
+#define BIT_7               0x80
+#define BIT_8               0x0100
+#define BIT_9               0x0200
+#define BIT_10              0x0400
+#define BIT_11              0x0800
+#define BIT_12              0x1000
+#define BIT_13              0x2000
+#define BIT_14              0x4000
+#define BIT_15              0x8000
+#define BIT_16              0x010000
+#define BIT_17              0x020000
+#define BIT_18              0x040000
+#define BIT_19              0x080000
+#define BIT_20              0x100000
+#define BIT_21              0x200000
+#define BIT_22              0x400000
+#define BIT_23              0x800000
+#define BIT_24              0x01000000
+#define BIT_25              0x02000000
+#define BIT_26              0x04000000
+#define BIT_27              0x08000000
+#define BIT_28              0x10000000
+#define BIT_29              0x20000000
+#define BIT_30              0x40000000
+#define BIT_31              0x80000000
+
+#endif				/* BITS_H */
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/bp_ioctl.h working/drivers/staging/silicom/bp_ioctl.h
--- linux-2.6/drivers/staging/silicom/bp_ioctl.h	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/bp_ioctl.h	2012-09-06 18:24:28.349047744 -0700
@@ -0,0 +1,141 @@
+/******************************************************************************/
+/*                                                                            */
+/* Silicom Bypass Control Utility, Copyright (c) 2005-2007 Silicom            */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+
+#ifndef BP_IOCTL_H
+#define BP_IOCTL_H
+
+#define BP_CAP                   0x01	//BIT_0
+#define BP_STATUS_CAP            0x02	//BIT_1
+#define BP_STATUS_CHANGE_CAP     0x04	//BIT_2
+#define SW_CTL_CAP               0x08	//BIT_3
+#define BP_DIS_CAP               0x10	//BIT_4
+#define BP_DIS_STATUS_CAP        0x20	//BIT_5
+#define STD_NIC_CAP              0x40	//BIT_6
+#define BP_PWOFF_ON_CAP          0x80	//BIT_7
+#define BP_PWOFF_OFF_CAP         0x0100	//BIT_8
+#define BP_PWOFF_CTL_CAP         0x0200	//BIT_9
+#define BP_PWUP_ON_CAP           0x0400	//BIT_10
+#define BP_PWUP_OFF_CAP          0x0800	//BIT_11
+#define BP_PWUP_CTL_CAP          0x1000	//BIT_12
+#define WD_CTL_CAP               0x2000	//BIT_13
+#define WD_STATUS_CAP            0x4000	//BIT_14
+#define WD_TIMEOUT_CAP           0x8000	//BIT_15
+#define TX_CTL_CAP               0x10000	//BIT_16
+#define TX_STATUS_CAP            0x20000	//BIT_17
+#define TAP_CAP                  0x40000	//BIT_18
+#define TAP_STATUS_CAP           0x80000	//BIT_19
+#define TAP_STATUS_CHANGE_CAP    0x100000	//BIT_20
+#define TAP_DIS_CAP              0x200000	//BIT_21
+#define TAP_DIS_STATUS_CAP       0x400000	//BIT_22
+#define TAP_PWUP_ON_CAP          0x800000	//BIT_23
+#define TAP_PWUP_OFF_CAP         0x1000000	//BIT 24
+#define TAP_PWUP_CTL_CAP         0x2000000	//BIT 25
+#define NIC_CAP_NEG              0x4000000	//BIT 26
+#define TPL_CAP                  0x8000000	//BIT 27
+#define DISC_CAP                 0x10000000	//BIT 28
+#define DISC_DIS_CAP             0x20000000	//BIT 29
+#define DISC_PWUP_CTL_CAP        0x40000000	//BIT 30
+
+#define TPL2_CAP_EX              0x01
+#define DISC_PORT_CAP_EX         0x02
+
+#define WD_MIN_TIME_MASK(val)      (val & 0xf)
+#define WD_STEP_COUNT_MASK(val)    ((val & 0xf) << 5)
+#define WDT_STEP_TIME              0x10	//BIT_4
+
+#define WD_MIN_TIME_GET(desc)   (desc & 0xf)
+#define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf
+
+typedef enum {
+	IF_SCAN,
+	GET_DEV_NUM,
+	IS_BYPASS,
+	GET_BYPASS_SLAVE,
+	GET_BYPASS_CAPS,
+	GET_WD_SET_CAPS,
+	SET_BYPASS,
+	GET_BYPASS,
+	GET_BYPASS_CHANGE,
+	SET_BYPASS_WD,
+	GET_BYPASS_WD,
+	GET_WD_EXPIRE_TIME,
+	RESET_BYPASS_WD_TIMER,
+	SET_DIS_BYPASS,
+	GET_DIS_BYPASS,
+	SET_BYPASS_PWOFF,
+	GET_BYPASS_PWOFF,
+	SET_BYPASS_PWUP,
+	GET_BYPASS_PWUP,
+	SET_STD_NIC,
+	GET_STD_NIC,
+	SET_TX,
+	GET_TX,
+	SET_TAP,
+	GET_TAP,
+	GET_TAP_CHANGE,
+	SET_DIS_TAP,
+	GET_DIS_TAP,
+	SET_TAP_PWUP,
+	GET_TAP_PWUP,
+	SET_WD_EXP_MODE,
+	GET_WD_EXP_MODE,
+	SET_WD_AUTORESET,
+	GET_WD_AUTORESET,
+	SET_TPL,
+	GET_TPL,
+	SET_DISC,
+	GET_DISC,
+	GET_DISC_CHANGE,
+	SET_DIS_DISC,
+	GET_DIS_DISC,
+	SET_DISC_PWUP,
+	GET_DISC_PWUP,
+	GET_BYPASS_INFO = 100,
+	GET_BP_WAIT_AT_PWUP,
+	SET_BP_WAIT_AT_PWUP,
+	GET_BP_HW_RESET,
+	SET_BP_HW_RESET,
+	SET_DISC_PORT,
+	GET_DISC_PORT,
+	SET_DISC_PORT_PWUP,
+	GET_DISC_PORT_PWUP,
+	SET_BP_FORCE_LINK,
+	GET_BP_FORCE_LINK,
+#ifdef BP_SELF_TEST
+	SET_BP_SELF_TEST = 200,
+	GET_BP_SELF_TEST,
+#endif
+
+} CMND_TYPE_SD;
+
+/*
+* The major device number. We can't rely on dynamic
+* registration any more, because ioctls need to know
+* it.
+*/
+
+#define MAGIC_NUM 'J'
+
+/* for passing single values */
+struct bpctl_cmd {
+	int status;
+	int data[8];
+	int in_param[8];
+	int out_param[8];
+};
+
+#define IOCTL_TX_MSG(cmd) _IOWR(MAGIC_NUM, cmd, struct bpctl_cmd)
+
+#define DEVICE_NODE "/dev/bpctl0"
+#define DEVICE_NAME "bpctl"
+
+#endif
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/bp_mod.c working/drivers/staging/silicom/bp_mod.c
--- linux-2.6/drivers/staging/silicom/bp_mod.c	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/bp_mod.c	2012-09-06 18:24:28.360047744 -0700
@@ -0,0 +1,9012 @@
+/******************************************************************************/
+/*                                                                            */
+/* Bypass Control utility, Copyright (c) 2005-20011 Silicom                   */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*  Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.          */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+#include <linux/version.h>
+#if defined(CONFIG_SMP) && ! defined(__SMP__)
+#define __SMP__
+#endif
+
+#include <linux/kernel.h>	/* We're doing kernel work */
+#include <linux/module.h>	/* Specifically, a module */
+#include <linux/fs.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/rcupdate.h>
+#include <linux/etherdevice.h>
+
+#include <asm/uaccess.h>	/* for get_user and put_user */
+#include <linux/sched.h>
+#include <linux/ethtool.h>
+#include <linux/proc_fs.h>
+
+#include "bp_ioctl.h"
+#include "bp_mod.h"
+#include "bypass.h"
+#include "libbp_sd.h"
+
+#define SUCCESS 0
+#define BP_MOD_VER  "9.0.4"
+#define BP_MOD_DESCR "Silicom Bypass-SD Control driver"
+#define BP_SYNC_FLAG 1
+
+static int Device_Open = 0;
+static int major_num = 0;
+
+MODULE_AUTHOR("Anna Lukin, annal at silicom.co.il");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(BP_MOD_DESCR);
+MODULE_VERSION(BP_MOD_VER);
+spinlock_t bpvm_lock;
+
+#define lock_bpctl() 					\
+if (down_interruptible(&bpctl_sema)) {			\
+	return -ERESTARTSYS;				\
+}							\
+
+#define unlock_bpctl() 					\
+	up(&bpctl_sema);
+
+/* Media Types */
+typedef enum {
+	bp_copper = 0,
+	bp_fiber,
+	bp_cx4,
+	bp_none,
+} bp_media_type;
+
+struct pfs_unit_sd {
+	struct proc_dir_entry *proc_entry;
+	char proc_name[32];
+};
+
+struct bypass_pfs_sd {
+	char dir_name[32];
+	struct proc_dir_entry *bypass_entry;
+	struct pfs_unit_sd bypass_info;
+	struct pfs_unit_sd bypass_slave;
+	struct pfs_unit_sd bypass_caps;
+	struct pfs_unit_sd wd_set_caps;
+	struct pfs_unit_sd bypass;
+	struct pfs_unit_sd bypass_change;
+	struct pfs_unit_sd bypass_wd;
+	struct pfs_unit_sd wd_expire_time;
+	struct pfs_unit_sd reset_bypass_wd;
+	struct pfs_unit_sd dis_bypass;
+	struct pfs_unit_sd bypass_pwup;
+	struct pfs_unit_sd bypass_pwoff;
+	struct pfs_unit_sd std_nic;
+	struct pfs_unit_sd tap;
+	struct pfs_unit_sd dis_tap;
+	struct pfs_unit_sd tap_pwup;
+	struct pfs_unit_sd tap_change;
+	struct pfs_unit_sd wd_exp_mode;
+	struct pfs_unit_sd wd_autoreset;
+	struct pfs_unit_sd tpl;
+
+};
+
+typedef struct _bpctl_dev {
+	char *name;
+	char *desc;
+	struct pci_dev *pdev;	/* PCI device */
+	struct net_device *ndev;	/* net device */
+	unsigned long mem_map;
+	uint8_t bus;
+	uint8_t slot;
+	uint8_t func;
+	u_int32_t device;
+	u_int32_t vendor;
+	u_int32_t subvendor;
+	u_int32_t subdevice;
+	int ifindex;
+	uint32_t bp_caps;
+	uint32_t bp_caps_ex;
+	uint8_t bp_fw_ver;
+	int bp_ext_ver;
+	int wdt_status;
+	unsigned long bypass_wdt_on_time;
+	uint32_t bypass_timer_interval;
+	struct timer_list bp_timer;
+	uint32_t reset_time;
+	uint8_t bp_status_un;
+	atomic_t wdt_busy;
+	bp_media_type media_type;
+	int bp_tpl_flag;
+	struct timer_list bp_tpl_timer;
+	spinlock_t bypass_wr_lock;
+	int bp_10g;
+	int bp_10gb;
+	int bp_fiber5;
+	int bp_10g9;
+	int bp_i80;
+	int bp_540;
+
+// selftest stanza
+	int (*hard_start_xmit_save) (struct sk_buff * skb,
+				     struct net_device * dev);
+	const struct net_device_ops *old_ops;
+	struct net_device_ops new_ops;
+	int bp_self_test_flag;
+	char *bp_tx_data;
+// end selftest stanza 
+//
+	struct bypass_pfs_sd bypass_pfs_set;
+
+} bpctl_dev_t;
+
+static bpctl_dev_t *bpctl_dev_arr;
+
+static struct semaphore bpctl_sema;
+static int device_num = 0;
+
+static int get_dev_idx(int ifindex);
+static bpctl_dev_t *get_master_port_fn(bpctl_dev_t * pbpctl_dev);
+static int disc_status(bpctl_dev_t * pbpctl_dev);
+static int bypass_status(bpctl_dev_t * pbpctl_dev);
+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);
+
+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);
+
+int is_bypass_fn(bpctl_dev_t * pbpctl_dev);
+int get_dev_idx_bsf(int bus, int slot, int func);
+
+static unsigned long str_to_hex(char *p);
+static int bp_device_event(struct notifier_block *unused,
+			   unsigned long event, void *ptr)
+{
+	struct net_device *dev = ptr;
+	static bpctl_dev_t *pbpctl_dev = NULL, *pbpctl_dev_m = NULL;
+	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;
+	if (!dev)
+		return NOTIFY_DONE;
+	if (event == NETDEV_REGISTER) {
+		{
+			struct ethtool_drvinfo drvinfo;
+			// char *str=NULL;
+			char cbuf[32];
+			char *buf = NULL;
+			char res[10];
+			int i = 0, ifindex, idx_dev = 0;
+			int bus = 0, slot = 0, func = 0;
+			ifindex = dev->ifindex;
+
+			memset(res, 0, 10);
+			memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
+
+			if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) {
+				memset(&drvinfo, 0, sizeof(drvinfo));
+				dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
+			} else
+				return NOTIFY_DONE;
+			if (!drvinfo.bus_info)
+				return NOTIFY_DONE;
+			if (!strcmp(drvinfo.bus_info, "N/A"))
+				return NOTIFY_DONE;
+			memcpy(&cbuf, drvinfo.bus_info, 32);
+			buf = &cbuf[0];
+
+			// while(*buf++){
+
+			/*if(*buf==':'){
+			   buf++;
+			   break;
+			   } */
+			//}
+			while (*buf++ != ':') ;
+			for (i = 0; i < 10; i++, buf++) {
+				if (*buf == ':')
+					break;
+				res[i] = *buf;
+
+			}
+			buf++;
+			bus = str_to_hex(res);
+			memset(res, 0, 10);
+
+			for (i = 0; i < 10; i++, buf++) {
+				if (*buf == '.')
+					break;
+				res[i] = *buf;
+
+			}
+			buf++;
+			slot = str_to_hex(res);
+			func = str_to_hex(buf);
+			idx_dev = get_dev_idx_bsf(bus, slot, func);
+
+			if (idx_dev != -1) {
+
+				bpctl_dev_arr[idx_dev].ifindex = ifindex;
+				bpctl_dev_arr[idx_dev].ndev = dev;
+
+				bypass_proc_remove_dev_sd(&bpctl_dev_arr
+							  [idx_dev]);
+				bypass_proc_create_dev_sd(&bpctl_dev_arr
+							  [idx_dev]);
+
+			}
+
+		}
+		return NOTIFY_DONE;
+
+	}
+	if (event == NETDEV_UNREGISTER) {
+		int idx_dev = 0;
+		//if_scan();
+		for (idx_dev = 0;
+		     ((bpctl_dev_arr[idx_dev].pdev != NULL)
+		      && (idx_dev < device_num)); idx_dev++) {
+			if (bpctl_dev_arr[idx_dev].ndev == dev) {
+				bypass_proc_remove_dev_sd(&bpctl_dev_arr
+							  [idx_dev]);
+				bpctl_dev_arr[idx_dev].ndev = NULL;
+
+				return NOTIFY_DONE;
+
+			}
+
+		}
+		return NOTIFY_DONE;
+	}
+	if (event == NETDEV_CHANGENAME) {
+		int idx_dev = 0;
+		//if_scan();
+		for (idx_dev = 0;
+		     ((bpctl_dev_arr[idx_dev].pdev != NULL)
+		      && (idx_dev < device_num)); idx_dev++) {
+			if (bpctl_dev_arr[idx_dev].ndev == dev) {
+				bypass_proc_remove_dev_sd(&bpctl_dev_arr
+							  [idx_dev]);
+				bypass_proc_create_dev_sd(&bpctl_dev_arr
+							  [idx_dev]);
+
+				return NOTIFY_DONE;
+
+			}
+
+		}
+		return NOTIFY_DONE;
+
+	}
+	//return NOTIFY_DONE;
+
+	switch (event) {
+
+	case NETDEV_CHANGE:{
+			if (netif_carrier_ok(dev))
+				return NOTIFY_DONE;
+
+			//if_scan();
+			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)
+				pbpctl_dev_m = pbpctl_dev;
+			else
+				pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
+			if (!pbpctl_dev_m)
+				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");
+
+			}
+			return NOTIFY_DONE;
+
+		}
+
+	default:
+		return NOTIFY_DONE;
+
+	}
+	return NOTIFY_DONE;
+
+}
+
+static struct notifier_block bp_notifier_block = {
+	.notifier_call = bp_device_event,
+};
+
+static int device_open(struct inode *inode, struct file *file)
+{
+#ifdef DEBUG
+	printk("device_open(%p)\n", file);
+#endif
+	Device_Open++;
+/*
+* Initialize the message
+*/
+	return SUCCESS;
+}
+
+static int device_release(struct inode *inode, struct file *file)
+{
+#ifdef DEBUG
+	printk("device_release(%p,%p)\n", inode, file);
+#endif
+	Device_Open--;
+	return SUCCESS;
+}
+
+int is_bypass_fn(bpctl_dev_t * pbpctl_dev);
+int wdt_time_left(bpctl_dev_t * pbpctl_dev);
+
+static void write_pulse(bpctl_dev_t * pbpctl_dev,
+			unsigned int ctrl_ext,
+			unsigned char value, unsigned char len)
+{
+	unsigned char ctrl_val = 0;
+	unsigned int i = len;
+	unsigned int ctrl = 0;
+	bpctl_dev_t *pbpctl_dev_c = NULL;
+
+	if (pbpctl_dev->bp_i80)
+		ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+	if (pbpctl_dev->bp_540)
+		ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+
+	if (pbpctl_dev->bp_10g9) {
+		if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev)))
+			return;
+		ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
+	}
+
+	while (i--) {
+		ctrl_val = (value >> i) & 0x1;
+		if (ctrl_val) {
+			if (pbpctl_dev->bp_10g9) {
+
+				/* To start management : MCLK 1, MDIO 1, output */
+				/* DATA 1 CLK 1 */
+				/*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */
+				BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
+						ctrl_ext |
+						BP10G_MDIO_DATA_OUT9);
+				BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+						(ctrl | BP10G_MCLK_DATA_OUT9 |
+						 BP10G_MCLK_DIR_OUT9));
+
+			} else if (pbpctl_dev->bp_fiber5) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext |
+								      BPCTLI_CTRL_EXT_MCLK_DIR5
+								      |
+								      BPCTLI_CTRL_EXT_MDIO_DIR5
+								      |
+								      BPCTLI_CTRL_EXT_MDIO_DATA5
+								      |
+								      BPCTLI_CTRL_EXT_MCLK_DATA5));
+
+			} else if (pbpctl_dev->bp_i80) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext |
+								      BPCTLI_CTRL_EXT_MDIO_DIR80
+								      |
+								      BPCTLI_CTRL_EXT_MDIO_DATA80));
+
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, (ctrl |
+									  BPCTLI_CTRL_EXT_MCLK_DIR80
+									  |
+									  BPCTLI_CTRL_EXT_MCLK_DATA80));
+
+			} else if (pbpctl_dev->bp_540) {
+				BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl |
+								   BP540_MDIO_DIR
+								   |
+								   BP540_MDIO_DATA
+								   |
+								   BP540_MCLK_DIR
+								   |
+								   BP540_MCLK_DATA));
+
+			} else if (pbpctl_dev->bp_10gb) {
+				BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+						 (ctrl_ext | BP10GB_MDIO_SET |
+						  BP10GB_MCLK_SET) &
+						 ~(BP10GB_MCLK_DIR |
+						   BP10GB_MDIO_DIR |
+						   BP10GB_MDIO_CLR |
+						   BP10GB_MCLK_CLR));
+
+			} else if (!pbpctl_dev->bp_10g)
+				/* To start management : MCLK 1, MDIO 1, output */
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+						   (ctrl_ext |
+						    BPCTLI_CTRL_EXT_MCLK_DIR |
+						    BPCTLI_CTRL_EXT_MDIO_DIR |
+						    BPCTLI_CTRL_EXT_MDIO_DATA |
+						    BPCTLI_CTRL_EXT_MCLK_DATA));
+			else {
+
+/* To start management : MCLK 1, MDIO 1, output*/
+				//writel((0x2|0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+				BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+						(ctrl_ext | BP10G_MCLK_DATA_OUT
+						 | BP10G_MDIO_DATA_OUT));
+				//BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl | BP10G_MDIO_DATA | BP10G_MDIO_DIR));  
+
+			}
+
+			usec_delay(PULSE_TIME);
+			if (pbpctl_dev->bp_10g9) {
+
+				/*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MDIO_DATA_OUT9)&~(BP10G_MCLK_DATA_OUT9))); */
+				/* DATA 1 CLK 0 */
+				BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
+						ctrl_ext |
+						BP10G_MDIO_DATA_OUT9);
+				BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+						(ctrl | BP10G_MCLK_DIR_OUT9) &
+						~BP10G_MCLK_DATA_OUT9);
+
+			} else if (pbpctl_dev->bp_fiber5) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+						   ((ctrl_ext |
+						     BPCTLI_CTRL_EXT_MCLK_DIR5 |
+						     BPCTLI_CTRL_EXT_MDIO_DIR5 |
+						     BPCTLI_CTRL_EXT_MDIO_DATA5)
+						    &
+						    ~
+						    (BPCTLI_CTRL_EXT_MCLK_DATA5)));
+
+			} else if (pbpctl_dev->bp_i80) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext |
+								      BPCTLI_CTRL_EXT_MDIO_DIR80
+								      |
+								      BPCTLI_CTRL_EXT_MDIO_DATA80));
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+						   ((ctrl |
+						     BPCTLI_CTRL_EXT_MCLK_DIR80)
+						    &
+						    ~
+						    (BPCTLI_CTRL_EXT_MCLK_DATA80)));
+
+			} else if (pbpctl_dev->bp_540) {
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						(ctrl | BP540_MDIO_DIR |
+						 BP540_MDIO_DATA |
+						 BP540_MCLK_DIR) &
+						~(BP540_MCLK_DATA));
+
+			} else if (pbpctl_dev->bp_10gb) {
+
+				BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+						 (ctrl_ext | BP10GB_MDIO_SET |
+						  BP10GB_MCLK_CLR) &
+						 ~(BP10GB_MCLK_DIR |
+						   BP10GB_MDIO_DIR |
+						   BP10GB_MDIO_CLR |
+						   BP10GB_MCLK_SET));
+
+			} else if (!pbpctl_dev->bp_10g)
+
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+						   ((ctrl_ext |
+						     BPCTLI_CTRL_EXT_MCLK_DIR |
+						     BPCTLI_CTRL_EXT_MDIO_DIR |
+						     BPCTLI_CTRL_EXT_MDIO_DATA)
+						    &
+						    ~
+						    (BPCTLI_CTRL_EXT_MCLK_DATA)));
+			else {
+
+				//writel((0x2), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+				BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+						((ctrl_ext |
+						  BP10G_MDIO_DATA_OUT) &
+						 ~(BP10G_MCLK_DATA_OUT)));
+				//  BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl |BP10G_MDIO_DIR|BP10G_MDIO_DATA));
+			}
+
+			usec_delay(PULSE_TIME);
+
+		} else {
+			if (pbpctl_dev->bp_10g9) {
+				/* DATA 0 CLK 1 */
+				/*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MCLK_DATA_OUT9)&~BP10G_MDIO_DATA_OUT9)); */
+				BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
+						(ctrl_ext &
+						 ~BP10G_MDIO_DATA_OUT9));
+				BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+						(ctrl | BP10G_MCLK_DATA_OUT9 |
+						 BP10G_MCLK_DIR_OUT9));
+
+			} else if (pbpctl_dev->bp_fiber5) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+						   ((ctrl_ext |
+						     BPCTLI_CTRL_EXT_MCLK_DIR5 |
+						     BPCTLI_CTRL_EXT_MDIO_DIR5 |
+						     BPCTLI_CTRL_EXT_MCLK_DATA5)
+						    &
+						    ~
+						    (BPCTLI_CTRL_EXT_MDIO_DATA5)));
+
+			} else if (pbpctl_dev->bp_i80) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+						   ((ctrl_ext |
+						     BPCTLI_CTRL_EXT_MDIO_DIR80)
+						    &
+						    ~
+						    (BPCTLI_CTRL_EXT_MDIO_DATA80)));
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+						   (ctrl |
+						    BPCTLI_CTRL_EXT_MCLK_DIR80 |
+						    BPCTLI_CTRL_EXT_MCLK_DATA80));
+
+			} else if (pbpctl_dev->bp_540) {
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						((ctrl | BP540_MCLK_DIR |
+						  BP540_MCLK_DATA |
+						  BP540_MDIO_DIR) &
+						 ~(BP540_MDIO_DATA)));
+
+			} else if (pbpctl_dev->bp_10gb) {
+				BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+						 (ctrl_ext | BP10GB_MDIO_CLR |
+						  BP10GB_MCLK_SET) &
+						 ~(BP10GB_MCLK_DIR |
+						   BP10GB_MDIO_DIR |
+						   BP10GB_MDIO_SET |
+						   BP10GB_MCLK_CLR));
+
+			} else if (!pbpctl_dev->bp_10g)
+
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+						   ((ctrl_ext |
+						     BPCTLI_CTRL_EXT_MCLK_DIR |
+						     BPCTLI_CTRL_EXT_MDIO_DIR |
+						     BPCTLI_CTRL_EXT_MCLK_DATA)
+						    &
+						    ~
+						    (BPCTLI_CTRL_EXT_MDIO_DATA)));
+			else {
+
+				//    writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+				BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+						((ctrl_ext |
+						  BP10G_MCLK_DATA_OUT) &
+						 ~BP10G_MDIO_DATA_OUT));
+				//  BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
+
+			}
+			usec_delay(PULSE_TIME);
+			if (pbpctl_dev->bp_10g9) {
+				/* DATA 0 CLK 0 */
+				/*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
+				BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
+						(ctrl_ext &
+						 ~BP10G_MDIO_DATA_OUT9));
+				BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+						((ctrl | BP10G_MCLK_DIR_OUT9) &
+						 ~(BP10G_MCLK_DATA_OUT9)));
+
+			} else if (pbpctl_dev->bp_fiber5) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+						   ((ctrl_ext |
+						     BPCTLI_CTRL_EXT_MCLK_DIR5 |
+						     BPCTLI_CTRL_EXT_MDIO_DIR5)
+						    &
+						    ~(BPCTLI_CTRL_EXT_MCLK_DATA5
+						      |
+						      BPCTLI_CTRL_EXT_MDIO_DATA5)));
+
+			} else if (pbpctl_dev->bp_i80) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+						   ((ctrl_ext |
+						     BPCTLI_CTRL_EXT_MDIO_DIR80)
+						    &
+						    ~BPCTLI_CTRL_EXT_MDIO_DATA80));
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+						   ((ctrl |
+						     BPCTLI_CTRL_EXT_MCLK_DIR80)
+						    &
+						    ~
+						    (BPCTLI_CTRL_EXT_MCLK_DATA80)));
+
+			} else if (pbpctl_dev->bp_540) {
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						((ctrl | BP540_MCLK_DIR |
+						  BP540_MDIO_DIR) &
+						 ~(BP540_MDIO_DATA |
+						   BP540_MCLK_DATA)));
+			} else if (pbpctl_dev->bp_10gb) {
+
+				BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+						 (ctrl_ext | BP10GB_MDIO_CLR |
+						  BP10GB_MCLK_CLR) &
+						 ~(BP10GB_MCLK_DIR |
+						   BP10GB_MDIO_DIR |
+						   BP10GB_MDIO_SET |
+						   BP10GB_MCLK_SET));
+
+			} else if (!pbpctl_dev->bp_10g)
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+						   ((ctrl_ext |
+						     BPCTLI_CTRL_EXT_MCLK_DIR |
+						     BPCTLI_CTRL_EXT_MDIO_DIR) &
+						    ~(BPCTLI_CTRL_EXT_MCLK_DATA
+						      |
+						      BPCTLI_CTRL_EXT_MDIO_DATA)));
+			else {
+
+				//writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+				BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+						(ctrl_ext &
+						 ~(BP10G_MCLK_DATA_OUT |
+						   BP10G_MDIO_DATA_OUT)));
+				//BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
+			}
+
+			usec_delay(PULSE_TIME);
+		}
+
+	}
+}
+
+static int read_pulse(bpctl_dev_t * pbpctl_dev, unsigned int ctrl_ext,
+		      unsigned char len)
+{
+	unsigned char ctrl_val = 0;
+	unsigned int i = len;
+	unsigned int ctrl = 0;
+	bpctl_dev_t *pbpctl_dev_c = NULL;
+
+	if (pbpctl_dev->bp_i80)
+		ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+	if (pbpctl_dev->bp_540)
+		ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+	if (pbpctl_dev->bp_10g9) {
+		if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev)))
+			return -1;
+		ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
+	}
+
+	//ctrl_ext=BP10G_READ_REG(pbpctl_dev,EODSDP);    
+
+	while (i--) {
+		if (pbpctl_dev->bp_10g9) {
+			/*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MDIO_DATA_OUT9)&~BP10G_MCLK_DATA_OUT9)); */
+			/* DATA ? CLK 0 */
+			BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+					((ctrl | BP10G_MCLK_DIR_OUT9) &
+					 ~(BP10G_MCLK_DATA_OUT9)));
+
+		} else if (pbpctl_dev->bp_fiber5) {
+			BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+							       BPCTLI_CTRL_EXT_MCLK_DIR5)
+							      &
+							      ~
+							      (BPCTLI_CTRL_EXT_MDIO_DIR5
+							       |
+							       BPCTLI_CTRL_EXT_MCLK_DATA5)));
+
+		} else if (pbpctl_dev->bp_i80) {
+			BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+					   (ctrl_ext &
+					    ~BPCTLI_CTRL_EXT_MDIO_DIR80));
+			BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+					   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80)
+					    & ~(BPCTLI_CTRL_EXT_MCLK_DATA80)));
+
+		} else if (pbpctl_dev->bp_540) {
+			BP10G_WRITE_REG(pbpctl_dev, ESDP,
+					((ctrl | BP540_MCLK_DIR) &
+					 ~(BP540_MDIO_DIR | BP540_MCLK_DATA)));
+
+		} else if (pbpctl_dev->bp_10gb) {
+
+			BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+					 (ctrl_ext | BP10GB_MDIO_DIR |
+					  BP10GB_MCLK_CLR) & ~(BP10GB_MCLK_DIR |
+							       BP10GB_MDIO_CLR |
+							       BP10GB_MDIO_SET |
+							       BP10GB_MCLK_SET));
+
+		} else if (!pbpctl_dev->bp_10g)
+			BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+								   BPCTLI_CTRL_EXT_MCLK_DIR)
+								  &
+								  ~
+								  (BPCTLI_CTRL_EXT_MDIO_DIR
+								   |
+								   BPCTLI_CTRL_EXT_MCLK_DATA)));
+		else {
+
+			// writel(( 0/*0x1*/), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+			BP10G_WRITE_REG(pbpctl_dev, EODSDP, ((ctrl_ext | BP10G_MDIO_DATA_OUT) & ~BP10G_MCLK_DATA_OUT));	/* ? */
+			//    printk("0x28=0x%x\n",BP10G_READ_REG(pbpctl_dev,EODSDP););
+			//BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~BP10G_MDIO_DIR));
+
+		}
+
+		usec_delay(PULSE_TIME);
+		if (pbpctl_dev->bp_10g9) {
+			/*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */
+			/* DATA ? CLK 1 */
+			BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+					(ctrl | BP10G_MCLK_DATA_OUT9 |
+					 BP10G_MCLK_DIR_OUT9));
+
+		} else if (pbpctl_dev->bp_fiber5) {
+			BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+							       BPCTLI_CTRL_EXT_MCLK_DIR5
+							       |
+							       BPCTLI_CTRL_EXT_MCLK_DATA5)
+							      &
+							      ~
+							      (BPCTLI_CTRL_EXT_MDIO_DIR5)));
+
+		} else if (pbpctl_dev->bp_i80) {
+			BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+					   (ctrl_ext &
+					    ~(BPCTLI_CTRL_EXT_MDIO_DIR80)));
+			BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+					   (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 |
+					    BPCTLI_CTRL_EXT_MCLK_DATA80));
+
+		} else if (pbpctl_dev->bp_540) {
+			BP10G_WRITE_REG(pbpctl_dev, ESDP,
+					((ctrl | BP540_MCLK_DIR |
+					  BP540_MCLK_DATA) &
+					 ~(BP540_MDIO_DIR)));
+
+		} else if (pbpctl_dev->bp_10gb) {
+			BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+					 (ctrl_ext | BP10GB_MDIO_DIR |
+					  BP10GB_MCLK_SET) & ~(BP10GB_MCLK_DIR |
+							       BP10GB_MDIO_CLR |
+							       BP10GB_MDIO_SET |
+							       BP10GB_MCLK_CLR));
+
+		} else if (!pbpctl_dev->bp_10g)
+			BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+								   BPCTLI_CTRL_EXT_MCLK_DIR
+								   |
+								   BPCTLI_CTRL_EXT_MCLK_DATA)
+								  &
+								  ~
+								  (BPCTLI_CTRL_EXT_MDIO_DIR)));
+		else {
+
+			// writel((0x8 /*|0x1*/ ), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+			BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+					(ctrl_ext | BP10G_MCLK_DATA_OUT |
+					 BP10G_MDIO_DATA_OUT));
+			//BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~BP10G_MDIO_DIR));
+
+		}
+		if (pbpctl_dev->bp_10g9) {
+			ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
+
+		} else if ((pbpctl_dev->bp_fiber5) || (pbpctl_dev->bp_i80)) {
+			ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
+		} else if (pbpctl_dev->bp_540) {
+			ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP);
+		} else if (pbpctl_dev->bp_10gb)
+			ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
+
+		else if (!pbpctl_dev->bp_10g)
+			ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+		else
+			ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
+		//ctrl_ext =readl((void *)((pbpctl_dev)->mem_map) + 0x28);
+
+		usec_delay(PULSE_TIME);
+		if (pbpctl_dev->bp_10g9) {
+			if (ctrl_ext & BP10G_MDIO_DATA_IN9)
+				ctrl_val |= 1 << i;
+
+		} else if (pbpctl_dev->bp_fiber5) {
+			if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA5)
+				ctrl_val |= 1 << i;
+		} else if (pbpctl_dev->bp_i80) {
+			if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA80)
+				ctrl_val |= 1 << i;
+		} else if (pbpctl_dev->bp_540) {
+			if (ctrl_ext & BP540_MDIO_DATA)
+				ctrl_val |= 1 << i;
+		} else if (pbpctl_dev->bp_10gb) {
+			if (ctrl_ext & BP10GB_MDIO_DATA)
+				ctrl_val |= 1 << i;
+
+		} else if (!pbpctl_dev->bp_10g) {
+
+			if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA)
+				ctrl_val |= 1 << i;
+		} else {
+
+			if (ctrl_ext & BP10G_MDIO_DATA_IN)
+				ctrl_val |= 1 << i;
+		}
+
+	}
+
+	return ctrl_val;
+}
+
+static void write_reg(bpctl_dev_t * pbpctl_dev, unsigned char value,
+		      unsigned char addr)
+{
+	uint32_t ctrl_ext = 0, ctrl = 0;
+	bpctl_dev_t *pbpctl_dev_c = NULL;
+	unsigned long flags;
+	if (pbpctl_dev->bp_10g9) {
+		if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev)))
+			return;
+	}
+	if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) &&
+	    (pbpctl_dev->bp_ext_ver < PXG4BPFI_VER))
+		wdt_time_left(pbpctl_dev);
+
+#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) {
+
+		ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
+		ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
+		/* DATA 0 CLK 0 */
+		/* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
+		BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
+				(ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
+		BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+				((ctrl | BP10G_MCLK_DIR_OUT9) &
+				 ~(BP10G_MCLK_DATA_OUT9)));
+
+	} else if (pbpctl_dev->bp_fiber5) {
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MCLK_DIR5
+						       |
+						       BPCTLI_CTRL_EXT_MDIO_DIR5)
+						      &
+						      ~
+						      (BPCTLI_CTRL_EXT_MDIO_DATA5
+						       |
+						       BPCTLI_CTRL_EXT_MCLK_DATA5)));
+	} else if (pbpctl_dev->bp_i80) {
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
+		ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MDIO_DIR80)
+						      &
+						      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+				   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
+				    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
+
+	} else if (pbpctl_dev->bp_540) {
+		ctrl = ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP);
+		BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |
+						    BP540_MDIO_DIR |
+						    BP540_MCLK_DIR) &
+						   ~(BP540_MDIO_DATA |
+						     BP540_MCLK_DATA)));
+
+	} else if (pbpctl_dev->bp_10gb) {
+		ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
+
+		BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+				 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
+				 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
+				     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
+
+	} else if (!pbpctl_dev->bp_10g) {
+
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+							   BPCTLI_CTRL_EXT_MCLK_DIR
+							   |
+							   BPCTLI_CTRL_EXT_MDIO_DIR)
+							  &
+							  ~
+							  (BPCTLI_CTRL_EXT_MDIO_DATA
+							   |
+							   BPCTLI_CTRL_EXT_MCLK_DATA)));
+	} else {
+		ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+		ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
+		BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+				(ctrl_ext &
+				 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
+		//BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
+		//writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+	}
+	usec_delay(CMND_INTERVAL);
+
+	/*send sync cmd */
+	write_pulse(pbpctl_dev, ctrl_ext, SYNC_CMD_VAL, SYNC_CMD_LEN);
+	/*send wr cmd */
+	write_pulse(pbpctl_dev, ctrl_ext, WR_CMD_VAL, WR_CMD_LEN);
+	write_pulse(pbpctl_dev, ctrl_ext, addr, ADDR_CMD_LEN);
+
+	/*write data */
+	write_pulse(pbpctl_dev, ctrl_ext, value, WR_DATA_LEN);
+	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));
+		BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+				((ctrl | BP10G_MCLK_DIR_OUT9) &
+				 ~(BP10G_MCLK_DATA_OUT9)));
+
+	} else if (pbpctl_dev->bp_fiber5) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MCLK_DIR5
+						       |
+						       BPCTLI_CTRL_EXT_MDIO_DIR5)
+						      &
+						      ~
+						      (BPCTLI_CTRL_EXT_MDIO_DATA5
+						       |
+						       BPCTLI_CTRL_EXT_MCLK_DATA5)));
+	} else if (pbpctl_dev->bp_i80) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MDIO_DIR80)
+						      &
+						      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+				   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
+				    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
+	} else if (pbpctl_dev->bp_540) {
+		BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |
+						    BP540_MDIO_DIR |
+						    BP540_MCLK_DIR) &
+						   ~(BP540_MDIO_DATA |
+						     BP540_MCLK_DATA)));
+	} else if (pbpctl_dev->bp_10gb) {
+		BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+				 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
+				 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
+				     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
+
+	} else if (!pbpctl_dev->bp_10g)
+
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+							   BPCTLI_CTRL_EXT_MCLK_DIR
+							   |
+							   BPCTLI_CTRL_EXT_MDIO_DIR)
+							  &
+							  ~
+							  (BPCTLI_CTRL_EXT_MDIO_DATA
+							   |
+							   BPCTLI_CTRL_EXT_MCLK_DATA)));
+	else {
+		BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+				(ctrl_ext &
+				 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
+		// BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
+
+		//   writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+	}
+
+	usec_delay(CMND_INTERVAL * 4);
+
+	if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) &&
+	    (pbpctl_dev->bp_ext_ver < PXG4BPFI_VER) && (addr == CMND_REG_ADDR))
+		pbpctl_dev->bypass_wdt_on_time = jiffies;
+#ifdef BP_SYNC_FLAG
+	spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
+#else
+	atomic_set(&pbpctl_dev->wdt_busy, 0);
+#endif
+
+}
+
+static void write_data(bpctl_dev_t * pbpctl_dev, unsigned char value)
+{
+	write_reg(pbpctl_dev, value, CMND_REG_ADDR);
+}
+
+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;
+	}
+
+	if (pbpctl_dev->bp_10g9) {
+		ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
+		ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
+
+		/* 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));
+		BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+				((ctrl | BP10G_MCLK_DIR_OUT9) &
+				 ~(BP10G_MCLK_DATA_OUT9)));
+
+	} else if (pbpctl_dev->bp_fiber5) {
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
+
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MCLK_DIR5
+						       |
+						       BPCTLI_CTRL_EXT_MDIO_DIR5)
+						      &
+						      ~
+						      (BPCTLI_CTRL_EXT_MDIO_DATA5
+						       |
+						       BPCTLI_CTRL_EXT_MCLK_DATA5)));
+	} else if (pbpctl_dev->bp_i80) {
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
+		ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MDIO_DIR80)
+						      &
+						      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+				   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
+				    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
+	} else if (pbpctl_dev->bp_540) {
+		ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP);
+		ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+
+		BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
+						    BP540_MDIO_DIR) &
+						   ~(BP540_MDIO_DATA |
+						     BP540_MCLK_DATA)));
+	} else if (pbpctl_dev->bp_10gb) {
+		ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
+
+		BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+				 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
+				 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
+				     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
+#if 0
+
+		/*BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, (ctrl_ext | BP10GB_MCLK_DIR | BP10GB_MDIO_DIR|
+		   BP10GB_MCLK_CLR|BP10GB_MDIO_CLR));
+		   ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
+		   printk("1reg=%x\n", ctrl_ext); */
+
+		BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, ((ctrl_ext |
+							      BP10GB_MCLK_SET |
+							      BP10GB_MDIO_CLR))
+				 & ~(BP10GB_MCLK_CLR | BP10GB_MDIO_SET |
+				     BP10GB_MCLK_DIR | BP10GB_MDIO_DIR));
+
+		/*   bnx2x_set_spio(pbpctl_dev, 5, MISC_REGISTERS_SPIO_OUTPUT_LOW);
+		   bnx2x_set_spio(pbpctl_dev, 4, MISC_REGISTERS_SPIO_OUTPUT_LOW);
+		   bnx2x_set_spio(pbpctl_dev, 4, MISC_REGISTERS_SPIO_INPUT_HI_Z); */
+
+		ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
+
+		//printk("2reg=%x\n", ctrl_ext);
+
+#ifdef BP_SYNC_FLAG
+		spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
+#else
+		atomic_set(&pbpctl_dev->wdt_busy, 0);
+#endif
+
+		return 0;
+
+#endif
+
+	} else if (!pbpctl_dev->bp_10g) {
+
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+							   BPCTLI_CTRL_EXT_MCLK_DIR
+							   |
+							   BPCTLI_CTRL_EXT_MDIO_DIR)
+							  &
+							  ~
+							  (BPCTLI_CTRL_EXT_MDIO_DATA
+							   |
+							   BPCTLI_CTRL_EXT_MCLK_DATA)));
+	} else {
+
+		//   writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+		ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+		ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
+		BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+				(ctrl_ext &
+				 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
+		//BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
+
+	}
+
+	usec_delay(CMND_INTERVAL);
+
+	/*send sync cmd */
+	write_pulse(pbpctl_dev, ctrl_ext, SYNC_CMD_VAL, SYNC_CMD_LEN);
+	/*send rd cmd */
+	write_pulse(pbpctl_dev, ctrl_ext, RD_CMD_VAL, RD_CMD_LEN);
+	/*send addr */
+	write_pulse(pbpctl_dev, ctrl_ext, addr, ADDR_CMD_LEN);
+	/*read data */
+	/* zero */
+	if (pbpctl_dev->bp_10g9) {
+		/* DATA 0 CLK 1 */
+		/*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */
+		BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
+				(ctrl_ext | BP10G_MDIO_DATA_OUT9));
+		BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+				(ctrl | BP10G_MCLK_DATA_OUT9 |
+				 BP10G_MCLK_DIR_OUT9));
+
+	} else if (pbpctl_dev->bp_fiber5) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MCLK_DIR5
+						       |
+						       BPCTLI_CTRL_EXT_MCLK_DATA5)
+						      &
+						      ~
+						      (BPCTLI_CTRL_EXT_MDIO_DIR5
+						       |
+						       BPCTLI_CTRL_EXT_MDIO_DATA5)));
+
+	} else if (pbpctl_dev->bp_i80) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+				   (ctrl_ext &
+				    ~(BPCTLI_CTRL_EXT_MDIO_DATA80 |
+				      BPCTLI_CTRL_EXT_MDIO_DIR80)));
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+				   (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 |
+				    BPCTLI_CTRL_EXT_MCLK_DATA80));
+
+	} else if (pbpctl_dev->bp_540) {
+		BP10G_WRITE_REG(pbpctl_dev, ESDP,
+				(((ctrl | BP540_MDIO_DIR | BP540_MCLK_DIR |
+				   BP540_MCLK_DATA) & ~BP540_MDIO_DATA)));
+
+	} else if (pbpctl_dev->bp_10gb) {
+
+		BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+				 (ctrl_ext | BP10GB_MDIO_DIR | BP10GB_MCLK_SET)
+				 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_SET |
+				     BP10GB_MDIO_CLR | BP10GB_MCLK_CLR));
+
+	} else if (!pbpctl_dev->bp_10g)
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+							   BPCTLI_CTRL_EXT_MCLK_DIR
+							   |
+							   BPCTLI_CTRL_EXT_MCLK_DATA)
+							  &
+							  ~
+							  (BPCTLI_CTRL_EXT_MDIO_DIR
+							   |
+							   BPCTLI_CTRL_EXT_MDIO_DATA)));
+	else {
+
+		// writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; 
+		BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+				(ctrl_ext | BP10G_MCLK_DATA_OUT |
+				 BP10G_MDIO_DATA_OUT));
+
+		// BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~(BP10G_MDIO_DATA|BP10G_MDIO_DIR)));
+
+	}
+	usec_delay(PULSE_TIME);
+
+	ctrl_value = read_pulse(pbpctl_dev, ctrl_ext, RD_DATA_LEN);
+
+	if (pbpctl_dev->bp_10g9) {
+		ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
+		ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
+
+		/* 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));
+		BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+				((ctrl | BP10G_MCLK_DIR_OUT9) &
+				 ~(BP10G_MCLK_DATA_OUT9)));
+
+	} else if (pbpctl_dev->bp_fiber5) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MCLK_DIR5
+						       |
+						       BPCTLI_CTRL_EXT_MDIO_DIR5)
+						      &
+						      ~
+						      (BPCTLI_CTRL_EXT_MDIO_DATA5
+						       |
+						       BPCTLI_CTRL_EXT_MCLK_DATA5)));
+	} else if (pbpctl_dev->bp_i80) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MDIO_DIR80)
+						      &
+						      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+				   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
+				    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
+
+	} else if (pbpctl_dev->bp_540) {
+		ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+		BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
+						    BP540_MDIO_DIR) &
+						   ~(BP540_MDIO_DATA |
+						     BP540_MCLK_DATA)));
+
+	} else if (pbpctl_dev->bp_10gb) {
+		ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
+		BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+				 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
+				 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
+				     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
+
+	} else if (!pbpctl_dev->bp_10g) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+							   BPCTLI_CTRL_EXT_MCLK_DIR
+							   |
+							   BPCTLI_CTRL_EXT_MDIO_DIR)
+							  &
+							  ~
+							  (BPCTLI_CTRL_EXT_MDIO_DATA
+							   |
+							   BPCTLI_CTRL_EXT_MCLK_DATA)));
+	} else {
+
+		//writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+		ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+		ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
+		BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+				(ctrl_ext &
+				 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
+		//BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
+
+	}
+
+	usec_delay(CMND_INTERVAL * 4);
+#ifdef BP_SYNC_FLAG
+	spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
+#else
+	atomic_set(&pbpctl_dev->wdt_busy, 0);
+#endif
+
+	return ctrl_value;
+}
+
+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_c = get_status_port_fn(pbpctl_dev)))
+			return -1;
+	}
+
+	if (pbpctl_dev->bp_10g9) {
+		ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
+		ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
+
+		/* 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));
+		BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+				((ctrl | BP10G_MCLK_DIR_OUT9) &
+				 ~(BP10G_MCLK_DATA_OUT9)));
+
+	} else if (pbpctl_dev->bp_fiber5) {
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MCLK_DIR5
+						       |
+						       BPCTLI_CTRL_EXT_MDIO_DIR5)
+						      &
+						      ~
+						      (BPCTLI_CTRL_EXT_MDIO_DATA5
+						       |
+						       BPCTLI_CTRL_EXT_MCLK_DATA5)));
+	} else if (pbpctl_dev->bp_i80) {
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
+		ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MDIO_DIR80)
+						      &
+						      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+				   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
+				    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
+	} else if (pbpctl_dev->bp_540) {
+		ctrl_ext = ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+		BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
+						    BP540_MDIO_DIR) &
+						   ~(BP540_MDIO_DATA |
+						     BP540_MCLK_DATA)));
+	} else if (pbpctl_dev->bp_10gb) {
+		ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
+		BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+				 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
+				 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
+				     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
+
+	} else if (!pbpctl_dev->bp_10g) {
+
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+							   BPCTLI_CTRL_EXT_MCLK_DIR
+							   |
+							   BPCTLI_CTRL_EXT_MDIO_DIR)
+							  &
+							  ~
+							  (BPCTLI_CTRL_EXT_MDIO_DATA
+							   |
+							   BPCTLI_CTRL_EXT_MCLK_DATA)));
+	} else {
+
+		// writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+		ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+		ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
+		BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+				(ctrl_ext &
+				 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
+		//BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
+
+	}
+	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));
+		BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+				(ctrl | BP10G_MCLK_DATA_OUT9 |
+				 BP10G_MCLK_DIR_OUT9));
+
+	} else if (pbpctl_dev->bp_fiber5) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MCLK_DIR5
+						       |
+						       BPCTLI_CTRL_EXT_MDIO_DIR5
+						       |
+						       BPCTLI_CTRL_EXT_MCLK_DATA5)
+						      &
+						      ~
+						      (BPCTLI_CTRL_EXT_MDIO_DATA5)));
+	} else if (pbpctl_dev->bp_i80) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MDIO_DIR80)
+						      &
+						      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+				   (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 |
+				    BPCTLI_CTRL_EXT_MCLK_DATA80));
+
+	} else if (pbpctl_dev->bp_540) {
+		BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |
+						    BP540_MDIO_DIR |
+						    BP540_MCLK_DIR |
+						    BP540_MCLK_DATA) &
+						   ~BP540_MDIO_DATA));
+
+	} else if (pbpctl_dev->bp_10gb) {
+		ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
+
+		BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+				 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_SET)
+				 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
+				     BP10GB_MDIO_SET | BP10GB_MCLK_CLR));
+
+	} else if (!pbpctl_dev->bp_10g)
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+							   BPCTLI_CTRL_EXT_MCLK_DIR
+							   |
+							   BPCTLI_CTRL_EXT_MDIO_DIR
+							   |
+							   BPCTLI_CTRL_EXT_MCLK_DATA)
+							  &
+							  ~
+							  (BPCTLI_CTRL_EXT_MDIO_DATA)));
+	else {
+
+		//writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+		BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+				((ctrl_ext | BP10G_MCLK_DATA_OUT) &
+				 ~BP10G_MDIO_DATA_OUT));
+		//BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
+
+	}
+
+	usec_delay(WDT_INTERVAL);
+	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));
+		BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
+				((ctrl | BP10G_MCLK_DIR_OUT9) &
+				 ~(BP10G_MCLK_DATA_OUT9)));
+
+	} else if (pbpctl_dev->bp_fiber5) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MCLK_DIR5
+						       |
+						       BPCTLI_CTRL_EXT_MDIO_DIR5)
+						      &
+						      ~
+						      (BPCTLI_CTRL_EXT_MCLK_DATA5
+						       |
+						       BPCTLI_CTRL_EXT_MDIO_DATA5)));
+	} else if (pbpctl_dev->bp_i80) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
+						       BPCTLI_CTRL_EXT_MDIO_DIR80)
+						      &
+						      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+				   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
+				    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
+
+	} else if (pbpctl_dev->bp_540) {
+		BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
+						    BP540_MDIO_DIR) &
+						   ~(BP540_MDIO_DATA |
+						     BP540_MCLK_DATA)));
+
+	} else if (pbpctl_dev->bp_10gb) {
+		ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
+		BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
+				 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
+				 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
+				     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
+
+	} else if (!pbpctl_dev->bp_10g)
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+							   BPCTLI_CTRL_EXT_MCLK_DIR
+							   |
+							   BPCTLI_CTRL_EXT_MDIO_DIR)
+							  &
+							  ~
+							  (BPCTLI_CTRL_EXT_MCLK_DATA
+							   |
+							   BPCTLI_CTRL_EXT_MDIO_DATA)));
+	else {
+
+		//writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+		BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+				(ctrl_ext &
+				 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
+		//BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
+	}
+	if ((pbpctl_dev->wdt_status == WDT_STATUS_EN)	/*&&
+							   (pbpctl_dev->bp_ext_ver<PXG4BPFI_VER) */ )
+		pbpctl_dev->bypass_wdt_on_time = jiffies;
+#ifdef BP_SYNC_FLAG
+	spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
+#endif
+	usec_delay(CMND_INTERVAL * 4);
+	return 0;
+}
+
+static void data_pulse(bpctl_dev_t * pbpctl_dev, unsigned char value)
+{
+
+	uint32_t ctrl_ext = 0;
+#ifdef BP_SYNC_FLAG
+	unsigned long flags;
+#endif
+	wdt_time_left(pbpctl_dev);
+#ifdef BP_SYNC_FLAG
+	spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags);
+#else
+	atomic_set(&pbpctl_dev->wdt_busy, 1);
+#endif
+
+	ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+						   BPCTLI_CTRL_EXT_SDP6_DIR |
+						   BPCTLI_CTRL_EXT_SDP7_DIR) &
+						  ~(BPCTLI_CTRL_EXT_SDP6_DATA |
+						    BPCTLI_CTRL_EXT_SDP7_DATA)));
+
+	usec_delay(INIT_CMND_INTERVAL);
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+						   BPCTLI_CTRL_EXT_SDP6_DIR |
+						   BPCTLI_CTRL_EXT_SDP7_DIR |
+						   BPCTLI_CTRL_EXT_SDP6_DATA) &
+						  ~
+						  (BPCTLI_CTRL_EXT_SDP7_DATA)));
+	usec_delay(INIT_CMND_INTERVAL);
+
+	while (value) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |
+				   BPCTLI_CTRL_EXT_SDP6_DIR |
+				   BPCTLI_CTRL_EXT_SDP7_DIR |
+				   BPCTLI_CTRL_EXT_SDP6_DATA |
+				   BPCTLI_CTRL_EXT_SDP7_DATA);
+		usec_delay(PULSE_INTERVAL);
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+							   BPCTLI_CTRL_EXT_SDP6_DIR
+							   |
+							   BPCTLI_CTRL_EXT_SDP7_DIR
+							   |
+							   BPCTLI_CTRL_EXT_SDP6_DATA)
+							  &
+							  ~BPCTLI_CTRL_EXT_SDP7_DATA));
+		usec_delay(PULSE_INTERVAL);
+		value--;
+
+	}
+	usec_delay(INIT_CMND_INTERVAL - PULSE_INTERVAL);
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+						   BPCTLI_CTRL_EXT_SDP6_DIR |
+						   BPCTLI_CTRL_EXT_SDP7_DIR) &
+						  ~(BPCTLI_CTRL_EXT_SDP6_DATA |
+						    BPCTLI_CTRL_EXT_SDP7_DATA)));
+	usec_delay(WDT_TIME_CNT);
+	if (pbpctl_dev->wdt_status == WDT_STATUS_EN)
+		pbpctl_dev->bypass_wdt_on_time = jiffies;
+#ifdef BP_SYNC_FLAG
+	spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
+#else
+	atomic_set(&pbpctl_dev->wdt_busy, 0);
+#endif
+
+}
+
+static int send_wdt_pulse(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t ctrl_ext = 0;
+
+#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
+	wdt_time_left(pbpctl_dev);
+	ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |	/* 1 */
+			   BPCTLI_CTRL_EXT_SDP7_DIR |
+			   BPCTLI_CTRL_EXT_SDP7_DATA);
+	usec_delay(PULSE_INTERVAL);
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |	/* 0 */
+						   BPCTLI_CTRL_EXT_SDP7_DIR) &
+						  ~BPCTLI_CTRL_EXT_SDP7_DATA));
+
+	usec_delay(PULSE_INTERVAL);
+	if (pbpctl_dev->wdt_status == WDT_STATUS_EN)
+		pbpctl_dev->bypass_wdt_on_time = jiffies;
+#ifdef BP_SYNC_FLAG
+	spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
+#endif
+
+	return 0;
+}
+
+void send_bypass_clear_pulse(bpctl_dev_t * pbpctl_dev, unsigned int value)
+{
+	uint32_t ctrl_ext = 0;
+
+	ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |	/* 0 */
+						   BPCTLI_CTRL_EXT_SDP6_DIR) &
+						  ~BPCTLI_CTRL_EXT_SDP6_DATA));
+
+	usec_delay(PULSE_INTERVAL);
+	while (value) {
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |	/* 1 */
+				   BPCTLI_CTRL_EXT_SDP6_DIR |
+				   BPCTLI_CTRL_EXT_SDP6_DATA);
+		usec_delay(PULSE_INTERVAL);
+		value--;
+	}
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |	/* 0 */
+						   BPCTLI_CTRL_EXT_SDP6_DIR) &
+						  ~BPCTLI_CTRL_EXT_SDP6_DATA));
+	usec_delay(PULSE_INTERVAL);
+}
+
+/*  #endif  OLD_FW */
+#ifdef BYPASS_DEBUG
+
+int pulse_set_fn(bpctl_dev_t * pbpctl_dev, unsigned int counter)
+{
+	uint32_t ctrl_ext = 0;
+
+	if (!pbpctl_dev)
+		return -1;
+
+	ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+	write_pulse_1(pbpctl_dev, ctrl_ext, counter, counter);
+
+	pbpctl_dev->bypass_wdt_status = 0;
+	if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+		write_pulse_1(pbpctl_dev, ctrl_ext, counter, counter);
+	} else {
+		wdt_time_left(pbpctl_dev);
+		if (pbpctl_dev->wdt_status == WDT_STATUS_EN) {
+			pbpctl_dev->wdt_status = 0;
+			data_pulse(pbpctl_dev, counter);
+			pbpctl_dev->wdt_status = WDT_STATUS_EN;
+			pbpctl_dev->bypass_wdt_on_time = jiffies;
+
+		} else
+			data_pulse(pbpctl_dev, counter);
+	}
+
+	return 0;
+}
+
+int zero_set_fn(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t ctrl_ext = 0, ctrl_value = 0;
+	if (!pbpctl_dev)
+		return -1;
+
+	if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+		printk("zero_set");
+
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+
+		BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+							   BPCTLI_CTRL_EXT_MCLK_DIR)
+							  &
+							  ~
+							  (BPCTLI_CTRL_EXT_MCLK_DATA
+							   |
+							   BPCTLI_CTRL_EXT_MDIO_DIR
+							   |
+							   BPCTLI_CTRL_EXT_MDIO_DATA)));
+
+	}
+	return ctrl_value;
+}
+
+int pulse_get2_fn(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t ctrl_ext = 0, ctrl_value = 0;
+	if (!pbpctl_dev)
+		return -1;
+
+	if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+		printk("pulse_get_fn\n");
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+		ctrl_value = read_pulse_2(pbpctl_dev, ctrl_ext);
+		printk("read:%d\n", ctrl_value);
+	}
+	return ctrl_value;
+}
+
+int pulse_get1_fn(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t ctrl_ext = 0, ctrl_value = 0;
+	if (!pbpctl_dev)
+		return -1;
+
+	if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+
+		printk("pulse_get_fn\n");
+
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+		ctrl_value = read_pulse_1(pbpctl_dev, ctrl_ext);
+		printk("read:%d\n", ctrl_value);
+	}
+	return ctrl_value;
+}
+
+int gpio6_set_fn(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t ctrl_ext = 0;
+
+	ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |
+			   BPCTLI_CTRL_EXT_SDP6_DIR |
+			   BPCTLI_CTRL_EXT_SDP6_DATA);
+	return 0;
+}
+
+int gpio7_set_fn(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t ctrl_ext = 0;
+
+	ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |
+			   BPCTLI_CTRL_EXT_SDP7_DIR |
+			   BPCTLI_CTRL_EXT_SDP7_DATA);
+	return 0;
+}
+
+int gpio7_clear_fn(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t ctrl_ext = 0;
+
+	ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+						   BPCTLI_CTRL_EXT_SDP7_DIR) &
+						  ~BPCTLI_CTRL_EXT_SDP7_DATA));
+	return 0;
+}
+
+int gpio6_clear_fn(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t ctrl_ext = 0;
+
+	ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
+						   BPCTLI_CTRL_EXT_SDP6_DIR) &
+						  ~BPCTLI_CTRL_EXT_SDP6_DATA));
+	return 0;
+}
+#endif				/*BYPASS_DEBUG */
+
+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->func == 0) || (pbpctl_dev->func == 2)) {
+		for (idx_dev = 0;
+		     ((bpctl_dev_arr[idx_dev].pdev != NULL)
+		      && (idx_dev < device_num)); 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 == 1)
+				&& (pbpctl_dev->func == 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]));
+			}
+		}
+	}
+	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->func == 1) || (pbpctl_dev->func == 3)) {
+		for (idx_dev = 0;
+		     ((bpctl_dev_arr[idx_dev].pdev != NULL)
+		      && (idx_dev < device_num)); 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 == 0)
+				&& (pbpctl_dev->func == 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 NULL;
+}
+
+/**************************************/
+/**************INTEL API***************/
+/**************************************/
+
+static void write_data_port_int(bpctl_dev_t * pbpctl_dev,
+				unsigned char ctrl_value)
+{
+	uint32_t value;
+
+	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;
+	value |= ((ctrl_value & 0x1) << BPCTLI_CTRL_SDP0_SHIFT);
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value);
+
+	value = (BPCTL_READ_REG(pbpctl_dev, CTRL_EXT));
+/* Make SDP2 Pin Directonality to Output */
+	value |= BPCTLI_CTRL_EXT_SDP6_DIR;
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, value);
+
+	value &= ~BPCTLI_CTRL_EXT_SDP6_DATA;
+	value |= (((ctrl_value & 0x2) >> 1) << BPCTLI_CTRL_EXT_SDP6_SHIFT);
+	BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, value);
+
+}
+
+static int write_data_int(bpctl_dev_t * pbpctl_dev, unsigned char value)
+{
+	bpctl_dev_t *pbpctl_dev_b = NULL;
+
+	if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev)))
+		return -1;
+	atomic_set(&pbpctl_dev->wdt_busy, 1);
+	write_data_port_int(pbpctl_dev, value & 0x3);
+	write_data_port_int(pbpctl_dev_b, ((value & 0xc) >> 2));
+	atomic_set(&pbpctl_dev->wdt_busy, 0);
+
+	return 0;
+}
+
+static int wdt_pulse_int(bpctl_dev_t * pbpctl_dev)
+{
+
+	if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)
+		return -1;
+
+	if ((write_data_int(pbpctl_dev, RESET_WDT_INT)) < 0)
+		return -1;
+	msec_delay_bp(CMND_INTERVAL_INT);
+	if ((write_data_int(pbpctl_dev, CMND_OFF_INT)) < 0)
+		return -1;
+	msec_delay_bp(CMND_INTERVAL_INT);
+
+	if (pbpctl_dev->wdt_status == WDT_STATUS_EN)
+		pbpctl_dev->bypass_wdt_on_time = jiffies;
+
+	return 0;
+}
+
+/*************************************/
+/************* COMMANDS **************/
+/*************************************/
+
+/* CMND_ON  0x4 (100)*/
+int cmnd_on(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+
+	if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
+			return 0;
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
+			write_data(pbpctl_dev, CMND_ON);
+		else
+			data_pulse(pbpctl_dev, CMND_ON);
+		ret = 0;
+	}
+	return ret;
+}
+
+/* CMND_OFF  0x2 (10)*/
+int cmnd_off(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+
+	if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
+			write_data_int(pbpctl_dev, CMND_OFF_INT);
+			msec_delay_bp(CMND_INTERVAL_INT);
+		} else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
+			write_data(pbpctl_dev, CMND_OFF);
+		else
+			data_pulse(pbpctl_dev, CMND_OFF);
+		ret = 0;
+	};
+	return ret;
+}
+
+/* BYPASS_ON (0xa)*/
+int bypass_on(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+
+	if (pbpctl_dev->bp_caps & BP_CAP) {
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
+			write_data_int(pbpctl_dev, BYPASS_ON_INT);
+			msec_delay_bp(BYPASS_DELAY_INT);
+			pbpctl_dev->bp_status_un = 0;
+		} else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			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;
+	};
+	return ret;
+}
+
+/* BYPASS_OFF (0x8 111)*/
+int bypass_off(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+
+	if (pbpctl_dev->bp_caps & BP_CAP) {
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
+			write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
+			msec_delay_bp(BYPASS_DELAY_INT);
+			write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT);
+			msec_delay_bp(BYPASS_DELAY_INT);
+			pbpctl_dev->bp_status_un = 0;
+		} else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			write_data(pbpctl_dev, BYPASS_OFF);
+			if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
+				msec_delay_bp(LATCH_DELAY);
+		} else
+			data_pulse(pbpctl_dev, BYPASS_OFF);
+		ret = 0;
+	}
+	return ret;
+}
+
+/* TAP_OFF (0x9)*/
+int tap_off(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+	if ((pbpctl_dev->bp_caps & TAP_CAP)
+	    && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) {
+		write_data(pbpctl_dev, TAP_OFF);
+		msec_delay_bp(LATCH_DELAY);
+		ret = 0;
+	};
+	return ret;
+}
+
+/* TAP_ON (0xb)*/
+int tap_on(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+	if ((pbpctl_dev->bp_caps & TAP_CAP)
+	    && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) {
+		write_data(pbpctl_dev, TAP_ON);
+		msec_delay_bp(LATCH_DELAY);
+		ret = 0;
+	};
+	return ret;
+}
+
+/* DISC_OFF (0x9)*/
+int disc_off(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+	if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) {
+		write_data(pbpctl_dev, DISC_OFF);
+		msec_delay_bp(LATCH_DELAY);
+	} else
+		ret = BP_NOT_CAP;
+	return ret;
+}
+
+/* DISC_ON (0xb)*/
+int disc_on(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+	if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) {
+		write_data(pbpctl_dev, /*DISC_ON */ 0x85);
+		msec_delay_bp(LATCH_DELAY);
+	} else
+		ret = BP_NOT_CAP;
+	return ret;
+}
+
+/* DISC_PORT_ON */
+int disc_port_on(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+	bpctl_dev_t *pbpctl_dev_m;
+
+	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 == NULL)
+		return BP_NOT_CAP;
+
+	if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
+		if (is_bypass_fn(pbpctl_dev) == 1) {
+
+			write_data(pbpctl_dev_m, TX_DISA);
+		} else {
+
+			write_data(pbpctl_dev_m, TX_DISB);
+		}
+
+		msec_delay_bp(LATCH_DELAY);
+
+	}
+	return ret;
+}
+
+/* DISC_PORT_OFF */
+int disc_port_off(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+	bpctl_dev_t *pbpctl_dev_m;
+
+	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 == NULL)
+		return BP_NOT_CAP;
+
+	if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
+		if (is_bypass_fn(pbpctl_dev) == 1)
+			write_data(pbpctl_dev_m, TX_ENA);
+		else
+			write_data(pbpctl_dev_m, TX_ENB);
+
+		msec_delay_bp(LATCH_DELAY);
+
+	}
+	return ret;
+}
+
+/*TWO_PORT_LINK_HW_EN (0xe)*/
+int tpl_hw_on(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0, ctrl = 0;
+	bpctl_dev_t *pbpctl_dev_b = NULL;
+
+	if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev)))
+		return BP_NOT_CAP;
+
+	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);
+		cmnd_off(pbpctl_dev);
+		return ret;
+	}
+
+	if (TPL_IF_SERIES(pbpctl_dev->subdevice)) {
+		ctrl = BPCTL_READ_REG(pbpctl_dev_b, CTRL);
+		BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL,
+				   ((ctrl | BPCTLI_CTRL_SWDPIO0) &
+				    ~BPCTLI_CTRL_SWDPIN0));
+	} else
+		ret = BP_NOT_CAP;
+	return ret;
+}
+
+/*TWO_PORT_LINK_HW_DIS (0xc)*/
+int tpl_hw_off(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0, ctrl = 0;
+	bpctl_dev_t *pbpctl_dev_b = NULL;
+
+	if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev)))
+		return BP_NOT_CAP;
+	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);
+		cmnd_off(pbpctl_dev);
+		return ret;
+	}
+	if (TPL_IF_SERIES(pbpctl_dev->subdevice)) {
+		ctrl = BPCTL_READ_REG(pbpctl_dev_b, CTRL);
+		BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL,
+				   (ctrl | BPCTLI_CTRL_SWDPIO0 |
+				    BPCTLI_CTRL_SWDPIN0));
+	} else
+		ret = BP_NOT_CAP;
+	return ret;
+}
+
+/* WDT_OFF (0x6 110)*/
+int wdt_off(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+
+	if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
+			bypass_off(pbpctl_dev);
+		} else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
+			write_data(pbpctl_dev, WDT_OFF);
+		else
+			data_pulse(pbpctl_dev, WDT_OFF);
+		pbpctl_dev->wdt_status = WDT_STATUS_DIS;
+		ret = 0;
+	};
+	return ret;
+}
+
+/* WDT_ON (0x10)*/
+
+/***Global***/
+static unsigned int
+    wdt_val_array[] = { 1000, 1500, 2000, 3000, 4000, 8000, 16000, 32000, 0 };
+
+int wdt_on(bpctl_dev_t * pbpctl_dev, unsigned int timeout)
+{
+
+	if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
+		unsigned int pulse = 0, temp_value = 0, temp_cnt = 0;
+		pbpctl_dev->wdt_status = 0;
+
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
+			for (; wdt_val_array[temp_cnt]; temp_cnt++)
+				if (timeout <= wdt_val_array[temp_cnt])
+					break;
+
+			if (!wdt_val_array[temp_cnt])
+				temp_cnt--;
+
+			timeout = wdt_val_array[temp_cnt];
+			temp_cnt += 0x7;
+
+			write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
+			msec_delay_bp(BYPASS_DELAY_INT);
+			pbpctl_dev->bp_status_un = 0;
+			write_data_int(pbpctl_dev, temp_cnt);
+			pbpctl_dev->bypass_wdt_on_time = jiffies;
+			msec_delay_bp(CMND_INTERVAL_INT);
+			pbpctl_dev->bypass_timer_interval = timeout;
+		} else {
+			timeout =
+			    (timeout <
+			     TIMEOUT_UNIT ? TIMEOUT_UNIT : (timeout >
+							    WDT_TIMEOUT_MAX ?
+							    WDT_TIMEOUT_MAX :
+							    timeout));
+			temp_value = timeout / 100;
+			while ((temp_value >>= 1))
+				temp_cnt++;
+			if (timeout > ((1 << temp_cnt) * 100))
+				temp_cnt++;
+			pbpctl_dev->bypass_wdt_on_time = jiffies;
+			pulse = (WDT_ON | temp_cnt);
+			if (pbpctl_dev->bp_ext_ver == OLD_IF_VER)
+				data_pulse(pbpctl_dev, pulse);
+			else
+				write_data(pbpctl_dev, pulse);
+			pbpctl_dev->bypass_timer_interval =
+			    (1 << temp_cnt) * 100;
+		}
+		pbpctl_dev->wdt_status = WDT_STATUS_EN;
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+void bp75_put_hw_semaphore_generic(bpctl_dev_t * pbpctl_dev)
+{
+	u32 swsm;
+
+	swsm = BPCTL_READ_REG(pbpctl_dev, SWSM);
+
+	swsm &= ~(BPCTLI_SWSM_SMBI | BPCTLI_SWSM_SWESMBI);
+
+	BPCTL_WRITE_REG(pbpctl_dev, SWSM, swsm);
+}
+
+s32 bp75_get_hw_semaphore_generic(bpctl_dev_t * pbpctl_dev)
+{
+	u32 swsm;
+	s32 ret_val = 0;
+	s32 timeout = 8192 + 1;
+	s32 i = 0;
+
+	/* Get the SW semaphore */
+	while (i < timeout) {
+		swsm = BPCTL_READ_REG(pbpctl_dev, SWSM);
+		if (!(swsm & BPCTLI_SWSM_SMBI))
+			break;
+
+		usec_delay(50);
+		i++;
+	}
+
+	if (i == timeout) {
+		printk
+		    ("bpctl_mod: Driver can't access device - SMBI bit is set.\n");
+		ret_val = -1;
+		goto out;
+	}
+
+	/* Get the FW semaphore. */
+	for (i = 0; i < timeout; i++) {
+		swsm = BPCTL_READ_REG(pbpctl_dev, SWSM);
+		BPCTL_WRITE_REG(pbpctl_dev, SWSM, swsm | BPCTLI_SWSM_SWESMBI);
+
+		/* Semaphore acquired if bit latched */
+		if (BPCTL_READ_REG(pbpctl_dev, SWSM) & BPCTLI_SWSM_SWESMBI)
+			break;
+
+		usec_delay(50);
+	}
+
+	if (i == timeout) {
+		/* Release semaphores */
+		bp75_put_hw_semaphore_generic(pbpctl_dev);
+		printk("bpctl_mod: Driver can't access the NVM\n");
+		ret_val = -1;
+		goto out;
+	}
+
+ out:
+	return ret_val;
+}
+
+static void bp75_release_phy(bpctl_dev_t * pbpctl_dev)
+{
+	u16 mask = BPCTLI_SWFW_PHY0_SM;
+	u32 swfw_sync;
+
+	if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3))
+		mask = BPCTLI_SWFW_PHY1_SM;
+
+	while (bp75_get_hw_semaphore_generic(pbpctl_dev) != 0) ;
+	/* Empty */
+
+	swfw_sync = BPCTL_READ_REG(pbpctl_dev, SW_FW_SYNC);
+	swfw_sync &= ~mask;
+	BPCTL_WRITE_REG(pbpctl_dev, SW_FW_SYNC, swfw_sync);
+
+	bp75_put_hw_semaphore_generic(pbpctl_dev);
+}
+
+static s32 bp75_acquire_phy(bpctl_dev_t * pbpctl_dev)
+{
+	u16 mask = BPCTLI_SWFW_PHY0_SM;
+	u32 swfw_sync;
+	u32 swmask;
+	u32 fwmask;
+	s32 ret_val = 0;
+	s32 i = 0, timeout = 200;
+
+	if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3))
+		mask = BPCTLI_SWFW_PHY1_SM;
+
+	swmask = mask;
+	fwmask = mask << 16;
+
+	while (i < timeout) {
+		if (bp75_get_hw_semaphore_generic(pbpctl_dev)) {
+			ret_val = -1;
+			goto out;
+		}
+
+		swfw_sync = BPCTL_READ_REG(pbpctl_dev, SW_FW_SYNC);
+		if (!(swfw_sync & (fwmask | swmask)))
+			break;
+
+		bp75_put_hw_semaphore_generic(pbpctl_dev);
+		mdelay(5);
+		i++;
+	}
+
+	if (i == timeout) {
+		printk
+		    ("bpctl_mod: Driver can't access resource, SW_FW_SYNC timeout.\n");
+		ret_val = -1;
+		goto out;
+	}
+
+	swfw_sync |= swmask;
+	BPCTL_WRITE_REG(pbpctl_dev, SW_FW_SYNC, swfw_sync);
+
+	bp75_put_hw_semaphore_generic(pbpctl_dev);
+
+ out:
+	return ret_val;
+}
+
+s32 bp75_read_phy_reg_mdic(bpctl_dev_t * pbpctl_dev, u32 offset, u16 * data)
+{
+	u32 i, mdic = 0;
+	s32 ret_val = 0;
+	u32 phy_addr = 1;
+
+	mdic = ((offset << BPCTLI_MDIC_REG_SHIFT) |
+		(phy_addr << BPCTLI_MDIC_PHY_SHIFT) | (BPCTLI_MDIC_OP_READ));
+
+	BPCTL_WRITE_REG(pbpctl_dev, MDIC, mdic);
+
+	for (i = 0; i < (BPCTLI_GEN_POLL_TIMEOUT * 3); i++) {
+		usec_delay(50);
+		mdic = BPCTL_READ_REG(pbpctl_dev, MDIC);
+		if (mdic & BPCTLI_MDIC_READY)
+			break;
+	}
+	if (!(mdic & BPCTLI_MDIC_READY)) {
+		printk("bpctl_mod: MDI Read did not complete\n");
+		ret_val = -1;
+		goto out;
+	}
+	if (mdic & BPCTLI_MDIC_ERROR) {
+		printk("bpctl_mod: MDI Error\n");
+		ret_val = -1;
+		goto out;
+	}
+	*data = (u16) mdic;
+
+ out:
+	return ret_val;
+}
+
+s32 bp75_write_phy_reg_mdic(bpctl_dev_t * pbpctl_dev, u32 offset, u16 data)
+{
+	u32 i, mdic = 0;
+	s32 ret_val = 0;
+	u32 phy_addr = 1;
+
+	mdic = (((u32) data) |
+		(offset << BPCTLI_MDIC_REG_SHIFT) |
+		(phy_addr << BPCTLI_MDIC_PHY_SHIFT) | (BPCTLI_MDIC_OP_WRITE));
+
+	BPCTL_WRITE_REG(pbpctl_dev, MDIC, mdic);
+
+	for (i = 0; i < (BPCTLI_GEN_POLL_TIMEOUT * 3); i++) {
+		usec_delay(50);
+		mdic = BPCTL_READ_REG(pbpctl_dev, MDIC);
+		if (mdic & BPCTLI_MDIC_READY)
+			break;
+	}
+	if (!(mdic & BPCTLI_MDIC_READY)) {
+		printk("bpctl_mod: MDI Write did not complete\n");
+		ret_val = -1;
+		goto out;
+	}
+	if (mdic & BPCTLI_MDIC_ERROR) {
+		printk("bpctl_mod: MDI Error\n");
+		ret_val = -1;
+		goto out;
+	}
+
+ out:
+	return ret_val;
+}
+
+static s32 bp75_read_phy_reg(bpctl_dev_t * pbpctl_dev, u32 offset, u16 * data)
+{
+	s32 ret_val = 0;
+
+	ret_val = bp75_acquire_phy(pbpctl_dev);
+	if (ret_val)
+		goto out;
+
+	if (offset > BPCTLI_MAX_PHY_MULTI_PAGE_REG) {
+		ret_val = bp75_write_phy_reg_mdic(pbpctl_dev,
+						  BPCTLI_IGP01E1000_PHY_PAGE_SELECT,
+						  (u16) offset);
+		if (ret_val)
+			goto release;
+	}
+
+	ret_val =
+	    bp75_read_phy_reg_mdic(pbpctl_dev,
+				   BPCTLI_MAX_PHY_REG_ADDRESS & offset, data);
+
+ release:
+	bp75_release_phy(pbpctl_dev);
+ out:
+	return ret_val;
+}
+
+static s32 bp75_write_phy_reg(bpctl_dev_t * pbpctl_dev, u32 offset, u16 data)
+{
+	s32 ret_val = 0;
+
+	ret_val = bp75_acquire_phy(pbpctl_dev);
+	if (ret_val)
+		goto out;
+
+	if (offset > BPCTLI_MAX_PHY_MULTI_PAGE_REG) {
+		ret_val = bp75_write_phy_reg_mdic(pbpctl_dev,
+						  BPCTLI_IGP01E1000_PHY_PAGE_SELECT,
+						  (u16) offset);
+		if (ret_val)
+			goto release;
+	}
+
+	ret_val =
+	    bp75_write_phy_reg_mdic(pbpctl_dev,
+				    BPCTLI_MAX_PHY_REG_ADDRESS & offset, data);
+
+ release:
+	bp75_release_phy(pbpctl_dev);
+
+ out:
+	return ret_val;
+}
+
+/* SET_TX  (non-Bypass command :)) */
+static int set_tx(bpctl_dev_t * pbpctl_dev, int tx_state)
+{
+	int ret = 0, ctrl = 0;
+	bpctl_dev_t *pbpctl_dev_m;
+	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 == NULL)
+		return BP_NOT_CAP;
+	if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
+		ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
+		if (!tx_state) {
+			if (pbpctl_dev->bp_540) {
+				ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						(ctrl | BP10G_SDP1_DIR |
+						 BP10G_SDP1_DATA));
+
+			} else {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+						   (ctrl | BPCTLI_CTRL_SDP1_DIR
+						    | BPCTLI_CTRL_SWDPIN1));
+			}
+		} else {
+			if (pbpctl_dev->bp_540) {
+				ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						((ctrl | BP10G_SDP1_DIR) &
+						 ~BP10G_SDP1_DATA));
+			} else {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+						   ((ctrl |
+						     BPCTLI_CTRL_SDP1_DIR) &
+						    ~BPCTLI_CTRL_SWDPIN1));
+			}
+			return ret;
+
+		}
+	} else if (pbpctl_dev->bp_caps & TX_CTL_CAP) {
+		if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) {
+			if (tx_state) {
+				uint16_t mii_reg;
+				if (!
+				    (ret =
+				     bp75_read_phy_reg(pbpctl_dev,
+						       BPCTLI_PHY_CONTROL,
+						       &mii_reg))) {
+					if (mii_reg & BPCTLI_MII_CR_POWER_DOWN) {
+						ret =
+						    bp75_write_phy_reg
+						    (pbpctl_dev,
+						     BPCTLI_PHY_CONTROL,
+						     mii_reg &
+						     ~BPCTLI_MII_CR_POWER_DOWN);
+					}
+				}
+			} else {
+				uint16_t mii_reg;
+				if (!
+				    (ret =
+				     bp75_read_phy_reg(pbpctl_dev,
+						       BPCTLI_PHY_CONTROL,
+						       &mii_reg))) {
+
+					mii_reg |= BPCTLI_MII_CR_POWER_DOWN;
+					ret =
+					    bp75_write_phy_reg(pbpctl_dev,
+							       BPCTLI_PHY_CONTROL,
+							       mii_reg);
+				}
+			}
+
+		}
+		if (pbpctl_dev->bp_fiber5) {
+			ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+
+		} else if (pbpctl_dev->bp_10gb)
+			ctrl = BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
+
+		else if (!pbpctl_dev->bp_10g)
+			ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
+		else
+			//ctrl =readl((void *)((pbpctl_dev)->mem_map) + 0x20);
+			ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+
+		if (!tx_state)
+			if (pbpctl_dev->bp_10g9) {
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						(ctrl | BP10G_SDP3_DATA |
+						 BP10G_SDP3_DIR));
+
+			} else if (pbpctl_dev->bp_fiber5) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+						   (ctrl |
+						    BPCTLI_CTRL_EXT_SDP6_DIR |
+						    BPCTLI_CTRL_EXT_SDP6_DATA));
+
+			} else if (pbpctl_dev->bp_10gb) {
+				if ((pbpctl_dev->func == 1)
+				    || (pbpctl_dev->func == 3))
+					BP10GB_WRITE_REG(pbpctl_dev,
+							 MISC_REG_GPIO,
+							 (ctrl |
+							  BP10GB_GPIO0_SET_P1) &
+							 ~(BP10GB_GPIO0_CLR_P1 |
+							   BP10GB_GPIO0_OE_P1));
+				else
+					BP10GB_WRITE_REG(pbpctl_dev,
+							 MISC_REG_GPIO,
+							 (ctrl |
+							  BP10GB_GPIO0_OE_P0 |
+							  BP10GB_GPIO0_SET_P0));
+
+			} else if (pbpctl_dev->bp_i80) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+						   (ctrl | BPCTLI_CTRL_SDP1_DIR
+						    | BPCTLI_CTRL_SWDPIN1));
+
+			} else if (pbpctl_dev->bp_540) {
+				ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						(ctrl | BP10G_SDP1_DIR |
+						 BP10G_SDP1_DATA));
+
+			}
+
+			else if (!pbpctl_dev->bp_10g)
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+						   (ctrl | BPCTLI_CTRL_SWDPIO0 |
+						    BPCTLI_CTRL_SWDPIN0));
+
+			else
+				//writel((ctrl|(0x1|0x100)), (void *)(((pbpctl_dev)->mem_map) + 0x20)) ;
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						(ctrl | BP10G_SDP0_DATA |
+						 BP10G_SDP0_DIR));
+
+		else {
+			if (pbpctl_dev->bp_10g9) {
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						((ctrl | BP10G_SDP3_DIR) &
+						 ~BP10G_SDP3_DATA));
+
+			} else if (pbpctl_dev->bp_fiber5) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
+						   ((ctrl |
+						     BPCTLI_CTRL_EXT_SDP6_DIR) &
+						    ~BPCTLI_CTRL_EXT_SDP6_DATA));
+
+			} else if (pbpctl_dev->bp_10gb) {
+				if ((bpctl_dev_arr->func == 1)
+				    || (bpctl_dev_arr->func == 3))
+					BP10GB_WRITE_REG(pbpctl_dev,
+							 MISC_REG_GPIO,
+							 (ctrl |
+							  BP10GB_GPIO0_CLR_P1) &
+							 ~(BP10GB_GPIO0_SET_P1 |
+							   BP10GB_GPIO0_OE_P1));
+				else
+					BP10GB_WRITE_REG(pbpctl_dev,
+							 MISC_REG_GPIO,
+							 (ctrl |
+							  BP10GB_GPIO0_OE_P0 |
+							  BP10GB_GPIO0_CLR_P0));
+
+			} else if (pbpctl_dev->bp_i80) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+						   ((ctrl |
+						     BPCTLI_CTRL_SDP1_DIR) &
+						    ~BPCTLI_CTRL_SWDPIN1));
+			} else if (pbpctl_dev->bp_540) {
+				ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						((ctrl | BP10G_SDP1_DIR) &
+						 ~BP10G_SDP1_DATA));
+			}
+
+			else if (!pbpctl_dev->bp_10g) {
+				BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+						   ((ctrl | BPCTLI_CTRL_SWDPIO0)
+						    & ~BPCTLI_CTRL_SWDPIN0));
+				if (!PEGF_IF_SERIES(pbpctl_dev->subdevice)) {
+					BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
+							   (ctrl &
+							    ~
+							    (BPCTLI_CTRL_SDP0_DATA
+							     |
+							     BPCTLI_CTRL_SDP0_DIR)));
+				}
+			} else
+				//writel(((ctrl|0x100)&~0x1), (void *)(((pbpctl_dev)->mem_map) + 0x20)) ;
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						((ctrl | BP10G_SDP0_DIR) &
+						 ~BP10G_SDP0_DATA));
+
+		}
+
+	} else
+		ret = BP_NOT_CAP;
+	return ret;
+
+}
+
+/* SET_FORCE_LINK  (non-Bypass command :)) */
+static int set_bp_force_link(bpctl_dev_t * pbpctl_dev, int tx_state)
+{
+	int ret = 0, ctrl = 0;
+
+	if (DBI_IF_SERIES(pbpctl_dev->subdevice)) {
+
+		if ((pbpctl_dev->bp_10g) || (pbpctl_dev->bp_10g9)) {
+
+			ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
+			if (!tx_state)
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						ctrl & ~BP10G_SDP1_DIR);
+			else
+				BP10G_WRITE_REG(pbpctl_dev, ESDP,
+						((ctrl | BP10G_SDP1_DIR) &
+						 ~BP10G_SDP1_DATA));
+			return ret;
+		}
+
+	}
+	return BP_NOT_CAP;
+}
+
+/*RESET_CONT 0x20 */
+int reset_cont(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+
+	if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
+			return BP_NOT_CAP;
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
+			write_data(pbpctl_dev, RESET_CONT);
+		else
+			data_pulse(pbpctl_dev, RESET_CONT);
+		ret = 0;
+	};
+	return ret;
+}
+
+/*DIS_BYPASS_CAP 0x22 */
+int dis_bypass_cap(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
+			write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
+			msec_delay_bp(BYPASS_DELAY_INT);
+		} else {
+			write_data(pbpctl_dev, BYPASS_OFF);
+			msec_delay_bp(LATCH_DELAY);
+			write_data(pbpctl_dev, DIS_BYPASS_CAP);
+			msec_delay_bp(BYPASS_CAP_DELAY);
+		}
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+/*EN_BYPASS_CAP 0x24 */
+int en_bypass_cap(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
+			write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT);
+			msec_delay_bp(BYPASS_DELAY_INT);
+		} else {
+			write_data(pbpctl_dev, EN_BYPASS_CAP);
+			msec_delay_bp(BYPASS_CAP_DELAY);
+		}
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+/* BYPASS_STATE_PWRON 0x26*/
+int bypass_state_pwron(bpctl_dev_t * pbpctl_dev)
+{
+	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(DFLT_PWRON_DELAY);
+		else
+			msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+/* NORMAL_STATE_PWRON 0x28*/
+int normal_state_pwron(bpctl_dev_t * pbpctl_dev)
+{
+	if ((pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP)
+	    || (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP)) {
+		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);
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+/* BYPASS_STATE_PWROFF 0x27*/
+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);
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+/* NORMAL_STATE_PWROFF 0x29*/
+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);
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+/*TAP_STATE_PWRON 0x2a*/
+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);
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+/*DIS_TAP_CAP 0x2c*/
+int dis_tap_cap(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
+		write_data(pbpctl_dev, DIS_TAP_CAP);
+		msec_delay_bp(BYPASS_CAP_DELAY);
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+/*EN_TAP_CAP 0x2e*/
+int en_tap_cap(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
+		write_data(pbpctl_dev, EN_TAP_CAP);
+		msec_delay_bp(BYPASS_CAP_DELAY);
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+/*DISC_STATE_PWRON 0x2a*/
+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);
+			return BP_OK;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+/*DIS_DISC_CAP 0x2c*/
+int dis_disc_cap(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & DISC_DIS_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= 0x8) {
+			write_data(pbpctl_dev, DIS_DISC_CAP);
+			msec_delay_bp(BYPASS_CAP_DELAY);
+			return BP_OK;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+/*DISC_STATE_PWRON 0x2a*/
+int disc_port_state_pwron(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+	bpctl_dev_t *pbpctl_dev_m;
+
+	return BP_NOT_CAP;
+
+	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 == NULL)
+		return BP_NOT_CAP;
+
+	if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
+		if (is_bypass_fn(pbpctl_dev) == 1)
+			write_data(pbpctl_dev_m, TX_DISA_PWRUP);
+		else
+			write_data(pbpctl_dev_m, TX_DISB_PWRUP);
+
+		msec_delay_bp(LATCH_DELAY);
+
+	}
+	return ret;
+}
+
+int normal_port_state_pwron(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+	bpctl_dev_t *pbpctl_dev_m;
+	return BP_NOT_CAP;
+
+	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 == NULL)
+		return BP_NOT_CAP;
+
+	if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
+		if (is_bypass_fn(pbpctl_dev) == 1)
+			write_data(pbpctl_dev_m, TX_ENA_PWRUP);
+		else
+			write_data(pbpctl_dev_m, TX_ENB_PWRUP);
+
+		msec_delay_bp(LATCH_DELAY);
+
+	}
+	return ret;
+}
+
+/*EN_TAP_CAP 0x2e*/
+int en_disc_cap(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & DISC_DIS_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= 0x8) {
+			write_data(pbpctl_dev, EN_DISC_CAP);
+			msec_delay_bp(BYPASS_CAP_DELAY);
+			return BP_OK;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+int std_nic_on(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & STD_NIC_CAP) {
+
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
+			write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
+			msec_delay_bp(BYPASS_DELAY_INT);
+			pbpctl_dev->bp_status_un = 0;
+			return BP_OK;
+		}
+
+		if (pbpctl_dev->bp_ext_ver >= 0x8) {
+			write_data(pbpctl_dev, STD_NIC_ON);
+			msec_delay_bp(BYPASS_CAP_DELAY);
+			return BP_OK;
+
+		}
+
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			wdt_off(pbpctl_dev);
+
+			if (pbpctl_dev->bp_caps & BP_CAP) {
+				write_data(pbpctl_dev, BYPASS_OFF);
+				msec_delay_bp(LATCH_DELAY);
+			}
+
+			if (pbpctl_dev->bp_caps & TAP_CAP) {
+				write_data(pbpctl_dev, TAP_OFF);
+				msec_delay_bp(LATCH_DELAY);
+			}
+
+			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);
+
+			if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
+				write_data(pbpctl_dev, DIS_BYPASS_CAP);
+				msec_delay_bp(BYPASS_CAP_DELAY);
+			}
+
+			if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
+				write_data(pbpctl_dev, DIS_TAP_CAP);
+				msec_delay_bp(BYPASS_CAP_DELAY);
+
+			}
+			return 0;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+int std_nic_off(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & STD_NIC_CAP) {
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
+			write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT);
+			msec_delay_bp(BYPASS_DELAY_INT);
+			return BP_OK;
+		}
+		if (pbpctl_dev->bp_ext_ver >= 0x8) {
+			write_data(pbpctl_dev, STD_NIC_OFF);
+			msec_delay_bp(BYPASS_CAP_DELAY);
+			return BP_OK;
+
+		}
+
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+
+			if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) {
+				write_data(pbpctl_dev, TAP_STATE_PWRON);
+				msec_delay_bp(LATCH_DELAY + 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);
+				else
+					msec_delay_bp(DFLT_PWRON_DELAY);
+			}
+
+			if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
+				write_data(pbpctl_dev, EN_TAP_CAP);
+				msec_delay_bp(BYPASS_CAP_DELAY);
+			}
+			if (pbpctl_dev->bp_caps & DISC_DIS_CAP) {
+				write_data(pbpctl_dev, EN_DISC_CAP);
+				msec_delay_bp(BYPASS_CAP_DELAY);
+			}
+
+			if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
+				write_data(pbpctl_dev, EN_BYPASS_CAP);
+				msec_delay_bp(BYPASS_CAP_DELAY);
+			}
+
+			return 0;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+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;
+
+	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_msec = jiffies_to_msecs(delta_time);
+		time_left = pbpctl_dev->bypass_timer_interval - delta_time_msec;
+		if (time_left < 0) {
+			time_left = -1;
+			pbpctl_dev->wdt_status = WDT_STATUS_EXP;
+		}
+		break;
+	case WDT_STATUS_EXP:
+		time_left = -1;
+		break;
+	}
+
+	return time_left;
+}
+
+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
+				*time_left = wdt_time_left(pbpctl_dev);
+		}
+
+	} else
+		ret = BP_NOT_CAP;
+	return ret;
+}
+
+static int wdt_timer_reload(bpctl_dev_t * pbpctl_dev)
+{
+
+	int ret = 0;
+
+	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))
+			ret = wdt_pulse_int(pbpctl_dev);
+		else
+			ret = send_wdt_pulse(pbpctl_dev);
+		//if (ret==-1)
+		//    mod_timer(&pbpctl_dev->bp_timer, jiffies+1);
+		return 1;
+	}
+	return BP_NOT_CAP;
+}
+
+static void wd_reset_timer(unsigned long param)
+{
+	bpctl_dev_t *pbpctl_dev = (bpctl_dev_t *) param;
+#ifdef BP_SELF_TEST
+	struct sk_buff *skb_tmp;
+#endif
+
+	if ((pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) &&
+	    ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)) {
+		mod_timer(&pbpctl_dev->bp_timer, jiffies + 1);
+		return;
+	}
+#ifdef BP_SELF_TEST
+
+	if (pbpctl_dev->bp_self_test_flag == 1) {
+		skb_tmp = dev_alloc_skb(BPTEST_DATA_LEN + 2);
+		if ((skb_tmp) && (pbpctl_dev->ndev) && (pbpctl_dev->bp_tx_data)) {
+			memcpy(skb_put(skb_tmp, BPTEST_DATA_LEN),
+			       pbpctl_dev->bp_tx_data, BPTEST_DATA_LEN);
+			skb_tmp->dev = pbpctl_dev->ndev;
+			skb_tmp->protocol =
+			    eth_type_trans(skb_tmp, pbpctl_dev->ndev);
+			skb_tmp->ip_summed = CHECKSUM_UNNECESSARY;
+			netif_receive_skb(skb_tmp);
+			goto bp_timer_reload;
+			return;
+		}
+	}
+#endif
+
+	wdt_timer_reload(pbpctl_dev);
+#ifdef BP_SELF_TEST
+ bp_timer_reload:
+#endif
+	if (pbpctl_dev->reset_time) {
+		mod_timer(&pbpctl_dev->bp_timer,
+			  jiffies + (HZ * pbpctl_dev->reset_time) / 1000);
+	}
+}
+
+//#ifdef PMC_FIX_FLAG
+/*WAIT_AT_PWRUP 0x80   */
+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);
+
+			return BP_OK;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+/*DIS_WAIT_AT_PWRUP       0x81 */
+int bp_wait_at_pwup_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_WAIT_AT_PWUP_DIS);
+			msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
+
+			return BP_OK;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+/*EN_HW_RESET  0x82   */
+
+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);
+
+			return BP_OK;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+/*DIS_HW_RESET             0x83   */
+
+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);
+
+			return BP_OK;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+//#endif /*PMC_FIX_FLAG*/
+
+int wdt_exp_mode(bpctl_dev_t * pbpctl_dev, int mode)
+{
+	uint32_t status_reg = 0, status_reg1 = 0;
+
+	if ((pbpctl_dev->bp_caps & (TAP_STATUS_CAP | DISC_CAP)) &&
+	    (pbpctl_dev->bp_caps & BP_CAP)) {
+		if (pbpctl_dev->bp_ext_ver >= PXE2TBPI_VER) {
+
+			if ((pbpctl_dev->bp_ext_ver >= 0x8) &&
+			    (mode == 2) && (pbpctl_dev->bp_caps & DISC_CAP)) {
+				status_reg1 =
+				    read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR);
+				if (!(status_reg1 & WDTE_DISC_BPN_MASK))
+					write_reg(pbpctl_dev,
+						  status_reg1 |
+						  WDTE_DISC_BPN_MASK,
+						  STATUS_DISC_REG_ADDR);
+				return BP_OK;
+			}
+		}
+		status_reg = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
+
+		if ((mode == 0) && (pbpctl_dev->bp_caps & BP_CAP)) {
+			if (pbpctl_dev->bp_ext_ver >= 0x8) {
+				status_reg1 =
+				    read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR);
+				if (status_reg1 & WDTE_DISC_BPN_MASK)
+					write_reg(pbpctl_dev,
+						  status_reg1 &
+						  ~WDTE_DISC_BPN_MASK,
+						  STATUS_DISC_REG_ADDR);
+			}
+			if (status_reg & WDTE_TAP_BPN_MASK)
+				write_reg(pbpctl_dev,
+					  status_reg & ~WDTE_TAP_BPN_MASK,
+					  STATUS_TAP_REG_ADDR);
+			return BP_OK;
+
+		} else if ((mode == 1) && (pbpctl_dev->bp_caps & TAP_CAP)) {
+			if (!(status_reg & WDTE_TAP_BPN_MASK))
+				write_reg(pbpctl_dev,
+					  status_reg | WDTE_TAP_BPN_MASK,
+					  STATUS_TAP_REG_ADDR);
+			/*else return BP_NOT_CAP; */
+			return BP_OK;
+		}
+
+	}
+	return BP_NOT_CAP;
+}
+
+int bypass_fw_ver(bpctl_dev_t * pbpctl_dev)
+{
+	if (is_bypass_fn(pbpctl_dev))
+		return ((read_reg(pbpctl_dev, VER_REG_ADDR)));
+	else
+		return BP_NOT_CAP;
+}
+
+int bypass_sign_check(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (is_bypass_fn(pbpctl_dev))
+		return (((read_reg(pbpctl_dev, PIC_SIGN_REG_ADDR)) ==
+			 PIC_SIGN_VALUE) ? 1 : 0);
+	else
+		return BP_NOT_CAP;
+}
+
+static int tx_status(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t ctrl = 0;
+	bpctl_dev_t *pbpctl_dev_m;
+	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 == NULL)
+		return BP_NOT_CAP;
+	if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
+
+		ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
+		if (pbpctl_dev->bp_i80)
+			return ((ctrl & BPCTLI_CTRL_SWDPIN1) != 0 ? 0 : 1);
+		if (pbpctl_dev->bp_540) {
+			ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+
+			return ((ctrl & BP10G_SDP1_DATA) != 0 ? 0 : 1);
+		}
+
+	}
+
+	if (pbpctl_dev->bp_caps & TX_CTL_CAP) {
+		if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) {
+			uint16_t mii_reg;
+			if (!
+			    (bp75_read_phy_reg
+			     (pbpctl_dev, BPCTLI_PHY_CONTROL, &mii_reg))) {
+				if (mii_reg & BPCTLI_MII_CR_POWER_DOWN)
+					return 0;
+
+				else
+					return 1;
+			}
+			return -1;
+		}
+
+		if (pbpctl_dev->bp_10g9) {
+			return ((BP10G_READ_REG(pbpctl_dev, ESDP) &
+				 BP10G_SDP3_DATA) != 0 ? 0 : 1);
+
+		} else if (pbpctl_dev->bp_fiber5) {
+			ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+			if (ctrl & BPCTLI_CTRL_EXT_SDP6_DATA)
+				return 0;
+			return 1;
+		} else if (pbpctl_dev->bp_10gb) {
+			ctrl = BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
+			BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO,
+					 (ctrl | BP10GB_GPIO0_OE_P1) &
+					 ~(BP10GB_GPIO0_SET_P1 |
+					   BP10GB_GPIO0_CLR_P1));
+
+			if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3))
+				return (((BP10GB_READ_REG
+					  (pbpctl_dev,
+					   MISC_REG_GPIO)) & BP10GB_GPIO0_P1) !=
+					0 ? 0 : 1);
+			else
+				return (((BP10GB_READ_REG
+					  (pbpctl_dev,
+					   MISC_REG_GPIO)) & BP10GB_GPIO0_P0) !=
+					0 ? 0 : 1);
+		}
+
+		if (!pbpctl_dev->bp_10g) {
+
+			ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
+			if (pbpctl_dev->bp_i80)
+				return ((ctrl & BPCTLI_CTRL_SWDPIN1) !=
+					0 ? 0 : 1);
+			if (pbpctl_dev->bp_540) {
+				ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
+
+				return ((ctrl & BP10G_SDP1_DATA) != 0 ? 0 : 1);
+			}
+
+			return ((ctrl & BPCTLI_CTRL_SWDPIN0) != 0 ? 0 : 1);
+		} else
+			return ((BP10G_READ_REG(pbpctl_dev, ESDP) &
+				 BP10G_SDP0_DATA) != 0 ? 0 : 1);
+
+	}
+	return BP_NOT_CAP;
+}
+
+static int bp_force_link_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (DBI_IF_SERIES(pbpctl_dev->subdevice)) {
+
+		if ((pbpctl_dev->bp_10g) || (pbpctl_dev->bp_10g9)) {
+			return ((BP10G_READ_REG(pbpctl_dev, ESDP) &
+				 BP10G_SDP1_DIR) != 0 ? 1 : 0);
+
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+int bypass_from_last_read(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t ctrl_ext = 0;
+	bpctl_dev_t *pbpctl_dev_b = NULL;
+
+	if ((pbpctl_dev->bp_caps & SW_CTL_CAP)
+	    && (pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) {
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT);
+		BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL_EXT,
+				   (ctrl_ext & ~BPCTLI_CTRL_EXT_SDP7_DIR));
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT);
+		if (ctrl_ext & BPCTLI_CTRL_EXT_SDP7_DATA)
+			return 0;
+		return 1;
+	} else
+		return BP_NOT_CAP;
+}
+
+int bypass_status_clear(bpctl_dev_t * pbpctl_dev)
+{
+	bpctl_dev_t *pbpctl_dev_b = NULL;
+
+	if ((pbpctl_dev->bp_caps & SW_CTL_CAP)
+	    && (pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) {
+
+		send_bypass_clear_pulse(pbpctl_dev_b, 1);
+		return 0;
+	} else
+		return BP_NOT_CAP;
+}
+
+int bypass_flag_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	if ((pbpctl_dev->bp_caps & BP_CAP)) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
+				  BYPASS_FLAG_MASK) ==
+				 BYPASS_FLAG_MASK) ? 1 : 0);
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+int bypass_flag_status_clear(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & BP_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			uint32_t status_reg = 0;
+			status_reg = read_reg(pbpctl_dev, STATUS_REG_ADDR);
+			write_reg(pbpctl_dev, status_reg & ~BYPASS_FLAG_MASK,
+				  STATUS_REG_ADDR);
+			return 0;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+int bypass_change_status(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+
+	if (pbpctl_dev->bp_caps & BP_STATUS_CHANGE_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= 0x8) {
+			ret = bypass_flag_status(pbpctl_dev);
+			bypass_flag_status_clear(pbpctl_dev);
+		} else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			ret = bypass_flag_status(pbpctl_dev);
+			bypass_flag_status_clear(pbpctl_dev);
+		} else {
+			ret = bypass_from_last_read(pbpctl_dev);
+			bypass_status_clear(pbpctl_dev);
+		}
+	}
+	return ret;
+}
+
+int bypass_off_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & BP_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
+				  BYPASS_OFF_MASK) == BYPASS_OFF_MASK) ? 1 : 0);
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+static int bypass_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_b = get_status_port_fn(pbpctl_dev)))
+			return BP_NOT_CAP;
+
+		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);
+			else
+				return BP_NOT_CAP;
+		}
+		if (pbpctl_dev->bp_ext_ver >= 0x8) {
+
+			//BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, (BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT))&~BPCTLI_CTRL_EXT_SDP7_DIR);
+			if (pbpctl_dev->bp_10g9) {
+				ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL);
+				BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL,
+						(ctrl_ext | BP10G_I2C_CLK_OUT));
+				//return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1);
+				return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) &
+					 BP10G_I2C_CLK_IN) != 0 ? 0 : 1);
+
+			} else if (pbpctl_dev->bp_540) {
+				return (((BP10G_READ_REG(pbpctl_dev_b, ESDP)) &
+					 BP10G_SDP0_DATA) != 0 ? 0 : 1);
+			}
+
+			else if ((pbpctl_dev->bp_fiber5)
+				 || (pbpctl_dev->bp_i80)) {
+				return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
+					 BPCTLI_CTRL_SWDPIN0) != 0 ? 0 : 1);
+			} else if (pbpctl_dev->bp_10gb) {
+				ctrl_ext =
+				    BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
+				BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO,
+						 (ctrl_ext | BP10GB_GPIO3_OE_P0)
+						 & ~(BP10GB_GPIO3_SET_P0 |
+						     BP10GB_GPIO3_CLR_P0));
+
+				return (((BP10GB_READ_REG
+					  (pbpctl_dev,
+					   MISC_REG_GPIO)) & BP10GB_GPIO3_P0) !=
+					0 ? 0 : 1);
+			}
+
+			else if (!pbpctl_dev->bp_10g)
+				return (((BPCTL_READ_REG
+					  (pbpctl_dev_b,
+					   CTRL_EXT)) &
+					 BPCTLI_CTRL_EXT_SDP7_DATA) !=
+					0 ? 0 : 1);
+
+			else {
+				ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP);
+				BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
+						(ctrl_ext |
+						 BP10G_SDP7_DATA_OUT));
+				//return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1);
+				return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) &
+					 BP10G_SDP7_DATA_IN) != 0 ? 0 : 1);
+			}
+
+		} else if (pbpctl_dev->media_type == bp_copper) {
+
+			return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
+				 BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0);
+		} else {
+			if ((bypass_status_clear(pbpctl_dev)) >= 0)
+				return (bypass_from_last_read(pbpctl_dev));
+		}
+
+	}
+	return BP_NOT_CAP;
+}
+
+int default_pwron_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
+		if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) {
+			if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+				return ((((read_reg
+					   (pbpctl_dev,
+					    STATUS_REG_ADDR)) & DFLT_PWRON_MASK)
+					 == DFLT_PWRON_MASK) ? 0 : 1);
+			}
+		}		/*else if ((!pbpctl_dev->bp_caps&BP_DIS_CAP)&&
+				   (pbpctl_dev->bp_caps&BP_PWUP_ON_CAP))
+				   return 1; */
+	}
+	return BP_NOT_CAP;
+}
+
+static int default_pwroff_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	/*if ((!pbpctl_dev->bp_caps&BP_DIS_CAP)&&
+	   (pbpctl_dev->bp_caps&BP_PWOFF_ON_CAP))
+	   return 1; */
+	if ((pbpctl_dev->bp_caps & SW_CTL_CAP)
+	    && (pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) {
+		return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
+			  DFLT_PWROFF_MASK) == DFLT_PWROFF_MASK) ? 0 : 1);
+	}
+	return BP_NOT_CAP;
+}
+
+int dis_bypass_cap_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
+				  DIS_BYPASS_CAP_MASK) ==
+				 DIS_BYPASS_CAP_MASK) ? 1 : 0);
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+int cmd_en_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
+				  CMND_EN_MASK) == CMND_EN_MASK) ? 1 : 0);
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+int wdt_en_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
+				  WDT_EN_MASK) == WDT_EN_MASK) ? 1 : 0);
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+int wdt_programmed(bpctl_dev_t * pbpctl_dev, int *timeout)
+{
+	int ret = 0;
+	if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			if ((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
+			    WDT_EN_MASK) {
+				u8 wdt_val;
+				wdt_val = read_reg(pbpctl_dev, WDT_REG_ADDR);
+				*timeout = (1 << wdt_val) * 100;
+			} else
+				*timeout = 0;
+		} else {
+			int curr_wdt_status = pbpctl_dev->wdt_status;
+			if (curr_wdt_status == WDT_STATUS_UNKNOWN)
+				*timeout = -1;
+			else
+				*timeout =
+				    curr_wdt_status ==
+				    0 ? 0 : pbpctl_dev->bypass_timer_interval;
+		};
+	} else
+		ret = BP_NOT_CAP;
+	return ret;
+}
+
+int bypass_support(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+
+	if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
+			ret =
+			    ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) &
+			       BYPASS_SUPPORT_MASK) ==
+			      BYPASS_SUPPORT_MASK) ? 1 : 0);
+		} else if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
+			ret = 1;
+	} else
+		ret = BP_NOT_CAP;
+	return ret;
+}
+
+int tap_support(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+
+	if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
+			ret =
+			    ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) &
+			       TAP_SUPPORT_MASK) == TAP_SUPPORT_MASK) ? 1 : 0);
+		} else if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
+			ret = 0;
+	} else
+		ret = BP_NOT_CAP;
+	return ret;
+}
+
+int normal_support(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+
+	if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
+			ret =
+			    ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) &
+			       NORMAL_UNSUPPORT_MASK) ==
+			      NORMAL_UNSUPPORT_MASK) ? 0 : 1);
+		} else
+			ret = 1;
+	};
+	return ret;
+}
+
+int get_bp_prod_caps(bpctl_dev_t * pbpctl_dev)
+{
+	if ((pbpctl_dev->bp_caps & SW_CTL_CAP) &&
+	    (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER))
+		return (read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR));
+	return BP_NOT_CAP;
+
+}
+
+int tap_flag_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
+			return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
+				  TAP_FLAG_MASK) == TAP_FLAG_MASK) ? 1 : 0);
+
+	}
+	return BP_NOT_CAP;
+}
+
+int tap_flag_status_clear(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t status_reg = 0;
+	if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
+			status_reg = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
+			write_reg(pbpctl_dev, status_reg & ~TAP_FLAG_MASK,
+				  STATUS_TAP_REG_ADDR);
+			return 0;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+int tap_change_status(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+	if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
+		if (pbpctl_dev->bp_caps & TAP_CAP) {
+			if (pbpctl_dev->bp_caps & BP_CAP) {
+				ret = tap_flag_status(pbpctl_dev);
+				tap_flag_status_clear(pbpctl_dev);
+			} else {
+				ret = bypass_from_last_read(pbpctl_dev);
+				bypass_status_clear(pbpctl_dev);
+			}
+		}
+	}
+	return ret;
+}
+
+int tap_off_status(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & TAP_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
+			return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
+				  TAP_OFF_MASK) == TAP_OFF_MASK) ? 1 : 0);
+	}
+	return BP_NOT_CAP;
+}
+
+int tap_status(bpctl_dev_t * pbpctl_dev)
+{
+	u32 ctrl_ext = 0;
+
+	if (pbpctl_dev->bp_caps & TAP_CAP) {
+		bpctl_dev_t *pbpctl_dev_b = NULL;
+
+		if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev)))
+			return BP_NOT_CAP;
+
+		if (pbpctl_dev->bp_ext_ver >= 0x8) {
+			if (!pbpctl_dev->bp_10g)
+				return (((BPCTL_READ_REG
+					  (pbpctl_dev_b,
+					   CTRL_EXT)) &
+					 BPCTLI_CTRL_EXT_SDP6_DATA) !=
+					0 ? 0 : 1);
+			else {
+				ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP);
+				BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
+						(ctrl_ext |
+						 BP10G_SDP6_DATA_OUT));
+				// return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x1)!=0?0:1);
+				return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) &
+					 BP10G_SDP6_DATA_IN) != 0 ? 0 : 1);
+			}
+
+		} else if (pbpctl_dev->media_type == bp_copper)
+			return (((BPCTL_READ_REG(pbpctl_dev, CTRL)) &
+				 BPCTLI_CTRL_SWDPIN0) != 0 ? 1 : 0);
+		else {
+			if ((bypass_status_clear(pbpctl_dev)) >= 0)
+				return (bypass_from_last_read(pbpctl_dev));
+		}
+
+	}
+	return BP_NOT_CAP;
+}
+
+int default_pwron_tap_status(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
+			return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
+				  DFLT_PWRON_TAP_MASK) ==
+				 DFLT_PWRON_TAP_MASK) ? 1 : 0);
+	}
+	return BP_NOT_CAP;
+}
+
+int dis_tap_cap_status(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
+			return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
+				  DIS_TAP_CAP_MASK) ==
+				 DIS_TAP_CAP_MASK) ? 1 : 0);
+	}
+	return BP_NOT_CAP;
+}
+
+int disc_flag_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & DISC_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= 0x8)
+			return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
+				  DISC_FLAG_MASK) == DISC_FLAG_MASK) ? 1 : 0);
+
+	}
+	return BP_NOT_CAP;
+}
+
+int disc_flag_status_clear(bpctl_dev_t * pbpctl_dev)
+{
+	uint32_t status_reg = 0;
+	if (pbpctl_dev->bp_caps & DISC_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= 0x8) {
+			status_reg = read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR);
+			write_reg(pbpctl_dev, status_reg & ~DISC_FLAG_MASK,
+				  STATUS_DISC_REG_ADDR);
+			return BP_OK;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+int disc_change_status(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+	if (pbpctl_dev->bp_caps & DISC_CAP) {
+		ret = disc_flag_status(pbpctl_dev);
+		disc_flag_status_clear(pbpctl_dev);
+		return ret;
+	}
+	return BP_NOT_CAP;
+}
+
+int disc_off_status(bpctl_dev_t * pbpctl_dev)
+{
+	bpctl_dev_t *pbpctl_dev_b = NULL;
+	u32 ctrl_ext = 0;
+
+	if (pbpctl_dev->bp_caps & DISC_CAP) {
+		if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev)))
+			return BP_NOT_CAP;
+		if (DISCF_IF_SERIES(pbpctl_dev->subdevice))
+			return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
+				  DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0);
+
+		if (pbpctl_dev->bp_i80) {
+			//  return((((read_reg(pbpctl_dev,STATUS_DISC_REG_ADDR)) & DISC_OFF_MASK)==DISC_OFF_MASK)?1:0);
+			return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT)) &
+				 BPCTLI_CTRL_EXT_SDP6_DATA) != 0 ? 1 : 0);
+
+		}
+		if (pbpctl_dev->bp_540) {
+			ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, ESDP);
+			//return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1);
+			return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) &
+				 BP10G_SDP2_DATA) != 0 ? 1 : 0);
+
+		}
+		//if (pbpctl_dev->device==SILICOM_PXG2TBI_SSID) {
+		if (pbpctl_dev->media_type == bp_copper) {
+
+#if 0
+			return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
+				  DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0);
+#endif
+			if (!pbpctl_dev->bp_10g)
+				return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
+					 BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0);
+			else
+				// return(((readl((void *)((pbpctl_dev)->mem_map) + 0x20)) & 0x2)!=0?1:0); 
+				return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) &
+					 BP10G_SDP1_DATA) != 0 ? 1 : 0);
+
+		} else {
+
+			if (pbpctl_dev->bp_10g9) {
+				ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL);
+				BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL,
+						(ctrl_ext |
+						 BP10G_I2C_DATA_OUT));
+				//return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1);
+				return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) &
+					 BP10G_I2C_DATA_IN) != 0 ? 1 : 0);
+
+			} else if (pbpctl_dev->bp_fiber5) {
+				return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
+					 BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0);
+			} else if (pbpctl_dev->bp_10gb) {
+				ctrl_ext =
+				    BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
+				BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO,
+						 (ctrl_ext | BP10GB_GPIO3_OE_P1)
+						 & ~(BP10GB_GPIO3_SET_P1 |
+						     BP10GB_GPIO3_CLR_P1));
+
+				return (((BP10GB_READ_REG
+					  (pbpctl_dev,
+					   MISC_REG_GPIO)) & BP10GB_GPIO3_P1) !=
+					0 ? 1 : 0);
+			}
+			if (!pbpctl_dev->bp_10g) {
+
+				return (((BPCTL_READ_REG
+					  (pbpctl_dev_b,
+					   CTRL_EXT)) &
+					 BPCTLI_CTRL_EXT_SDP6_DATA) !=
+					0 ? 1 : 0);
+			} else {
+				ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP);
+				BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
+						(ctrl_ext |
+						 BP10G_SDP6_DATA_OUT));
+				// temp=  (((BP10G_READ_REG(pbpctl_dev_b,EODSDP))&BP10G_SDP6_DATA_IN)!=0?1:0);
+				//return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28)) & 0x1)!=0?1:0);
+				return (((BP10G_READ_REG(pbpctl_dev_b, EODSDP))
+					 & BP10G_SDP6_DATA_IN) != 0 ? 1 : 0);
+			}
+
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+static int disc_status(bpctl_dev_t * pbpctl_dev)
+{
+	int ctrl = 0;
+	if (pbpctl_dev->bp_caps & DISC_CAP) {
+
+		if ((ctrl = disc_off_status(pbpctl_dev)) < 0)
+			return ctrl;
+		return ((ctrl == 0) ? 1 : 0);
+
+	}
+	return BP_NOT_CAP;
+}
+
+int default_pwron_disc_status(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= 0x8)
+			return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
+				  DFLT_PWRON_DISC_MASK) ==
+				 DFLT_PWRON_DISC_MASK) ? 1 : 0);
+	}
+	return BP_NOT_CAP;
+}
+
+int dis_disc_cap_status(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & DIS_DISC_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= 0x8)
+			return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
+				  DIS_DISC_CAP_MASK) ==
+				 DIS_DISC_CAP_MASK) ? 1 : 0);
+	}
+	return BP_NOT_CAP;
+}
+
+int disc_port_status(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+	bpctl_dev_t *pbpctl_dev_m;
+
+	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 == NULL)
+		return BP_NOT_CAP;
+
+	if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
+		if (is_bypass_fn(pbpctl_dev) == 1) {
+			return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
+				  TX_DISA_MASK) == TX_DISA_MASK) ? 1 : 0);
+		} else
+			return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
+				  TX_DISB_MASK) == TX_DISB_MASK) ? 1 : 0);
+
+	}
+	return ret;
+}
+
+int default_pwron_disc_port_status(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = BP_NOT_CAP;
+	bpctl_dev_t *pbpctl_dev_m;
+
+	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 == NULL)
+		return BP_NOT_CAP;
+
+	if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
+		if (is_bypass_fn(pbpctl_dev) == 1)
+			return ret;
+		//  return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0);
+		else
+			return ret;
+		//   return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0);
+
+	}
+	return ret;
+}
+
+int wdt_exp_mode_status(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
+		if (pbpctl_dev->bp_ext_ver <= PXG2BPI_VER)
+			return 0;	/* bypass mode */
+		else if (pbpctl_dev->bp_ext_ver == PXG2TBPI_VER)
+			return 1;	/* tap mode */
+		else if (pbpctl_dev->bp_ext_ver >= PXE2TBPI_VER) {
+			if (pbpctl_dev->bp_ext_ver >= 0x8) {
+				if (((read_reg
+				      (pbpctl_dev,
+				       STATUS_DISC_REG_ADDR)) &
+				     WDTE_DISC_BPN_MASK) == WDTE_DISC_BPN_MASK)
+					return 2;
+			}
+			return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
+				  WDTE_TAP_BPN_MASK) ==
+				 WDTE_TAP_BPN_MASK) ? 1 : 0);
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+int tpl2_flag_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) {
+		return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
+			  TPL2_FLAG_MASK) == TPL2_FLAG_MASK) ? 1 : 0);
+
+	}
+	return BP_NOT_CAP;
+}
+
+int tpl_hw_status(bpctl_dev_t * pbpctl_dev)
+{
+	bpctl_dev_t *pbpctl_dev_b = NULL;
+
+	if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev)))
+		return BP_NOT_CAP;
+
+	if (TPL_IF_SERIES(pbpctl_dev->subdevice))
+		return (((BPCTL_READ_REG(pbpctl_dev, CTRL)) &
+			 BPCTLI_CTRL_SWDPIN0) != 0 ? 1 : 0);
+	return BP_NOT_CAP;
+}
+
+//#ifdef PMC_FIX_FLAG
+
+int bp_wait_at_pwup_status(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
+		if (pbpctl_dev->bp_ext_ver >= 0x8)
+			return ((((read_reg(pbpctl_dev, CONT_CONFIG_REG_ADDR)) &
+				  WAIT_AT_PWUP_MASK) ==
+				 WAIT_AT_PWUP_MASK) ? 1 : 0);
+	}
+	return BP_NOT_CAP;
+}
+
+int bp_hw_reset_status(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
+
+		if (pbpctl_dev->bp_ext_ver >= 0x8)
+			return ((((read_reg(pbpctl_dev, CONT_CONFIG_REG_ADDR)) &
+				  EN_HW_RESET_MASK) ==
+				 EN_HW_RESET_MASK) ? 1 : 0);
+	}
+	return BP_NOT_CAP;
+}
+
+//#endif /*PMC_FIX_FLAG*/
+
+int std_nic_status(bpctl_dev_t * pbpctl_dev)
+{
+	int status_val = 0;
+
+	if (pbpctl_dev->bp_caps & STD_NIC_CAP) {
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
+			return BP_NOT_CAP;
+		if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
+			return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
+				  STD_NIC_ON_MASK) == STD_NIC_ON_MASK) ? 1 : 0);
+		}
+
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			if (pbpctl_dev->bp_caps & BP_CAP) {
+				status_val =
+				    read_reg(pbpctl_dev, STATUS_REG_ADDR);
+				if (((!(status_val & WDT_EN_MASK))
+				     && ((status_val & STD_NIC_MASK) ==
+					 STD_NIC_MASK)))
+					status_val = 1;
+				else
+					return 0;
+			}
+			if (pbpctl_dev->bp_caps & TAP_CAP) {
+				status_val =
+				    read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
+				if ((status_val & STD_NIC_TAP_MASK) ==
+				    STD_NIC_TAP_MASK)
+					status_val = 1;
+				else
+					return 0;
+			}
+			if (pbpctl_dev->bp_caps & TAP_CAP) {
+				if ((disc_off_status(pbpctl_dev)))
+					status_val = 1;
+				else
+					return 0;
+			}
+
+			return status_val;
+		}
+	}
+	return BP_NOT_CAP;
+}
+
+/******************************************************/
+/**************SW_INIT*********************************/
+/******************************************************/
+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))) {
+		ret = read_reg(pbpctl_dev, VER_REG_ADDR);
+		printk("VER_REG reg1=%x\n", ret);
+		ret = read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR);
+		printk("PRODUCT_CAP reg=%x\n", ret);
+		ret = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
+		printk("STATUS_TAP reg1=%x\n", ret);
+		ret = read_reg(pbpctl_dev, 0x7);
+		printk("SIG_REG reg1=%x\n", ret);
+		ret = read_reg(pbpctl_dev, STATUS_REG_ADDR);
+		printk("STATUS_REG_ADDR=%x\n", ret);
+		ret = read_reg(pbpctl_dev, WDT_REG_ADDR);
+		printk("WDT_REG_ADDR=%x\n", ret);
+		ret = read_reg(pbpctl_dev, TMRL_REG_ADDR);
+		printk("TMRL_REG_ADDR=%x\n", ret);
+		ret = read_reg(pbpctl_dev, TMRH_REG_ADDR);
+		printk("TMRH_REG_ADDR=%x\n", ret);
+	}
+#endif
+	if ((pbpctl_dev->bp_fiber5) || (pbpctl_dev->bp_10g9)) {
+		pbpctl_dev->media_type = bp_fiber;
+	} else if (pbpctl_dev->bp_10gb) {
+		if (BP10GB_CX4_SERIES(pbpctl_dev->subdevice))
+			pbpctl_dev->media_type = bp_cx4;
+		else
+			pbpctl_dev->media_type = bp_fiber;
+
+	}
+
+	else if (pbpctl_dev->bp_540)
+		pbpctl_dev->media_type = bp_none;
+	else if (!pbpctl_dev->bp_10g) {
+
+		ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
+		if ((ctrl_ext & BPCTLI_CTRL_EXT_LINK_MODE_MASK) == 0x0)
+			pbpctl_dev->media_type = bp_copper;
+		else
+			pbpctl_dev->media_type = bp_fiber;
+
+	}
+	//if (!pbpctl_dev->bp_10g)
+	//  pbpctl_dev->media_type=((BPCTL_READ_REG(pbpctl_dev, STATUS))&BPCTLI_STATUS_TBIMODE)?bp_fiber:bp_copper;
+	else {
+		if (BP10G_CX4_SERIES(pbpctl_dev->subdevice))
+			pbpctl_dev->media_type = bp_cx4;
+		else
+			pbpctl_dev->media_type = bp_fiber;
+	}
+
+	//pbpctl_dev->bp_fw_ver=0xa8;
+	if (is_bypass_fn(pbpctl_dev)) {
+
+		pbpctl_dev->bp_caps |= BP_PWOFF_ON_CAP;
+		if (pbpctl_dev->media_type == bp_fiber)
+			pbpctl_dev->bp_caps |=
+			    (TX_CTL_CAP | TX_STATUS_CAP | TPL_CAP);
+
+		if (TPL_IF_SERIES(pbpctl_dev->subdevice)) {
+			pbpctl_dev->bp_caps |= TPL_CAP;
+		}
+
+		if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
+			pbpctl_dev->bp_caps |=
+			    (BP_CAP | BP_STATUS_CAP | SW_CTL_CAP |
+			     BP_PWUP_ON_CAP | BP_PWUP_OFF_CAP | BP_PWOFF_OFF_CAP
+			     | WD_CTL_CAP | WD_STATUS_CAP | STD_NIC_CAP |
+			     WD_TIMEOUT_CAP);
+
+			pbpctl_dev->bp_ext_ver = OLD_IF_VER;
+			return;
+		}
+
+		if ((pbpctl_dev->bp_fw_ver == 0xff) &&
+		    OLD_IF_SERIES(pbpctl_dev->subdevice)) {
+
+			pbpctl_dev->bp_caps |=
+			    (BP_CAP | BP_STATUS_CAP | BP_STATUS_CHANGE_CAP |
+			     SW_CTL_CAP | BP_PWUP_ON_CAP | WD_CTL_CAP |
+			     WD_STATUS_CAP | WD_TIMEOUT_CAP);
+
+			pbpctl_dev->bp_ext_ver = OLD_IF_VER;
+			return;
+		}
+
+		else {
+			switch (pbpctl_dev->bp_fw_ver) {
+			case BP_FW_VER_A0:
+			case BP_FW_VER_A1:{
+					pbpctl_dev->bp_ext_ver =
+					    (pbpctl_dev->
+					     bp_fw_ver & EXT_VER_MASK);
+					break;
+				}
+			default:{
+					if ((bypass_sign_check(pbpctl_dev)) !=
+					    1) {
+						pbpctl_dev->bp_caps = 0;
+						return;
+					}
+					pbpctl_dev->bp_ext_ver =
+					    (pbpctl_dev->
+					     bp_fw_ver & EXT_VER_MASK);
+				}
+			}
+		}
+
+		if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
+			pbpctl_dev->bp_caps |=
+			    (BP_CAP | BP_STATUS_CAP | BP_STATUS_CHANGE_CAP |
+			     SW_CTL_CAP | BP_DIS_CAP | BP_DIS_STATUS_CAP |
+			     BP_PWUP_ON_CAP | BP_PWUP_OFF_CAP | BP_PWUP_CTL_CAP
+			     | WD_CTL_CAP | STD_NIC_CAP | WD_STATUS_CAP |
+			     WD_TIMEOUT_CAP);
+		else if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
+			int cap_reg;
+
+			pbpctl_dev->bp_caps |=
+			    (SW_CTL_CAP | WD_CTL_CAP | WD_STATUS_CAP |
+			     WD_TIMEOUT_CAP);
+			cap_reg = get_bp_prod_caps(pbpctl_dev);
+
+			if ((cap_reg & NORMAL_UNSUPPORT_MASK) ==
+			    NORMAL_UNSUPPORT_MASK)
+				pbpctl_dev->bp_caps |= NIC_CAP_NEG;
+			else
+				pbpctl_dev->bp_caps |= STD_NIC_CAP;
+
+			if ((normal_support(pbpctl_dev)) == 1)
+
+				pbpctl_dev->bp_caps |= STD_NIC_CAP;
+
+			else
+				pbpctl_dev->bp_caps |= NIC_CAP_NEG;
+			if ((cap_reg & BYPASS_SUPPORT_MASK) ==
+			    BYPASS_SUPPORT_MASK) {
+				pbpctl_dev->bp_caps |=
+				    (BP_CAP | BP_STATUS_CAP |
+				     BP_STATUS_CHANGE_CAP | BP_DIS_CAP |
+				     BP_DIS_STATUS_CAP | BP_PWUP_ON_CAP |
+				     BP_PWUP_OFF_CAP | BP_PWUP_CTL_CAP);
+				if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER7)
+					pbpctl_dev->bp_caps |=
+					    BP_PWOFF_ON_CAP | BP_PWOFF_OFF_CAP |
+					    BP_PWOFF_CTL_CAP;
+			}
+			if ((cap_reg & TAP_SUPPORT_MASK) == TAP_SUPPORT_MASK) {
+				pbpctl_dev->bp_caps |=
+				    (TAP_CAP | TAP_STATUS_CAP |
+				     TAP_STATUS_CHANGE_CAP | TAP_DIS_CAP |
+				     TAP_DIS_STATUS_CAP | TAP_PWUP_ON_CAP |
+				     TAP_PWUP_OFF_CAP | TAP_PWUP_CTL_CAP);
+			}
+			if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
+				if ((cap_reg & DISC_SUPPORT_MASK) ==
+				    DISC_SUPPORT_MASK)
+					pbpctl_dev->bp_caps |=
+					    (DISC_CAP | DISC_DIS_CAP |
+					     DISC_PWUP_CTL_CAP);
+				if ((cap_reg & TPL2_SUPPORT_MASK) ==
+				    TPL2_SUPPORT_MASK) {
+					pbpctl_dev->bp_caps_ex |= TPL2_CAP_EX;
+					pbpctl_dev->bp_caps |= TPL_CAP;
+					pbpctl_dev->bp_tpl_flag =
+					    tpl2_flag_status(pbpctl_dev);
+				}
+
+			}
+
+			if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER9) {
+				if ((cap_reg & DISC_PORT_SUPPORT_MASK) ==
+				    DISC_PORT_SUPPORT_MASK) {
+					pbpctl_dev->bp_caps_ex |=
+					    DISC_PORT_CAP_EX;
+					pbpctl_dev->bp_caps |=
+					    (TX_CTL_CAP | TX_STATUS_CAP);
+				}
+
+			}
+
+		}
+		if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
+			if ((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
+			    WDT_EN_MASK)
+				pbpctl_dev->wdt_status = WDT_STATUS_EN;
+			else
+				pbpctl_dev->wdt_status = WDT_STATUS_DIS;
+		}
+
+	} else if ((P2BPFI_IF_SERIES(pbpctl_dev->subdevice)) ||
+		   (PEGF5_IF_SERIES(pbpctl_dev->subdevice)) ||
+		   (PEGF80_IF_SERIES(pbpctl_dev->subdevice)) ||
+		   (BP10G9_IF_SERIES(pbpctl_dev->subdevice))) {
+		pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP);
+	}
+	if ((pbpctl_dev->subdevice & 0xa00) == 0xa00)
+		pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP);
+	if (PEG5_IF_SERIES(pbpctl_dev->subdevice))
+		pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP);
+
+	if (BP10GB_IF_SERIES(pbpctl_dev->subdevice)) {
+		pbpctl_dev->bp_caps &= ~(TX_CTL_CAP | TX_STATUS_CAP);
+	}
+	pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
+	if (pbpctl_dev_m != NULL) {
+		int cap_reg = 0;
+		if (pbpctl_dev_m->bp_ext_ver >= 0x9) {
+			cap_reg = get_bp_prod_caps(pbpctl_dev_m);
+			if ((cap_reg & DISC_PORT_SUPPORT_MASK) ==
+			    DISC_PORT_SUPPORT_MASK)
+				pbpctl_dev->bp_caps |=
+				    (TX_CTL_CAP | TX_STATUS_CAP);
+			pbpctl_dev->bp_caps_ex |= DISC_PORT_CAP_EX;
+		}
+	}
+}
+
+int bypass_off_init(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+
+	if ((ret = cmnd_on(pbpctl_dev)) < 0)
+		return ret;
+	if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
+		return (dis_bypass_cap(pbpctl_dev));
+	wdt_off(pbpctl_dev);
+	if (pbpctl_dev->bp_caps & BP_CAP)
+		bypass_off(pbpctl_dev);
+	if (pbpctl_dev->bp_caps & TAP_CAP)
+		tap_off(pbpctl_dev);
+	cmnd_off(pbpctl_dev);
+	return 0;
+}
+
+void remove_bypass_wd_auto(bpctl_dev_t * pbpctl_dev)
+{
+#ifdef BP_SELF_TEST
+	bpctl_dev_t *pbpctl_dev_sl = NULL;
+#endif
+
+	if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
+
+		del_timer_sync(&pbpctl_dev->bp_timer);
+#ifdef BP_SELF_TEST
+		pbpctl_dev_sl = get_status_port_fn(pbpctl_dev);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31))
+		if (pbpctl_dev_sl && (pbpctl_dev_sl->ndev)
+		    && (pbpctl_dev_sl->ndev->hard_start_xmit)
+		    && (pbpctl_dev_sl->hard_start_xmit_save)) {
+			rtnl_lock();
+			pbpctl_dev_sl->ndev->hard_start_xmit =
+			    pbpctl_dev_sl->hard_start_xmit_save;
+			rtnl_unlock();
+		}
+#else
+		if (pbpctl_dev_sl && (pbpctl_dev_sl->ndev)) {
+			if ((pbpctl_dev_sl->ndev->netdev_ops)
+			    && (pbpctl_dev_sl->old_ops)) {
+				rtnl_lock();
+				pbpctl_dev_sl->ndev->netdev_ops =
+				    pbpctl_dev_sl->old_ops;
+				pbpctl_dev_sl->old_ops = NULL;
+
+				rtnl_unlock();
+
+			}
+
+		}
+
+#endif
+#endif
+	}
+
+}
+
+int init_bypass_wd_auto(bpctl_dev_t * pbpctl_dev)
+{
+	if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
+		init_timer(&pbpctl_dev->bp_timer);
+		pbpctl_dev->bp_timer.function = &wd_reset_timer;
+		pbpctl_dev->bp_timer.data = (unsigned long)pbpctl_dev;
+		return 1;
+	}
+	return BP_NOT_CAP;
+}
+
+#ifdef BP_SELF_TEST
+int bp_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	bpctl_dev_t *pbpctl_dev = NULL, *pbpctl_dev_m = NULL;
+	int idx_dev = 0;
+	struct ethhdr *eth = (struct ethhdr *)skb->data;
+
+	for (idx_dev = 0;
+	     ((bpctl_dev_arr[idx_dev].ndev != NULL) && (idx_dev < device_num));
+	     idx_dev++) {
+		if (bpctl_dev_arr[idx_dev].ndev == dev) {
+			pbpctl_dev = &bpctl_dev_arr[idx_dev];
+			break;
+		}
+	}
+	if (!pbpctl_dev)
+		return 1;
+	if ((htons(ETH_P_BPTEST) == eth->h_proto)) {
+
+		pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
+		if (pbpctl_dev_m) {
+
+			if (bypass_status(pbpctl_dev_m)) {
+				cmnd_on(pbpctl_dev_m);
+				bypass_off(pbpctl_dev_m);
+				cmnd_off(pbpctl_dev_m);
+			}
+			wdt_timer_reload(pbpctl_dev_m);
+		}
+		dev_kfree_skb_irq(skb);
+		return 0;
+	}
+	return (pbpctl_dev->hard_start_xmit_save(skb, dev));
+}
+#endif
+
+int set_bypass_wd_auto(bpctl_dev_t * pbpctl_dev, unsigned int param)
+{
+	if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
+		if (pbpctl_dev->reset_time != param) {
+			if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
+				pbpctl_dev->reset_time =
+				    (param <
+				     WDT_AUTO_MIN_INT) ? WDT_AUTO_MIN_INT :
+				    param;
+			else
+				pbpctl_dev->reset_time = param;
+			if (param)
+				mod_timer(&pbpctl_dev->bp_timer, jiffies);
+		}
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+int get_bypass_wd_auto(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
+		return pbpctl_dev->reset_time;
+	}
+	return BP_NOT_CAP;
+}
+
+#ifdef  BP_SELF_TEST
+
+int set_bp_self_test(bpctl_dev_t * pbpctl_dev, unsigned int param)
+{
+	bpctl_dev_t *pbpctl_dev_sl = NULL;
+
+	if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
+		pbpctl_dev->bp_self_test_flag = param == 0 ? 0 : 1;
+		pbpctl_dev_sl = get_status_port_fn(pbpctl_dev);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31))
+		if ((pbpctl_dev_sl->ndev) &&
+		    (pbpctl_dev_sl->ndev->hard_start_xmit)) {
+			rtnl_lock();
+			if (pbpctl_dev->bp_self_test_flag == 1) {
+
+				pbpctl_dev_sl->hard_start_xmit_save =
+				    pbpctl_dev_sl->ndev->hard_start_xmit;
+				pbpctl_dev_sl->ndev->hard_start_xmit =
+				    bp_hard_start_xmit;
+			} else if (pbpctl_dev_sl->hard_start_xmit_save) {
+				pbpctl_dev_sl->ndev->hard_start_xmit =
+				    pbpctl_dev_sl->hard_start_xmit_save;
+			}
+			rtnl_unlock();
+		}
+#else
+		if ((pbpctl_dev_sl->ndev) && (pbpctl_dev_sl->ndev->netdev_ops)) {
+			rtnl_lock();
+			if (pbpctl_dev->bp_self_test_flag == 1) {
+
+				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 =
+				    bp_hard_start_xmit;
+				pbpctl_dev_sl->ndev->netdev_ops =
+				    &pbpctl_dev_sl->new_ops;
+
+			} else if (pbpctl_dev_sl->old_ops) {
+				pbpctl_dev_sl->ndev->netdev_ops =
+				    pbpctl_dev_sl->old_ops;
+				pbpctl_dev_sl->old_ops = NULL;
+			}
+			rtnl_unlock();
+		}
+#endif
+
+		set_bypass_wd_auto(pbpctl_dev, param);
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+int get_bp_self_test(bpctl_dev_t * pbpctl_dev)
+{
+
+	if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
+		if (pbpctl_dev->bp_self_test_flag == 1)
+			return pbpctl_dev->reset_time;
+		else
+			return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+#endif
+
+/**************************************************************/
+/************************* API ********************************/
+/**************************************************************/
+
+int is_bypass_fn(bpctl_dev_t * pbpctl_dev)
+{
+	if (!pbpctl_dev)
+		return -1;
+
+	return (((pbpctl_dev->func == 0) || (pbpctl_dev->func == 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);
+
+	return ret;
+}
+
+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;
+
+	return (bypass_change_status(pbpctl_dev));
+}
+
+int set_dis_bypass_fn(bpctl_dev_t * pbpctl_dev, int dis_param)
+{
+	int ret = 0;
+	if (!pbpctl_dev)
+		return -1;
+
+	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;
+}
+
+int get_dis_bypass_fn(bpctl_dev_t * pbpctl_dev)
+{
+	if (!pbpctl_dev)
+		return -1;
+
+	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->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;
+}
+
+int get_bypass_pwoff_fn(bpctl_dev_t * pbpctl_dev)
+{
+	if (!pbpctl_dev)
+		return -1;
+
+	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->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;
+}
+
+int get_bypass_pwup_fn(bpctl_dev_t * pbpctl_dev)
+{
+	if (!pbpctl_dev)
+		return -1;
+
+	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->bp_caps & WD_CTL_CAP))
+		return BP_NOT_CAP;
+
+	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;
+
+	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 reset_bypass_wd_timer_fn(bpctl_dev_t * pbpctl_dev)
+{
+	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 (INTEL_IF_SERIES(pbpctl_dev->subdevice))
+		return BP_NOT_CAP;
+
+	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->bp_caps & STD_NIC_CAP))
+		return BP_NOT_CAP;
+
+	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 set_tap_fn(bpctl_dev_t * pbpctl_dev, int tap_mode)
+{
+	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);
+		cmnd_off(pbpctl_dev);
+		return 0;
+	}
+	return BP_NOT_CAP;
+}
+
+int get_tap_fn(bpctl_dev_t * pbpctl_dev)
+{
+	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->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);
+		cmnd_off(pbpctl_dev);
+	} 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 ((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;
+
+	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->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);
+		cmnd_off(pbpctl_dev);
+		return ret;
+	} else
+		return BP_NOT_CAP;
+}
+
+int get_dis_tap_fn(bpctl_dev_t * pbpctl_dev)
+{
+	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->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);
+
+		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);
+
+	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->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;
+}
+
+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));
+}
+
+int get_disc_change_fn(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+	if (!pbpctl_dev)
+		return -1;
+
+	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;
+}
+
+int get_dis_disc_fn(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+	if (!pbpctl_dev)
+		return -1;
+
+	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);
+
+	return ret;
+}
+
+int get_disc_port_fn(bpctl_dev_t * pbpctl_dev)
+{
+	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);
+
+	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;
+	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));
+}
+
+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));
+}
+
+int reset_cont_fn(bpctl_dev_t * pbpctl_dev)
+{
+	int ret = 0;
+	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));
+}
+
+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;
+	bpctl_dev_curr = &bpctl_dev_arr[dev_num];
+
+	return (set_bp_force_link(bpctl_dev_curr, tx_state));
+}
+
+int set_wd_autoreset_fn(bpctl_dev_t * pbpctl_dev, int param)
+{
+	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;
+
+	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;
+
+	return (set_bp_self_test(pbpctl_dev, param));
+}
+
+int get_bp_self_test_fn(bpctl_dev_t * pbpctl_dev)
+{
+	if (!pbpctl_dev)
+		return -1;
+
+	return (get_bp_self_test(pbpctl_dev));
+}
+
+#endif
+
+int get_bypass_caps_fn(bpctl_dev_t * pbpctl_dev)
+{
+	if (!pbpctl_dev)
+		return -1;
+
+	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_dev < device_num)); idx_dev++) {
+			if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)
+			    && (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;
+}
+
+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->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))
+		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));
+
+}
+
+static void bp_tpl_timer_fn(unsigned long param)
+{
+	bpctl_dev_t *pbpctl_dev = (bpctl_dev_t *) param;
+	uint32_t link1, link2;
+	bpctl_dev_t *pbpctl_dev_b = NULL;
+
+	if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev)))
+		return;
+
+	if (!pbpctl_dev->bp_tpl_flag) {
+		set_tx(pbpctl_dev_b, 1);
+		set_tx(pbpctl_dev, 1);
+		return;
+	}
+	link1 = get_bypass_link_status(pbpctl_dev);
+
+	link2 = get_bypass_link_status(pbpctl_dev_b);
+	if ((link1) && (tx_status(pbpctl_dev))) {
+		if ((!link2) && (tx_status(pbpctl_dev_b))) {
+			set_tx(pbpctl_dev, 0);
+		} else if (!tx_status(pbpctl_dev_b)) {
+			set_tx(pbpctl_dev_b, 1);
+		}
+	} else if ((!link1) && (tx_status(pbpctl_dev))) {
+		if ((link2) && (tx_status(pbpctl_dev_b))) {
+			set_tx(pbpctl_dev_b, 0);
+		}
+	} else if ((link1) && (!tx_status(pbpctl_dev))) {
+		if ((link2) && (tx_status(pbpctl_dev_b))) {
+			set_tx(pbpctl_dev, 1);
+		}
+	} else if ((!link1) && (!tx_status(pbpctl_dev))) {
+		if ((link2) && (tx_status(pbpctl_dev_b))) {
+			set_tx(pbpctl_dev, 1);
+		}
+	}
+
+	mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies + BP_LINK_MON_DELAY * HZ);
+}
+
+void remove_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev)
+{
+	bpctl_dev_t *pbpctl_dev_b = NULL;
+	if (!pbpctl_dev)
+		return;
+	pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
+
+	if (pbpctl_dev->bp_caps & TPL_CAP) {
+		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);
+		set_tx(pbpctl_dev, 1);
+	}
+	return;
+}
+
+int init_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev)
+{
+	if (!pbpctl_dev)
+		return -1;
+	if (pbpctl_dev->bp_caps & TPL_CAP) {
+		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;
+		return BP_OK;
+	}
+	return BP_NOT_CAP;
+}
+
+int set_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev, unsigned int param)
+{
+	if (!pbpctl_dev)
+		return -1;
+	if (pbpctl_dev->bp_caps & TPL_CAP) {
+		if ((param) && (!pbpctl_dev->bp_tpl_flag)) {
+			pbpctl_dev->bp_tpl_flag = 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);
+
+		return BP_OK;
+	}
+	return BP_NOT_CAP;
+}
+
+int get_bypass_tpl_auto(bpctl_dev_t * pbpctl_dev)
+{
+	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;
+	if (!pbpctl_dev)
+		return -1;
+
+	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->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;
+
+	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);
+
+		// 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);
+
+	return ret;
+}
+
+int set_bp_hw_reset_fn(bpctl_dev_t * pbpctl_dev, int tap_mode)
+{
+	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_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);
+
+	//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;
+}
+
+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_dev < device_num));
+	     idx_dev++) {
+		if ((bus == bpctl_dev_arr[idx_dev].bus)
+		    && (slot == bpctl_dev_arr[idx_dev].slot)
+		    && (func == bpctl_dev_arr[idx_dev].func))
+
+			return idx_dev;
+	}
+	return -1;
+}
+
+static void str_low(char *str)
+{
+	int i;
+
+	for (i = 0; i < strlen(str); i++)
+		if ((str[i] >= 65) && (str[i] <= 90))
+			str[i] += 32;
+}
+
+static unsigned long str_to_hex(char *p)
+{
+	unsigned long hex = 0;
+	unsigned long length = strlen(p), shift = 0;
+	unsigned char dig = 0;
+
+	str_low(p);
+	length = strlen(p);
+
+	if (length == 0)
+		return 0;
+
+	do {
+		dig = p[--length];
+		dig = dig < 'a' ? (dig - '0') : (dig - 'a' + 0xa);
+		hex |= (dig << shift);
+		shift += 4;
+	} while (length);
+	return hex;
+}
+
+static int get_dev_idx(int ifindex)
+{
+	int idx_dev = 0;
+
+	for (idx_dev = 0;
+	     ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num));
+	     idx_dev++) {
+		if (ifindex == bpctl_dev_arr[idx_dev].ifindex)
+			return idx_dev;
+	}
+
+	return -1;
+}
+
+static bpctl_dev_t *get_dev_idx_p(int ifindex)
+{
+	int idx_dev = 0;
+
+	for (idx_dev = 0;
+	     ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num));
+	     idx_dev++) {
+		if (ifindex == bpctl_dev_arr[idx_dev].ifindex)
+			return &bpctl_dev_arr[idx_dev];
+	}
+
+	return NULL;
+}
+
+static void if_scan_init(void)
+{
+	int idx_dev = 0;
+	struct net_device *dev;
+	int ifindex;
+	//rcu_read_lock();
+	//rtnl_lock();
+	//rcu_read_lock();
+#if 1
+#if (LINUX_VERSION_CODE >= 0x020618)
+	for_each_netdev(&init_net, dev)
+#elif (LINUX_VERSION_CODE >= 0x20616)
+	for_each_netdev(dev)
+#else
+	for (dev = dev_base; dev; dev = dev->next)
+#endif
+	{
+
+		struct ethtool_drvinfo drvinfo;
+		// char *str=NULL;
+		char cbuf[32];
+		char *buf = NULL;
+		char res[10];
+		int i = 0;
+		int bus = 0, slot = 0, func = 0;
+		ifindex = dev->ifindex;
+
+		memset(res, 0, 10);
+		memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
+
+		if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) {
+			memset(&drvinfo, 0, sizeof(drvinfo));
+			dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
+		} else
+			continue;
+		if (!drvinfo.bus_info)
+			continue;
+		if (!strcmp(drvinfo.bus_info, "N/A"))
+			continue;
+		memcpy(&cbuf, drvinfo.bus_info, 32);
+		buf = &cbuf[0];
+
+		// while(*buf++){
+
+		/*if(*buf==':'){
+		   buf++;
+		   break;
+		   } */
+		//}
+		while (*buf++ != ':') ;
+		for (i = 0; i < 10; i++, buf++) {
+			if (*buf == ':')
+				break;
+			res[i] = *buf;
+
+		}
+		buf++;
+		bus = str_to_hex(res);
+		memset(res, 0, 10);
+
+		for (i = 0; i < 10; i++, buf++) {
+			if (*buf == '.')
+				break;
+			res[i] = *buf;
+
+		}
+		buf++;
+		slot = str_to_hex(res);
+		func = str_to_hex(buf);
+		idx_dev = get_dev_idx_bsf(bus, slot, func);
+
+		if (idx_dev != -1) {
+
+			bpctl_dev_arr[idx_dev].ifindex = ifindex;
+			bpctl_dev_arr[idx_dev].ndev = dev;
+
+		}
+
+	}
+#endif
+	//rtnl_unlock();
+	//rcu_read_unlock();
+
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+static int device_ioctl(struct inode *inode,	/* see include/linux/fs.h */
+			struct file *file,	/* ditto */
+			unsigned int ioctl_num,	/* number and param for ioctl */
+			unsigned long ioctl_param)
+#else
+static long device_ioctl(struct file *file,	/* ditto */
+			 unsigned int ioctl_num,	/* number and param for ioctl */
+			 unsigned long ioctl_param)
+#endif
+{
+	struct bpctl_cmd bpctl_cmd;
+	int dev_idx = 0;
+	bpctl_dev_t *pbpctl_dev_out;
+	void __user *argp = (void __user *)ioctl_param;
+	int ret = 0;
+	unsigned long flags;
+
+	static 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
+*/
+	if (ioctl_num == IOCTL_TX_MSG(IF_SCAN)) {
+		if_scan_init();
+		ret = SUCCESS;
+		goto bp_exit;
+	}
+	if (copy_from_user(&bpctl_cmd, argp, sizeof(struct bpctl_cmd))) {
+
+		ret = -EFAULT;
+		goto bp_exit;
+	}
+
+	if (ioctl_num == IOCTL_TX_MSG(GET_DEV_NUM)) {
+		bpctl_cmd.out_param[0] = device_num;
+		if (copy_to_user
+		    (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) {
+			ret = -EFAULT;
+			goto bp_exit;
+		}
+		ret = SUCCESS;
+		goto bp_exit;
+
+	}
+	//lock_bpctl(); 
+	//preempt_disable();
+	local_irq_save(flags);
+	if (!spin_trylock(&bpvm_lock)) {
+		local_irq_restore(flags);
+		unlock_bpctl();
+		//unlock_kernel();
+		return -1;
+	}
+//    preempt_disable();
+	//rcu_read_lock();
+//    spin_lock_irqsave(&bpvm_lock, flags);
+	if ((bpctl_cmd.in_param[5]) ||
+	    (bpctl_cmd.in_param[6]) || (bpctl_cmd.in_param[7]))
+		dev_idx = get_dev_idx_bsf(bpctl_cmd.in_param[5],
+					  bpctl_cmd.in_param[6],
+					  bpctl_cmd.in_param[7]);
+	else if (bpctl_cmd.in_param[1] == 0)
+		dev_idx = bpctl_cmd.in_param[0];
+	else
+		dev_idx = get_dev_idx(bpctl_cmd.in_param[1]);
+
+	if (dev_idx < 0 || dev_idx > device_num) {
+		//unlock_bpctl();
+		//preempt_enable();
+		ret = -EOPNOTSUPP;
+		//preempt_enable();
+		//rcu_read_unlock();
+		spin_unlock_irqrestore(&bpvm_lock, flags);
+		goto bp_exit;
+	}
+
+	bpctl_cmd.out_param[0] = bpctl_dev_arr[dev_idx].bus;
+	bpctl_cmd.out_param[1] = bpctl_dev_arr[dev_idx].slot;
+	bpctl_cmd.out_param[2] = bpctl_dev_arr[dev_idx].func;
+	bpctl_cmd.out_param[3] = bpctl_dev_arr[dev_idx].ifindex;
+
+	if ((bpctl_dev_arr[dev_idx].bp_10gb)
+	    && (!(bpctl_dev_arr[dev_idx].ifindex))) {
+		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;
+
+	}
+	if ((bpctl_dev_arr[dev_idx].bp_10gb) && (bpctl_dev_arr[dev_idx].ndev)) {
+		if (!(bpctl_dev_arr[dev_idx].ndev->flags & IFF_UP)) {
+			if (!(bpctl_dev_arr[dev_idx].ndev->flags & IFF_UP)) {
+				printk
+				    ("Please bring up network interfaces 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;
+			}
+
+		}
+	}
+
+	if ((dev_idx < 0) || (dev_idx > device_num)
+	    || (bpctl_dev_arr[dev_idx].pdev == NULL)) {
+		bpctl_cmd.status = -1;
+		goto bpcmd_exit;
+	}
+
+	pbpctl_dev = &bpctl_dev_arr[dev_idx];
+
+	switch (ioctl_num) {
+	case IOCTL_TX_MSG(SET_BYPASS_PWOFF):
+		bpctl_cmd.status =
+		    set_bypass_pwoff_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_BYPASS_PWOFF):
+		bpctl_cmd.status = get_bypass_pwoff_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(SET_BYPASS_PWUP):
+		bpctl_cmd.status =
+		    set_bypass_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_BYPASS_PWUP):
+		bpctl_cmd.status = get_bypass_pwup_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(SET_BYPASS_WD):
+		bpctl_cmd.status =
+		    set_bypass_wd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_BYPASS_WD):
+		bpctl_cmd.status =
+		    get_bypass_wd_fn(pbpctl_dev, (int *)&(bpctl_cmd.data[0]));
+		break;
+
+	case IOCTL_TX_MSG(GET_WD_EXPIRE_TIME):
+		bpctl_cmd.status =
+		    get_wd_expire_time_fn(pbpctl_dev,
+					  (int *)&(bpctl_cmd.data[0]));
+		break;
+
+	case IOCTL_TX_MSG(RESET_BYPASS_WD_TIMER):
+		bpctl_cmd.status = reset_bypass_wd_timer_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(GET_WD_SET_CAPS):
+		bpctl_cmd.status = get_wd_set_caps_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(SET_STD_NIC):
+		bpctl_cmd.status =
+		    set_std_nic_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_STD_NIC):
+		bpctl_cmd.status = get_std_nic_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(SET_TAP):
+		bpctl_cmd.status =
+		    set_tap_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_TAP):
+		bpctl_cmd.status = get_tap_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(GET_TAP_CHANGE):
+		bpctl_cmd.status = get_tap_change_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(SET_DIS_TAP):
+		bpctl_cmd.status =
+		    set_dis_tap_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_DIS_TAP):
+		bpctl_cmd.status = get_dis_tap_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(SET_TAP_PWUP):
+		bpctl_cmd.status =
+		    set_tap_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_TAP_PWUP):
+		bpctl_cmd.status = get_tap_pwup_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(SET_WD_EXP_MODE):
+		bpctl_cmd.status =
+		    set_wd_exp_mode_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_WD_EXP_MODE):
+		bpctl_cmd.status = get_wd_exp_mode_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(GET_DIS_BYPASS):
+		bpctl_cmd.status = get_dis_bypass_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(SET_DIS_BYPASS):
+		bpctl_cmd.status =
+		    set_dis_bypass_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_BYPASS_CHANGE):
+		bpctl_cmd.status = get_bypass_change_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(GET_BYPASS):
+		bpctl_cmd.status = get_bypass_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(SET_BYPASS):
+		bpctl_cmd.status =
+		    set_bypass_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	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;
+		}
+		goto bp_exit;
+
+	case IOCTL_TX_MSG(GET_BYPASS_SLAVE):
+		bpctl_cmd.status =
+		    get_bypass_slave_fn(pbpctl_dev, &pbpctl_dev_out);
+		if (bpctl_cmd.status == 1) {
+			bpctl_cmd.out_param[4] = pbpctl_dev_out->bus;
+			bpctl_cmd.out_param[5] = pbpctl_dev_out->slot;
+			bpctl_cmd.out_param[6] = pbpctl_dev_out->func;
+			bpctl_cmd.out_param[7] = pbpctl_dev_out->ifindex;
+		}
+		break;
+
+	case IOCTL_TX_MSG(IS_BYPASS):
+		bpctl_cmd.status = is_bypass(pbpctl_dev);
+		break;
+	case IOCTL_TX_MSG(SET_TX):
+		bpctl_cmd.status = set_tx_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+	case IOCTL_TX_MSG(GET_TX):
+		bpctl_cmd.status = get_tx_fn(pbpctl_dev);
+		break;
+	case IOCTL_TX_MSG(SET_WD_AUTORESET):
+		bpctl_cmd.status =
+		    set_wd_autoreset_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+
+		break;
+	case IOCTL_TX_MSG(GET_WD_AUTORESET):
+
+		bpctl_cmd.status = get_wd_autoreset_fn(pbpctl_dev);
+		break;
+	case IOCTL_TX_MSG(SET_DISC):
+		bpctl_cmd.status =
+		    set_disc_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+	case IOCTL_TX_MSG(GET_DISC):
+		bpctl_cmd.status = get_disc_fn(pbpctl_dev);
+		break;
+	case IOCTL_TX_MSG(GET_DISC_CHANGE):
+		bpctl_cmd.status = get_disc_change_fn(pbpctl_dev);
+		break;
+	case IOCTL_TX_MSG(SET_DIS_DISC):
+		bpctl_cmd.status =
+		    set_dis_disc_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+	case IOCTL_TX_MSG(GET_DIS_DISC):
+		bpctl_cmd.status = get_dis_disc_fn(pbpctl_dev);
+		break;
+	case IOCTL_TX_MSG(SET_DISC_PWUP):
+		bpctl_cmd.status =
+		    set_disc_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+	case IOCTL_TX_MSG(GET_DISC_PWUP):
+		bpctl_cmd.status = get_disc_pwup_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(GET_BYPASS_INFO):
+
+		bpctl_cmd.status =
+		    get_bypass_info_fn(pbpctl_dev, (char *)&bpctl_cmd.data,
+				       (char *)&bpctl_cmd.out_param[4]);
+		break;
+
+	case IOCTL_TX_MSG(SET_TPL):
+		bpctl_cmd.status =
+		    set_tpl_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_TPL):
+		bpctl_cmd.status = get_tpl_fn(pbpctl_dev);
+		break;
+//#ifdef PMC_FIX_FLAG
+	case IOCTL_TX_MSG(SET_BP_WAIT_AT_PWUP):
+		bpctl_cmd.status =
+		    set_bp_wait_at_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_BP_WAIT_AT_PWUP):
+		bpctl_cmd.status = get_bp_wait_at_pwup_fn(pbpctl_dev);
+		break;
+	case IOCTL_TX_MSG(SET_BP_HW_RESET):
+		bpctl_cmd.status =
+		    set_bp_hw_reset_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_BP_HW_RESET):
+		bpctl_cmd.status = get_bp_hw_reset_fn(pbpctl_dev);
+		break;
+//#endif
+#ifdef BP_SELF_TEST
+	case IOCTL_TX_MSG(SET_BP_SELF_TEST):
+		bpctl_cmd.status =
+		    set_bp_self_test_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+
+		break;
+	case IOCTL_TX_MSG(GET_BP_SELF_TEST):
+		bpctl_cmd.status = get_bp_self_test_fn(pbpctl_dev);
+		break;
+
+#endif
+#if 0
+	case IOCTL_TX_MSG(SET_DISC_PORT):
+		bpctl_cmd.status =
+		    set_disc_port_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_DISC_PORT):
+		bpctl_cmd.status = get_disc_port_fn(pbpctl_dev);
+		break;
+
+	case IOCTL_TX_MSG(SET_DISC_PORT_PWUP):
+		bpctl_cmd.status =
+		    set_disc_port_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_DISC_PORT_PWUP):
+		bpctl_cmd.status = get_disc_port_pwup_fn(pbpctl_dev);
+		break;
+#endif
+	case IOCTL_TX_MSG(SET_BP_FORCE_LINK):
+		bpctl_cmd.status =
+		    set_bp_force_link_fn(dev_idx, bpctl_cmd.in_param[2]);
+		break;
+
+	case IOCTL_TX_MSG(GET_BP_FORCE_LINK):
+		bpctl_cmd.status = get_bp_force_link_fn(dev_idx);
+		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;
+}
+
+struct file_operations Fops = {
+	.owner = THIS_MODULE,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
+	.ioctl = device_ioctl,
+#else
+	.unlocked_ioctl = device_ioctl,
+#endif
+
+	.open = device_open,
+	.release = device_release,	/* a.k.a. close */
+};
+
+#ifndef PCI_DEVICE
+#define PCI_DEVICE(vend,dev) \
+	.vendor = (vend), .device = (dev), \
+	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
+#endif
+
+#define SILICOM_E1000BP_ETHERNET_DEVICE(device_id) {\
+	PCI_DEVICE(SILICOM_VID, device_id)}
+
+typedef enum {
+	PXG2BPFI,
+	PXG2BPFIL,
+	PXG2BPFILX,
+	PXG2BPFILLX,
+	PXGBPI,
+	PXGBPIG,
+	PXG2TBFI,
+	PXG4BPI,
+	PXG4BPFI,
+	PEG4BPI,
+	PEG2BPI,
+	PEG4BPIN,
+	PEG2BPFI,
+	PEG2BPFILX,
+	PMCXG2BPFI,
+	PMCXG2BPFIN,
+	PEG4BPII,
+	PEG4BPFII,
+	PXG4BPFILX,
+	PMCXG2BPIN,
+	PMCXG4BPIN,
+	PXG2BISC1,
+	PEG2TBFI,
+	PXG2TBI,
+	PXG4BPFID,
+	PEG4BPFI,
+	PEG4BPIPT,
+	PXG6BPI,
+	PEG4BPIL,
+	PMCXG2BPIN2,
+	PMCXG4BPIN2,
+	PMCX2BPI,
+	PEG2BPFID,
+	PEG2BPFIDLX,
+	PMCX4BPI,
+	MEG2BPFILN,
+	MEG2BPFINX,
+	PEG4BPFILX,
+	PE10G2BPISR,
+	PE10G2BPILR,
+	MHIO8AD,
+	PE10G2BPICX4,
+	PEG2BPI5,
+	PEG6BPI,
+	PEG4BPFI5,
+	PEG4BPFI5LX,
+	MEG2BPFILXLN,
+	PEG2BPIX1,
+	MEG2BPFILXNX,
+	XE10G2BPIT,
+	XE10G2BPICX4,
+	XE10G2BPISR,
+	XE10G2BPILR,
+	PEG4BPIIO,
+	XE10G2BPIXR,
+	PE10GDBISR,
+	PE10GDBILR,
+	PEG2BISC6,
+	PEG6BPIFC,
+	PE10G2BPTCX4,
+	PE10G2BPTSR,
+	PE10G2BPTLR,
+	PE10G2BPTT,
+	PEG4BPI6,
+	PEG4BPFI6,
+	PEG4BPFI6LX,
+	PEG4BPFI6ZX,
+	PEG2BPI6,
+	PEG2BPFI6,
+	PEG2BPFI6LX,
+	PEG2BPFI6ZX,
+	PEG2BPFI6FLXM,
+	PEG4BPI6FC,
+	PEG4BPFI6FC,
+	PEG4BPFI6FCLX,
+	PEG4BPFI6FCZX,
+	PEG6BPI6,
+	PEG2BPI6SC6,
+	MEG2BPI6,
+	XEG2BPI6,
+	MEG4BPI6,
+	PEG2BPFI5,
+	PEG2BPFI5LX,
+	PXEG4BPFI,
+	M1EG2BPI6,
+	M1EG2BPFI6,
+	M1EG2BPFI6LX,
+	M1EG2BPFI6ZX,
+	M1EG4BPI6,
+	M1EG4BPFI6,
+	M1EG4BPFI6LX,
+	M1EG4BPFI6ZX,
+	M1EG6BPI6,
+	M1E2G4BPi80,
+	M1E2G4BPFi80,
+	M1E2G4BPFi80LX,
+	M1E2G4BPFi80ZX,
+	PE210G2SPI9,
+	M1E10G2BPI9CX4,
+	M1E10G2BPI9SR,
+	M1E10G2BPI9LR,
+	M1E10G2BPI9T,
+	PE210G2BPI9CX4,
+	PE210G2BPI9SR,
+	PE210G2BPI9LR,
+	PE210G2BPI9T,
+	M2EG2BPFI6,
+	M2EG2BPFI6LX,
+	M2EG2BPFI6ZX,
+	M2EG4BPI6,
+	M2EG4BPFI6,
+	M2EG4BPFI6LX,
+	M2EG4BPFI6ZX,
+	M2EG6BPI6,
+	PEG2DBI6,
+	PEG2DBFI6,
+	PEG2DBFI6LX,
+	PEG2DBFI6ZX,
+	PE2G4BPi80,
+	PE2G4BPFi80,
+	PE2G4BPFi80LX,
+	PE2G4BPFi80ZX,
+	PE2G4BPi80L,
+	M6E2G8BPi80A,
+
+	PE2G2BPi35,
+	PAC1200BPi35,
+	PE2G2BPFi35,
+	PE2G2BPFi35LX,
+	PE2G2BPFi35ZX,
+	PE2G4BPi35,
+	PE2G4BPi35L,
+	PE2G4BPFi35,
+	PE2G4BPFi35LX,
+	PE2G4BPFi35ZX,
+
+	PE2G6BPi35,
+	PE2G6BPi35CX,
+
+	PE2G2BPi80,
+	PE2G2BPFi80,
+	PE2G2BPFi80LX,
+	PE2G2BPFi80ZX,
+	M2E10G2BPI9CX4,
+	M2E10G2BPI9SR,
+	M2E10G2BPI9LR,
+	M2E10G2BPI9T,
+	M6E2G8BPi80,
+	PE210G2DBi9SR,
+	PE210G2DBi9SRRB,
+	PE210G2DBi9LR,
+	PE210G2DBi9LRRB,
+	PE310G4DBi940SR,
+	PE310G4BPi9T,
+	PE310G4BPi9SR,
+	PE310G4BPi9LR,
+	PE210G2BPi40,
+} board_t;
+
+typedef struct _bpmod_info_t {
+	unsigned int vendor;
+	unsigned int device;
+	unsigned int subvendor;
+	unsigned int subdevice;
+	unsigned int index;
+	char *bp_name;
+
+} bpmod_info_t;
+
+typedef struct _dev_desc {
+	char *name;
+} dev_desc_t;
+
+dev_desc_t dev_desc[] = {
+	{"Silicom Bypass PXG2BPFI-SD series adapter"},
+	{"Silicom Bypass PXG2BPFIL-SD series adapter"},
+	{"Silicom Bypass PXG2BPFILX-SD series adapter"},
+	{"Silicom Bypass PXG2BPFILLX-SD series adapter"},
+	{"Silicom Bypass PXG2BPI-SD series adapter"},
+	{"Silicom Bypass PXG2BPIG-SD series adapter"},
+	{"Silicom Bypass PXG2TBFI-SD series adapter"},
+	{"Silicom Bypass PXG4BPI-SD series adapter"},
+	{"Silicom Bypass PXG4BPFI-SD series adapter"},
+	{"Silicom Bypass PEG4BPI-SD series adapter"},
+	{"Silicom Bypass PEG2BPI-SD series adapter"},
+	{"Silicom Bypass PEG4BPIN-SD series adapter"},
+	{"Silicom Bypass PEG2BPFI-SD series adapter"},
+	{"Silicom Bypass PEG2BPFI-LX-SD series adapter"},
+	{"Silicom Bypass PMCX2BPFI-SD series adapter"},
+	{"Silicom Bypass PMCX2BPFI-N series adapter"},
+	{"Intel Bypass PEG2BPII series adapter"},
+	{"Intel Bypass PEG2BPFII series adapter"},
+	{"Silicom Bypass PXG4BPFILX-SD series adapter"},
+	{"Silicom Bypass PMCX2BPI-N series adapter"},
+	{"Silicom Bypass PMCX4BPI-N series adapter"},
+	{"Silicom Bypass PXG2BISC1-SD series adapter"},
+	{"Silicom Bypass PEG2TBFI-SD series adapter"},
+	{"Silicom Bypass PXG2TBI-SD series adapter"},
+	{"Silicom Bypass PXG4BPFID-SD series adapter"},
+	{"Silicom Bypass PEG4BPFI-SD series adapter"},
+	{"Silicom Bypass PEG4BPIPT-SD series adapter"},
+	{"Silicom Bypass PXG6BPI-SD series adapter"},
+	{"Silicom Bypass PEG4BPIL-SD series adapter"},
+	{"Silicom Bypass PMCX2BPI-N2 series adapter"},
+	{"Silicom Bypass PMCX4BPI-N2 series adapter"},
+	{"Silicom Bypass PMCX2BPI-SD series adapter"},
+	{"Silicom Bypass PEG2BPFID-SD series adapter"},
+	{"Silicom Bypass PEG2BPFIDLX-SD series adapter"},
+	{"Silicom Bypass PMCX4BPI-SD series adapter"},
+	{"Silicom Bypass MEG2BPFILN-SD series adapter"},
+	{"Silicom Bypass MEG2BPFINX-SD series adapter"},
+	{"Silicom Bypass PEG4BPFILX-SD series adapter"},
+	{"Silicom Bypass PE10G2BPISR-SD series adapter"},
+	{"Silicom Bypass PE10G2BPILR-SD series adapter"},
+	{"Silicom Bypass MHIO8AD-SD series adapter"},
+	{"Silicom Bypass PE10G2BPICX4-SD series adapter"},
+	{"Silicom Bypass PEG2BPI5-SD series adapter"},
+	{"Silicom Bypass PEG6BPI5-SD series adapter"},
+	{"Silicom Bypass PEG4BPFI5-SD series adapter"},
+	{"Silicom Bypass PEG4BPFI5LX-SD series adapter"},
+	{"Silicom Bypass MEG2BPFILXLN-SD series adapter"},
+	{"Silicom Bypass PEG2BPIX1-SD series adapter"},
+	{"Silicom Bypass MEG2BPFILXNX-SD series adapter"},
+	{"Silicom Bypass XE10G2BPIT-SD series adapter"},
+	{"Silicom Bypass XE10G2BPICX4-SD series adapter"},
+	{"Silicom Bypass XE10G2BPISR-SD series adapter"},
+	{"Silicom Bypass XE10G2BPILR-SD series adapter"},
+	{"Intel Bypass PEG2BPFII0 series adapter"},
+	{"Silicom Bypass XE10G2BPIXR series adapter"},
+	{"Silicom Bypass PE10G2DBISR series adapter"},
+	{"Silicom Bypass PEG2BI5SC6 series adapter"},
+	{"Silicom Bypass PEG6BPI5FC series adapter"},
+
+	{"Silicom Bypass PE10G2BPTCX4 series adapter"},
+	{"Silicom Bypass PE10G2BPTSR series adapter"},
+	{"Silicom Bypass PE10G2BPTLR series adapter"},
+	{"Silicom Bypass PE10G2BPTT series adapter"},
+	{"Silicom Bypass PEG4BPI6 series adapter"},
+	{"Silicom Bypass PEG4BPFI6 series adapter"},
+	{"Silicom Bypass PEG4BPFI6LX series adapter"},
+	{"Silicom Bypass PEG4BPFI6ZX series adapter"},
+	{"Silicom Bypass PEG2BPI6 series adapter"},
+	{"Silicom Bypass PEG2BPFI6 series adapter"},
+	{"Silicom Bypass PEG2BPFI6LX series adapter"},
+	{"Silicom Bypass PEG2BPFI6ZX series adapter"},
+	{"Silicom Bypass PEG2BPFI6FLXM series adapter"},
+	{"Silicom Bypass PEG4BPI6FC series adapter"},
+	{"Silicom Bypass PEG4BPFI6FC series adapter"},
+	{"Silicom Bypass PEG4BPFI6FCLX series adapter"},
+	{"Silicom Bypass PEG4BPFI6FCZX series adapter"},
+	{"Silicom Bypass PEG6BPI6 series adapter"},
+	{"Silicom Bypass PEG2BPI6SC6 series adapter"},
+	{"Silicom Bypass MEG2BPI6 series adapter"},
+	{"Silicom Bypass XEG2BPI6 series adapter"},
+	{"Silicom Bypass MEG4BPI6 series adapter"},
+	{"Silicom Bypass PEG2BPFI5-SD series adapter"},
+	{"Silicom Bypass PEG2BPFI5LX-SD series adapter"},
+	{"Silicom Bypass PXEG4BPFI-SD series adapter"},
+	{"Silicom Bypass MxEG2BPI6 series adapter"},
+	{"Silicom Bypass MxEG2BPFI6 series adapter"},
+	{"Silicom Bypass MxEG2BPFI6LX series adapter"},
+	{"Silicom Bypass MxEG2BPFI6ZX series adapter"},
+	{"Silicom Bypass MxEG4BPI6 series adapter"},
+	{"Silicom Bypass MxEG4BPFI6 series adapter"},
+	{"Silicom Bypass MxEG4BPFI6LX series adapter"},
+	{"Silicom Bypass MxEG4BPFI6ZX series adapter"},
+	{"Silicom Bypass MxEG6BPI6 series adapter"},
+	{"Silicom Bypass MxE2G4BPi80 series adapter"},
+	{"Silicom Bypass MxE2G4BPFi80 series adapter"},
+	{"Silicom Bypass MxE2G4BPFi80LX series adapter"},
+	{"Silicom Bypass MxE2G4BPFi80ZX series adapter"},
+
+	{"Silicom Bypass PE210G2SPI9 series adapter"},
+
+	{"Silicom Bypass MxE210G2BPI9CX4 series adapter"},
+	{"Silicom Bypass MxE210G2BPI9SR series adapter"},
+	{"Silicom Bypass MxE210G2BPI9LR series adapter"},
+	{"Silicom Bypass MxE210G2BPI9T series adapter"},
+
+	{"Silicom Bypass PE210G2BPI9CX4 series adapter"},
+	{"Silicom Bypass PE210G2BPI9SR series adapter"},
+	{"Silicom Bypass PE210G2BPI9LR series adapter"},
+	{"Silicom Bypass PE210G2BPI9T series adapter"},
+
+	{"Silicom Bypass M2EG2BPFI6 series adapter"},
+	{"Silicom Bypass M2EG2BPFI6LX series adapter"},
+	{"Silicom Bypass M2EG2BPFI6ZX series adapter"},
+	{"Silicom Bypass M2EG4BPI6 series adapter"},
+	{"Silicom Bypass M2EG4BPFI6 series adapter"},
+	{"Silicom Bypass M2EG4BPFI6LX series adapter"},
+	{"Silicom Bypass M2EG4BPFI6ZX series adapter"},
+	{"Silicom Bypass M2EG6BPI6 series adapter"},
+
+	{"Silicom Bypass PEG2DBI6    series adapter"},
+	{"Silicom Bypass PEG2DBFI6   series adapter"},
+	{"Silicom Bypass PEG2DBFI6LX series adapter"},
+	{"Silicom Bypass PEG2DBFI6ZX series adapter"},
+
+	{"Silicom Bypass PE2G4BPi80 series adapter"},
+	{"Silicom Bypass PE2G4BPFi80 series adapter"},
+	{"Silicom Bypass PE2G4BPFi80LX series adapter"},
+	{"Silicom Bypass PE2G4BPFi80ZX series adapter"},
+
+	{"Silicom Bypass PE2G4BPi80L series adapter"},
+	{"Silicom Bypass MxE2G8BPi80A series adapter"},
+
+	{"Silicom Bypass PE2G2BPi35 series adapter"},
+	{"Silicom Bypass PAC1200BPi35 series adapter"},
+	{"Silicom Bypass PE2G2BPFi35 series adapter"},
+	{"Silicom Bypass PE2G2BPFi35LX series adapter"},
+	{"Silicom Bypass PE2G2BPFi35ZX series adapter"},
+
+	{"Silicom Bypass PE2G4BPi35 series adapter"},
+	{"Silicom Bypass PE2G4BPi35L series adapter"},
+	{"Silicom Bypass PE2G4BPFi35 series adapter"},
+	{"Silicom Bypass PE2G4BPFi35LX series adapter"},
+	{"Silicom Bypass PE2G4BPFi35ZX series adapter"},
+
+	{"Silicom Bypass PE2G6BPi35 series adapter"},
+	{"Silicom Bypass PE2G6BPi35CX series adapter"},
+
+	{"Silicom Bypass PE2G2BPi80 series adapter"},
+	{"Silicom Bypass PE2G2BPFi80 series adapter"},
+	{"Silicom Bypass PE2G2BPFi80LX series adapter"},
+	{"Silicom Bypass PE2G2BPFi80ZX series adapter"},
+
+	{"Silicom Bypass M2E10G2BPI9CX4 series adapter"},
+	{"Silicom Bypass M2E10G2BPI9SR series adapter"},
+	{"Silicom Bypass M2E10G2BPI9LR series adapter"},
+	{"Silicom Bypass M2E10G2BPI9T series adapter"},
+	{"Silicom Bypass MxE2G8BPi80 series adapter"},
+	{"Silicom Bypass PE210G2DBi9SR series adapter"},
+	{"Silicom Bypass PE210G2DBi9SRRB series adapter"},
+	{"Silicom Bypass PE210G2DBi9LR series adapter"},
+	{"Silicom Bypass PE210G2DBi9LRRB series adapter"},
+	{"Silicom Bypass PE310G4DBi9-SR series adapter"},
+	{"Silicom Bypass PE310G4BPi9T series adapter"},
+	{"Silicom Bypass PE310G4BPi9SR series adapter"},
+	{"Silicom Bypass PE310G4BPi9LR series adapter"},
+	{"Silicom Bypass PE210G2BPi40T series adapter"},
+	{0},
+};
+
+static bpmod_info_t tx_ctl_pci_tbl[] = {
+	{0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFI_SSID, PXG2BPFI,
+	 "PXG2BPFI-SD"},
+	{0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFIL_SSID, PXG2BPFIL,
+	 "PXG2BPFIL-SD"},
+	{0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILX_SSID, PXG2BPFILX,
+	 "PXG2BPFILX-SD"},
+	{0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILLX_SSID, PXG2BPFILLX,
+	 "PXG2BPFILLXSD"},
+	{0x8086, 0x1010, SILICOM_SVID, SILICOM_PXGBPI_SSID, PXGBPI,
+	 "PXG2BPI-SD"},
+	{0x8086, 0x1079, SILICOM_SVID, SILICOM_PXGBPIG_SSID, PXGBPIG,
+	 "PXG2BPIG-SD"},
+	{0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2TBFI_SSID, PXG2TBFI,
+	 "PXG2TBFI-SD"},
+	{0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI,
+	 "PXG4BPI-SD"},
+	{0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI,
+	 "PXG4BPFI-SD"},
+	{0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFILX_SSID, PXG4BPFILX,
+	 "PXG4BPFILX-SD"},
+	{0x8086, 0x1079, SILICOM_SVID, SILICOM_PEG4BPI_SSID, PEG4BPI,
+	 "PEXG4BPI-SD"},
+	{0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPI_SSID, PEG2BPI,
+	 "PEG2BPI-SD"},
+	{0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIN_SSID, PEG4BPIN,
+	 "PEG4BPI-SD"},
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFI_SSID, PEG2BPFI,
+	 "PEG2BPFI-SD"},
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFILX_SSID, PEG2BPFILX,
+	 "PEG2BPFILX-SD"},
+	{0x8086, 0x107a, SILICOM_SVID, SILICOM_PMCXG2BPFI_SSID, PMCXG2BPFI,
+	 "PMCX2BPFI-SD"},
+	{0x8086, 0x107a, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPFIN_SSID,
+	 PMCXG2BPFIN, "PMCX2BPFI-N"},
+	{0x8086, INTEL_PEG4BPII_PID, 0x8086, INTEL_PEG4BPII_SSID, PEG4BPII,
+	 "PEG4BPII"},
+	{0x8086, INTEL_PEG4BPIIO_PID, 0x8086, INTEL_PEG4BPIIO_SSID, PEG4BPIIO,
+	 "PEG4BPII0"},
+	{0x8086, INTEL_PEG4BPFII_PID, 0x8086, INTEL_PEG4BPFII_SSID, PEG4BPFII,
+	 "PEG4BPFII"},
+	{0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN_SSID,
+	 PMCXG2BPIN, "PMCX2BPI-N"},
+	{0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN_SSID,
+	 PMCXG4BPIN, "PMCX4BPI-N"},
+	{0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1,
+	 "PXG2BISC1-SD"},
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2TBFI_SSID, PEG2TBFI,
+	 "PEG2TBFI-SD"},
+	{0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI,
+	 "PXG2TBI-SD"},
+	{0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFID_SSID, PXG4BPFID,
+	 "PXG4BPFID-SD"},
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI,
+	 "PEG4BPFI-SD"},
+	{0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIPT_SSID, PEG4BPIPT,
+	 "PEG4BPIPT-SD"},
+	{0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG6BPI_SSID, PXG6BPI,
+	 "PXG6BPI-SD"},
+	{0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG4BPIL_SSID /*PCI_ANY_ID */ , PEG4BPIL, "PEG4BPIL-SD"},
+	{0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN2_SSID,
+	 PMCXG2BPIN2, "PMCX2BPI-N2"},
+	{0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN2_SSID,
+	 PMCXG4BPIN2, "PMCX4BPI-N2"},
+	{0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX2BPI_SSID, PMCX2BPI,
+	 "PMCX2BPI-SD"},
+	{0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX4BPI_SSID, PMCX4BPI,
+	 "PMCX4BPI-SD"},
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFID_SSID, PEG2BPFID,
+	 "PEG2BPFID-SD"},
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFIDLX_SSID, PEG2BPFIDLX,
+	 "PEG2BPFIDLXSD"},
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILN_SSID, MEG2BPFILN,
+	 "MEG2BPFILN-SD"},
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFINX_SSID, MEG2BPFINX,
+	 "MEG2BPFINX-SD"},
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFILX_SSID, PEG4BPFILX,
+	 "PEG4BPFILX-SD"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPISR_SSID,
+	 PE10G2BPISR, "PE10G2BPISR"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPILR_SSID,
+	 PE10G2BPILR, "PE10G2BPILR"},
+	{0x8086, 0x10a9, SILICOM_SVID, SILICOM_MHIO8AD_SSID, MHIO8AD,
+	 "MHIO8AD-SD"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPICX4_SSID,
+	 PE10G2BPISR, "PE10G2BPICX4"},
+	{0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2BPI5_SSID /*PCI_ANY_ID */ , PEG2BPI5, "PEG2BPI5-SD"},
+	{0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG6BPI_SSID /*PCI_ANY_ID */ , PEG6BPI, "PEG6BPI5"},
+	{0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG4BPFI5_SSID,
+	 PEG4BPFI5, "PEG4BPFI5"},
+	{0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG4BPFI5LX_SSID, PEG4BPFI5LX, "PEG4BPFI5LX"},
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXLN_SSID, MEG2BPFILXLN,
+	 "MEG2BPFILXLN"},
+	{0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPIX1_SSID, PEG2BPIX1,
+	 "PEG2BPIX1-SD"},
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXNX_SSID, MEG2BPFILXNX,
+	 "MEG2BPFILXNX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPIT_SSID, XE10G2BPIT,
+	 "XE10G2BPIT"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPICX4_SSID,
+	 XE10G2BPICX4, "XE10G2BPICX4"},
+	{0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPISR_SSID, XE10G2BPISR,
+	 "XE10G2BPISR"},
+	{0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPILR_SSID, XE10G2BPILR,
+	 "XE10G2BPILR"},
+	{0x8086, 0x10C6, NOKIA_XE10G2BPIXR_SVID, NOKIA_XE10G2BPIXR_SSID,
+	 XE10G2BPIXR, "XE10G2BPIXR"},
+	{0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBISR_SSID, PE10GDBISR,
+	 "PE10G2DBISR"},
+	{0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBILR_SSID, PE10GDBILR,
+	 "PE10G2DBILR"},
+	{0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2BISC6_SSID /*PCI_ANY_ID */ , PEG2BISC6, "PEG2BI5SC6"},
+	{0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG6BPIFC_SSID /*PCI_ANY_ID */ , PEG6BPIFC, "PEG6BPI5FC"},
+
+	{BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
+	 SILICOM_PE10G2BPTCX4_SSID, PE10G2BPTCX4, "PE10G2BPTCX4"},
+	{BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
+	 SILICOM_PE10G2BPTSR_SSID, PE10G2BPTSR, "PE10G2BPTSR"},
+	{BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
+	 SILICOM_PE10G2BPTLR_SSID, PE10G2BPTLR, "PE10G2BPTLR"},
+	{BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
+	 SILICOM_PE10G2BPTT_SSID, PE10G2BPTT, "PE10G2BPTT"},
+
+	//{BROADCOM_VID, BROADCOM_PE10G2_PID, PCI_ANY_ID, PCI_ANY_ID, PE10G2BPTCX4, "PE10G2BPTCX4"},
+
+	{0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG4BPI6_SSID /*PCI_ANY_ID */ , PEG4BPI6, "PEG4BPI6"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG4BPFI6_SSID /*PCI_ANY_ID */ , PEG4BPFI6, "PEG4BPFI6"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG4BPFI6LX_SSID /*PCI_ANY_ID */ , PEG4BPFI6LX, "PEG4BPFI6LX"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG4BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6ZX, "PEG4BPFI6ZX"},
+	{0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2BPI6_SSID /*PCI_ANY_ID */ , PEG2BPI6, "PEG2BPI6"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2BPFI6_SSID /*PCI_ANY_ID */ , PEG2BPFI6, "PEG2BPFI6"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2BPFI6LX_SSID /*PCI_ANY_ID */ , PEG2BPFI6LX, "PEG2BPFI6LX"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG2BPFI6ZX, "PEG2BPFI6ZX"},
+	{0x8086, 0x10e7, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2BPFI6FLXM_SSID /*PCI_ANY_ID */ , PEG2BPFI6FLXM,
+	 "PEG2BPFI6FLXM"},
+	{0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG4BPI6FC_SSID /*PCI_ANY_ID */ , PEG4BPI6FC, "PEG4BPI6FC"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG4BPFI6FC_SSID /*PCI_ANY_ID */ , PEG4BPFI6FC, "PEG4BPFI6FC"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG4BPFI6FCLX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCLX,
+	 "PEG4BPFI6FCLX"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG4BPFI6FCZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCZX,
+	 "PEG4BPFI6FCZX"},
+	{0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG6BPI6_SSID /*PCI_ANY_ID */ , PEG6BPI6, "PEG6BPI6"},
+	{0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2BPI6SC6_SSID /*PCI_ANY_ID */ , PEG2BPI6SC6,
+	 "PEG6BPI62SC6"},
+	{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_MEG4BPI6_SSID /*PCI_ANY_ID */ , MEG4BPI6, "MEG4BPI6"},
+
+	{0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG2BPFI5_SSID,
+	 PEG2BPFI5, "PEG2BPFI5"},
+	{0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2BPFI5LX_SSID, PEG2BPFI5LX, "PEG2BPFI5LX"},
+
+	{0x8086, 0x105f, SILICOM_SVID, SILICOM_PXEG4BPFI_SSID, PXEG4BPFI,
+	 "PXEG4BPFI-SD"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1EG2BPI6_SSID /*PCI_ANY_ID */ , M1EG2BPI6, "MxEG2BPI6"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1EG2BPFI6_SSID /*PCI_ANY_ID */ , M1EG2BPFI6, "MxEG2BPFI6"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6LX,
+	 "MxEG2BPFI6LX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6ZX,
+	 "MxEG2BPFI6ZX"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1EG4BPI6_SSID /*PCI_ANY_ID */ , M1EG4BPI6, "MxEG4BPI6"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1EG4BPFI6_SSID /*PCI_ANY_ID */ , M1EG4BPFI6, "MxEG4BPFI6"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6LX,
+	 "MxEG4BPFI6LX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6ZX,
+	 "MxEG4BPFI6ZX"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1EG6BPI6_SSID /*PCI_ANY_ID */ , M1EG6BPI6, "MxEG6BPI6"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1E2G4BPi80_SSID /*PCI_ANY_ID */ , M1E2G4BPi80, "MxE2G4BPi80"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1E2G4BPFi80_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80,
+	 "MxE2G4BPFi80"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1E2G4BPFi80LX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80LX,
+	 "MxE2G4BPFi80LX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1E2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80ZX,
+	 "MxE2G4BPFi80ZX"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M2EG2BPFI6_SSID /*PCI_ANY_ID */ , M2EG2BPFI6, "M2EG2BPFI6"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M2EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6LX,
+	 "M2EG2BPFI6LX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M2EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6ZX,
+	 "M2EG2BPFI6ZX"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M2EG4BPI6_SSID /*PCI_ANY_ID */ , M2EG4BPI6, "M2EG4BPI6"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M2EG4BPFI6_SSID /*PCI_ANY_ID */ , M2EG4BPFI6, "M2EG4BPFI6"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M2EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6LX,
+	 "M2EG4BPFI6LX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M2EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6ZX,
+	 "M2EG4BPFI6ZX"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M2EG6BPI6_SSID /*PCI_ANY_ID */ , M2EG6BPI6, "M2EG6BPI6"},
+
+	{0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2DBI6_SSID /*PCI_ANY_ID */ , PEG2DBI6, "PEG2DBI6"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2DBFI6_SSID /*PCI_ANY_ID */ , PEG2DBFI6, "PEG2DBFI6"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2DBFI6LX_SSID /*PCI_ANY_ID */ , PEG2DBFI6LX, "PEG2DBFI6LX"},
+	{0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PEG2DBFI6ZX_SSID /*PCI_ANY_ID */ , PEG2DBFI6ZX, "PEG2DBFI6ZX"},
+
+	{0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE210G2DBi9SR_SSID, PE210G2DBi9SR, "PE210G2DBi9SR"},
+	//{0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE210G2DBi9SRRB_SSID , PE210G2DBi9SRRB, "PE210G2DBi9SRRB"}, 
+	{0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE210G2DBi9LR_SSID, PE210G2DBi9LR, "PE210G2DBi9LR"},
+	//  {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE210G2DBi9LRRB_SSID , PE210G2DBi9LRRB, "PE210G2DBi9LRRB"}, 
+	{0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE310G4DBi940SR_SSID, PE310G4DBi940SR, "PE310G4DBi9SR"},
+
+	{0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE310G4BPi9T_SSID, PE310G4BPi9T, "PE310G4BPi9T"},
+	{0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE310G4BPi9SR_SSID, PE310G4BPi9SR, "PE310G4BPi9SR"},
+	{0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE310G4BPi9LR_SSID, PE310G4BPi9LR, "PE310G4BPi9LR"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G4BPi80_SSID /*PCI_ANY_ID */ , PE2G4BPi80, "PE2G4BPi80"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G4BPFi80_SSID /*PCI_ANY_ID */ , PE2G4BPFi80, "PE2G4BPFi80"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G4BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80LX,
+	 "PE2G4BPFi80LX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80ZX,
+	 "PE2G4BPFi80ZX"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G4BPi80L_SSID /*PCI_ANY_ID */ , PE2G4BPi80L, "PE2G4BPi80L"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M6E2G8BPi80A_SSID /*PCI_ANY_ID */ , M6E2G8BPi80A,
+	 "MxE2G8BPi80A"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G2BPi35_SSID /*PCI_ANY_ID */ , PE2G2BPi35, "PE2G2BPi35"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PAC1200BPi35_SSID /*PCI_ANY_ID */ , PAC1200BPi35,
+	 "PAC1200BPi35"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G2BPFi35_SSID /*PCI_ANY_ID */ , PE2G2BPFi35, "PE2G2BPFi35"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G2BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35LX,
+	 "PE2G2BPFi35LX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G2BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35ZX,
+	 "PE2G2BPFi35ZX"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G4BPi35_SSID /*PCI_ANY_ID */ , PE2G4BPi35, "PE2G4BPi35"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G4BPi35L_SSID /*PCI_ANY_ID */ , PE2G4BPi35L, "PE2G4BPi35L"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G4BPFi35_SSID /*PCI_ANY_ID */ , PE2G4BPFi35, "PE2G4BPFi35"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G4BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35LX,
+	 "PE2G4BPFi35LX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G4BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35ZX,
+	 "PE2G4BPFi35ZX"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G6BPi35_SSID /*PCI_ANY_ID */ , PE2G6BPi35, "PE2G6BPi35"},
+
+	// {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa0,PE2G6BPi35CX,"PE2G6BPi35CX"},
+	// {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa1,PE2G6BPi35CX,"PE2G6BPi35CX"},
+	// {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa2,PE2G6BPi35CX,"PE2G6BPi35CX"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa0, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa1, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa2, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa3, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa4, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa5, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa6, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa7, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa8, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa9, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaa, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaab, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaac, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaad, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaae, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaf, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab0, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab1, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab2, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab3, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab4, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab5, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab6, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab7, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab8, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab9, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaba, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabb, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabc, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabd, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabe, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabf, PE2G6BPi35CX,
+	 "PE2G6BPi35CX"},
+
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G2BPi80_SSID /*PCI_ANY_ID */ , PE2G2BPi80, "PE2G2BPi80"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G2BPFi80_SSID /*PCI_ANY_ID */ , PE2G2BPFi80, "PE2G2BPFi80"},
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE2G2BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi80LX,
+	 "PE2G2BPFi80LX"},
+	{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"},
+
+#if 0
+	{0x8086, 0x10fb, 0x8086, INTEL_PE210G2SPI9_SSID, PE210G2SPI9,
+	 "PE210G2SPI9"},
+#endif
+	{0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M1E10G2BPI9CX4_SSID /*PCI_ANY_ID */ , M1E10G2BPI9CX4,
+	 "MxE210G2BPI9CX4"},
+	{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_M1E10G2BPI9T_SSID /*PCI_ANY_ID */ , M1E10G2BPI9T,
+	 "MxE210G2BPI9T"},
+
+	{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, SILICOM_PE210G2BPI9CX4_SSID,
+	 PE210G2BPI9CX4, "PE210G2BPI9CX4"},
+	{0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9SR_SSID,
+	 PE210G2BPI9SR, "PE210G2BPI9SR"},
+	{0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9LR_SSID,
+	 PE210G2BPI9LR, "PE210G2BPI9LR"},
+	{0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9T_SSID, PE210G2BPI9T,
+	 "PE210G2BPI9T"},
+
+#if 0
+	{0x1374, 0x2c, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI,
+	 "PXG4BPI-SD"},
+
+	{0x1374, 0x2d, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI,
+	 "PXG4BPFI-SD"},
+
+	{0x1374, 0x3f, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI,
+	 "PXG2TBI-SD"},
+
+	{0x1374, 0x3d, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1,
+	 "PXG2BISC1-SD"},
+
+	{0x1374, 0x40, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI,
+	 "PEG4BPFI-SD"},
+
+#ifdef BP_SELF_TEST
+	{0x1374, 0x28, SILICOM_SVID, 0x28, PXGBPI, "PXG2BPI-SD"},
+#endif
+#endif
+	{0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_M6E2G8BPi80_SSID /*PCI_ANY_ID */ , M6E2G8BPi80, "MxE2G8BPi80"},
+	{0x8086, 0x1528, SILICOM_SVID /*PCI_ANY_ID */ ,
+	 SILICOM_PE210G2BPi40_SSID /*PCI_ANY_ID */ , PE210G2BPi40,
+	 "PE210G2BPi40T"},
+
+	/* required last entry */
+	{0,}
+};
+
+/*
+* Initialize the module - Register the character device
+*/
+
+static int __init 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");
+	ret_val = register_chrdev(major_num, DEVICE_NAME, &Fops);
+	if (ret_val < 0) {
+		printk("%s failed with %d\n", DEVICE_NAME, ret_val);
+		return ret_val;
+	}
+	major_num = ret_val;	/* dynamic */
+	for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) {
+		while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor,
+					       tx_ctl_pci_tbl[idx].device,
+					       tx_ctl_pci_tbl[idx].subvendor,
+					       tx_ctl_pci_tbl[idx].subdevice,
+					       pdev1))) {
+
+			device_num++;
+		}
+	}
+	if (!device_num) {
+		printk("No such device\n");
+		unregister_chrdev(major_num, DEVICE_NAME);
+		return -1;
+	}
+
+	bpctl_dev_arr = kmalloc((device_num) * sizeof(bpctl_dev_t), GFP_KERNEL);
+
+	if (!bpctl_dev_arr) {
+		printk("Allocation error\n");
+		unregister_chrdev(major_num, DEVICE_NAME);
+		return -1;
+	}
+	memset(bpctl_dev_arr, 0, ((device_num) * sizeof(bpctl_dev_t)));
+
+	pdev1 = NULL;
+	for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) {
+		while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor,
+					       tx_ctl_pci_tbl[idx].device,
+					       tx_ctl_pci_tbl[idx].subvendor,
+					       tx_ctl_pci_tbl[idx].subdevice,
+					       pdev1))) {
+			bpctl_dev_arr[idx_dev].pdev = pdev1;
+
+			mmio_start = pci_resource_start(pdev1, 0);
+			mmio_len = pci_resource_len(pdev1, 0);
+
+			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;
+			bpctl_dev_arr[idx_dev].device =
+			    tx_ctl_pci_tbl[idx].device;
+			bpctl_dev_arr[idx_dev].vendor =
+			    tx_ctl_pci_tbl[idx].vendor;
+			bpctl_dev_arr[idx_dev].subdevice =
+			    tx_ctl_pci_tbl[idx].subdevice;
+			bpctl_dev_arr[idx_dev].subvendor =
+			    tx_ctl_pci_tbl[idx].subvendor;
+			//bpctl_dev_arr[idx_dev].pdev=pdev1;
+			bpctl_dev_arr[idx_dev].func = PCI_FUNC(pdev1->devfn);
+			bpctl_dev_arr[idx_dev].slot = PCI_SLOT(pdev1->devfn);
+			bpctl_dev_arr[idx_dev].bus = pdev1->bus->number;
+			bpctl_dev_arr[idx_dev].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
+			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))
+				bpctl_dev_arr[idx_dev].bp_10g = 1;
+			if (PEG540_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) {
+
+				bpctl_dev_arr[idx_dev].bp_540 = 1;
+			}
+			if (PEGF5_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))
+				bpctl_dev_arr[idx_dev].bp_fiber5 = 1;
+			if (PEG80_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))
+				bpctl_dev_arr[idx_dev].bp_i80 = 1;
+			if (PEGF80_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice))
+				bpctl_dev_arr[idx_dev].bp_i80 = 1;
+			if ((bpctl_dev_arr[idx_dev].subdevice & 0xa00) == 0xa00)
+				bpctl_dev_arr[idx_dev].bp_i80 = 1;
+			if (BP10GB_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) {
+				if (bpctl_dev_arr[idx_dev].ifindex == 0) {
+					unregister_chrdev(major_num,
+							  DEVICE_NAME);
+					printk
+					    ("Please load network driver for %s adapter!\n",
+					     bpctl_dev_arr[idx_dev].name);
+					return -1;
+				}
+
+				if (bpctl_dev_arr[idx_dev].ndev) {
+					if (!
+					    (bpctl_dev_arr[idx_dev].ndev->
+					     flags & IFF_UP)) {
+						if (!
+						    (bpctl_dev_arr[idx_dev].
+						     ndev->flags & IFF_UP)) {
+							unregister_chrdev
+							    (major_num,
+							     DEVICE_NAME);
+							printk
+							    ("Please bring up network interfaces for %s adapter!\n",
+							     bpctl_dev_arr
+							     [idx_dev].name);
+							return -1;
+						}
+
+					}
+				}
+				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))) {
+
+				memset(bpctl_dev_arr[idx_dev].bp_tx_data, 0x0,
+				       BPTEST_DATA_LEN);
+
+				memset(bpctl_dev_arr[idx_dev].bp_tx_data, 0xff,
+				       6);
+				memset(bpctl_dev_arr[idx_dev].bp_tx_data + 6,
+				       0x0, 1);
+				memset(bpctl_dev_arr[idx_dev].bp_tx_data + 7,
+				       0xaa, 5);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
+				bpctl_dev_arr[idx_dev].bp_tx_data[12] =
+				    (ETH_P_BPTEST >> 8) & 0xff;
+				bpctl_dev_arr[idx_dev].bp_tx_data[13] =
+				    ETH_P_BPTEST & 0xff;
+#else
+				*(__be16 *) (bpctl_dev_arr[idx_dev].bp_tx_data +
+					     12) = htons(ETH_P_BPTEST);
+#endif
+
+			} else
+				printk("bp_ctl: Memory allocation error!\n");
+#endif
+			idx_dev++;
+
+		}
+	}
+	if_scan_init();
+
+	sema_init(&bpctl_sema, 1);
+	spin_lock_init(&bpvm_lock);
+	{
+
+		bpctl_dev_t *pbpctl_dev_c = NULL;
+		for (idx_dev = 0;
+		     ((bpctl_dev_arr[idx_dev].pdev != NULL)
+		      && (idx_dev < device_num)); idx_dev++) {
+			if (bpctl_dev_arr[idx_dev].bp_10g9) {
+				pbpctl_dev_c =
+				    get_status_port_fn(&bpctl_dev_arr[idx_dev]);
+				if (is_bypass_fn(&bpctl_dev_arr[idx_dev])) {
+					printk(KERN_INFO "%s found, ",
+					       bpctl_dev_arr[idx_dev].name);
+					bpctl_dev_arr[idx_dev].bp_fw_ver =
+					    bypass_fw_ver(&bpctl_dev_arr
+							  [idx_dev]);
+					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 (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+	inter_module_register("is_bypass_sd", THIS_MODULE, &is_bypass_sd);
+	inter_module_register("get_bypass_slave_sd", THIS_MODULE,
+			      &get_bypass_slave_sd);
+	inter_module_register("get_bypass_caps_sd", THIS_MODULE,
+			      &get_bypass_caps_sd);
+	inter_module_register("get_wd_set_caps_sd", THIS_MODULE,
+			      &get_wd_set_caps_sd);
+	inter_module_register("set_bypass_sd", THIS_MODULE, &set_bypass_sd);
+	inter_module_register("get_bypass_sd", THIS_MODULE, &get_bypass_sd);
+	inter_module_register("get_bypass_change_sd", THIS_MODULE,
+			      &get_bypass_change_sd);
+	inter_module_register("set_dis_bypass_sd", THIS_MODULE,
+			      &set_dis_bypass_sd);
+	inter_module_register("get_dis_bypass_sd", THIS_MODULE,
+			      &get_dis_bypass_sd);
+	inter_module_register("set_bypass_pwoff_sd", THIS_MODULE,
+			      &set_bypass_pwoff_sd);
+	inter_module_register("get_bypass_pwoff_sd", THIS_MODULE,
+			      &get_bypass_pwoff_sd);
+	inter_module_register("set_bypass_pwup_sd", THIS_MODULE,
+			      &set_bypass_pwup_sd);
+	inter_module_register("get_bypass_pwup_sd", THIS_MODULE,
+			      &get_bypass_pwup_sd);
+	inter_module_register("get_bypass_wd_sd", THIS_MODULE,
+			      &get_bypass_wd_sd);
+	inter_module_register("set_bypass_wd_sd", THIS_MODULE,
+			      &set_bypass_wd_sd);
+	inter_module_register("get_wd_expire_time_sd", THIS_MODULE,
+			      &get_wd_expire_time_sd);
+	inter_module_register("reset_bypass_wd_timer_sd", THIS_MODULE,
+			      &reset_bypass_wd_timer_sd);
+	inter_module_register("set_std_nic_sd", THIS_MODULE, &set_std_nic_sd);
+	inter_module_register("get_std_nic_sd", THIS_MODULE, &get_std_nic_sd);
+	inter_module_register("set_tx_sd", THIS_MODULE, &set_tx_sd);
+	inter_module_register("get_tx_sd", THIS_MODULE, &get_tx_sd);
+	inter_module_register("set_tpl_sd", THIS_MODULE, &set_tpl_sd);
+	inter_module_register("get_tpl_sd", THIS_MODULE, &get_tpl_sd);
+
+	inter_module_register("set_bp_hw_reset_sd", THIS_MODULE,
+			      &set_bp_hw_reset_sd);
+	inter_module_register("get_bp_hw_reset_sd", THIS_MODULE,
+			      &get_bp_hw_reset_sd);
+
+	inter_module_register("set_tap_sd", THIS_MODULE, &set_tap_sd);
+	inter_module_register("get_tap_sd", THIS_MODULE, &get_tap_sd);
+	inter_module_register("get_tap_change_sd", THIS_MODULE,
+			      &get_tap_change_sd);
+	inter_module_register("set_dis_tap_sd", THIS_MODULE, &set_dis_tap_sd);
+	inter_module_register("get_dis_tap_sd", THIS_MODULE, &get_dis_tap_sd);
+	inter_module_register("set_tap_pwup_sd", THIS_MODULE, &set_tap_pwup_sd);
+	inter_module_register("get_tap_pwup_sd", THIS_MODULE, &get_tap_pwup_sd);
+	inter_module_register("set_bp_disc_sd", THIS_MODULE, &set_bp_disc_sd);
+	inter_module_register("get_bp_disc_sd", THIS_MODULE, &get_bp_disc_sd);
+	inter_module_register("get_bp_disc_change_sd", THIS_MODULE,
+			      &get_bp_disc_change_sd);
+	inter_module_register("set_bp_dis_disc_sd", THIS_MODULE,
+			      &set_bp_dis_disc_sd);
+	inter_module_register("get_bp_dis_disc_sd", THIS_MODULE,
+			      &get_bp_dis_disc_sd);
+	inter_module_register("set_bp_disc_pwup_sd", THIS_MODULE,
+			      &set_bp_disc_pwup_sd);
+	inter_module_register("get_bp_disc_pwup_sd", THIS_MODULE,
+			      &get_bp_disc_pwup_sd);
+	inter_module_register("set_wd_exp_mode_sd", THIS_MODULE,
+			      &set_wd_exp_mode_sd);
+	inter_module_register("get_wd_exp_mode_sd", THIS_MODULE,
+			      &get_wd_exp_mode_sd);
+	inter_module_register("set_wd_autoreset_sd", THIS_MODULE,
+			      &set_wd_autoreset_sd);
+	inter_module_register("get_wd_autoreset_sd", THIS_MODULE,
+			      &get_wd_autoreset_sd);
+	inter_module_register("get_bypass_info_sd", THIS_MODULE,
+			      &get_bypass_info_sd);
+	inter_module_register("bp_if_scan_sd", THIS_MODULE, &bp_if_scan_sd);
+
+#endif
+	register_netdevice_notifier(&bp_notifier_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;
+}
+
+/*
+* Cleanup - unregister the appropriate file from /proc
+*/
+static void __exit bypass_cleanup_module(void)
+{
+	int i;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23))
+	int ret;
+#endif
+	unregister_netdevice_notifier(&bp_notifier_block);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+	inter_module_unregister("is_bypass_sd");
+	inter_module_unregister("get_bypass_slave_sd");
+	inter_module_unregister("get_bypass_caps_sd");
+	inter_module_unregister("get_wd_set_caps_sd");
+	inter_module_unregister("set_bypass_sd");
+	inter_module_unregister("get_bypass_sd");
+	inter_module_unregister("get_bypass_change_sd");
+	inter_module_unregister("set_dis_bypass_sd");
+	inter_module_unregister("get_dis_bypass_sd");
+	inter_module_unregister("set_bypass_pwoff_sd");
+	inter_module_unregister("get_bypass_pwoff_sd");
+	inter_module_unregister("set_bypass_pwup_sd");
+	inter_module_unregister("get_bypass_pwup_sd");
+	inter_module_unregister("set_bypass_wd_sd");
+	inter_module_unregister("get_bypass_wd_sd");
+	inter_module_unregister("get_wd_expire_time_sd");
+	inter_module_unregister("reset_bypass_wd_timer_sd");
+	inter_module_unregister("set_std_nic_sd");
+	inter_module_unregister("get_std_nic_sd");
+	inter_module_unregister("set_tx_sd");
+	inter_module_unregister("get_tx_sd");
+	inter_module_unregister("set_tpl_sd");
+	inter_module_unregister("get_tpl_sd");
+	inter_module_unregister("set_tap_sd");
+	inter_module_unregister("get_tap_sd");
+	inter_module_unregister("get_tap_change_sd");
+	inter_module_unregister("set_dis_tap_sd");
+	inter_module_unregister("get_dis_tap_sd");
+	inter_module_unregister("set_tap_pwup_sd");
+	inter_module_unregister("get_tap_pwup_sd");
+	inter_module_unregister("set_bp_disc_sd");
+	inter_module_unregister("get_bp_disc_sd");
+	inter_module_unregister("get_bp_disc_change_sd");
+	inter_module_unregister("set_bp_dis_disc_sd");
+	inter_module_unregister("get_bp_dis_disc_sd");
+	inter_module_unregister("set_bp_disc_pwup_sd");
+	inter_module_unregister("get_bp_disc_pwup_sd");
+	inter_module_unregister("set_wd_exp_mode_sd");
+	inter_module_unregister("get_wd_exp_mode_sd");
+	inter_module_unregister("set_wd_autoreset_sd");
+	inter_module_unregister("get_wd_autoreset_sd");
+	inter_module_unregister("get_bypass_info_sd");
+	inter_module_unregister("bp_if_scan_sd");
+
+#endif
+
+	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]);
+	}
+
+	/* unmap all devices */
+	for (i = 0; i < device_num; i++) {
+#ifdef BP_SELF_TEST
+		if (bpctl_dev_arr[i].bp_tx_data)
+			kfree(bpctl_dev_arr[i].bp_tx_data);
+#endif
+		iounmap((void *)(bpctl_dev_arr[i].mem_map));
+	}
+
+	/* free all devices space */
+	if (bpctl_dev_arr)
+		kfree(bpctl_dev_arr);
+
+/*
+* Unregister the device                             
+*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23))
+	ret = unregister_chrdev(major_num, DEVICE_NAME);
+/*
+* If there's an error, report it
+*/
+	if (ret < 0)
+		printk("Error in module_unregister_chrdev: %d\n", ret);
+#else
+	unregister_chrdev(major_num, DEVICE_NAME);
+
+#endif
+}
+
+module_init(bypass_init_module);
+module_exit(bypass_cleanup_module);
+
+int is_bypass_sd(int ifindex)
+{
+	return (is_bypass(get_dev_idx_p(ifindex)));
+}
+
+int set_bypass_sd(int ifindex, int bypass_mode)
+{
+
+	return (set_bypass_fn(get_dev_idx_p(ifindex), bypass_mode));
+}
+
+int get_bypass_sd(int ifindex)
+{
+
+	return (get_bypass_fn(get_dev_idx_p(ifindex)));
+}
+
+int get_bypass_change_sd(int ifindex)
+{
+
+	return (get_bypass_change_fn(get_dev_idx_p(ifindex)));
+}
+
+int set_dis_bypass_sd(int ifindex, int dis_param)
+{
+	return (set_dis_bypass_fn(get_dev_idx_p(ifindex), dis_param));
+}
+
+int get_dis_bypass_sd(int ifindex)
+{
+
+	return (get_dis_bypass_fn(get_dev_idx_p(ifindex)));
+}
+
+int set_bypass_pwoff_sd(int ifindex, int bypass_mode)
+{
+	return (set_bypass_pwoff_fn(get_dev_idx_p(ifindex), bypass_mode));
+
+}
+
+int get_bypass_pwoff_sd(int ifindex)
+{
+	return (get_bypass_pwoff_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int set_bypass_pwup_sd(int ifindex, int bypass_mode)
+{
+	return (set_bypass_pwup_fn(get_dev_idx_p(ifindex), bypass_mode));
+
+}
+
+int get_bypass_pwup_sd(int ifindex)
+{
+	return (get_bypass_pwup_fn(get_dev_idx_p(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)
+		return BP_NOT_CAP;
+	*ms_timeout_set = set_bypass_wd_fn(get_dev_idx_p(if_index), ms_timeout);
+	return 0;
+}
+
+int get_bypass_wd_sd(int ifindex, int *timeout)
+{
+	return (get_bypass_wd_fn(get_dev_idx_p(ifindex), timeout));
+
+}
+
+int get_wd_expire_time_sd(int ifindex, int *time_left)
+{
+	return (get_wd_expire_time_fn(get_dev_idx_p(ifindex), time_left));
+}
+
+int reset_bypass_wd_timer_sd(int ifindex)
+{
+	return (reset_bypass_wd_timer_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int get_wd_set_caps_sd(int ifindex)
+{
+	return (get_wd_set_caps_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int set_std_nic_sd(int ifindex, int nic_mode)
+{
+	return (set_std_nic_fn(get_dev_idx_p(ifindex), nic_mode));
+
+}
+
+int get_std_nic_sd(int ifindex)
+{
+	return (get_std_nic_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int set_tap_sd(int ifindex, int tap_mode)
+{
+	return (set_tap_fn(get_dev_idx_p(ifindex), tap_mode));
+
+}
+
+int get_tap_sd(int ifindex)
+{
+	return (get_tap_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int set_tap_pwup_sd(int ifindex, int tap_mode)
+{
+	return (set_tap_pwup_fn(get_dev_idx_p(ifindex), tap_mode));
+
+}
+
+int get_tap_pwup_sd(int ifindex)
+{
+	return (get_tap_pwup_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int get_tap_change_sd(int ifindex)
+{
+	return (get_tap_change_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int set_dis_tap_sd(int ifindex, int dis_param)
+{
+	return (set_dis_tap_fn(get_dev_idx_p(ifindex), dis_param));
+
+}
+
+int get_dis_tap_sd(int ifindex)
+{
+	return (get_dis_tap_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int set_bp_disc_sd(int ifindex, int disc_mode)
+{
+	return (set_disc_fn(get_dev_idx_p(ifindex), disc_mode));
+
+}
+
+int get_bp_disc_sd(int ifindex)
+{
+	return (get_disc_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int set_bp_disc_pwup_sd(int ifindex, int disc_mode)
+{
+	return (set_disc_pwup_fn(get_dev_idx_p(ifindex), disc_mode));
+
+}
+
+int get_bp_disc_pwup_sd(int ifindex)
+{
+	return (get_disc_pwup_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int get_bp_disc_change_sd(int ifindex)
+{
+	return (get_disc_change_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int set_bp_dis_disc_sd(int ifindex, int dis_param)
+{
+	return (set_dis_disc_fn(get_dev_idx_p(ifindex), dis_param));
+
+}
+
+int get_bp_dis_disc_sd(int ifindex)
+{
+	return (get_dis_disc_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int get_wd_exp_mode_sd(int ifindex)
+{
+	return (get_wd_exp_mode_fn(get_dev_idx_p(ifindex)));
+}
+
+int set_wd_exp_mode_sd(int ifindex, int param)
+{
+	return (set_wd_exp_mode_fn(get_dev_idx_p(ifindex), param));
+
+}
+
+int reset_cont_sd(int ifindex)
+{
+	return (reset_cont_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int set_tx_sd(int ifindex, int tx_state)
+{
+	return (set_tx_fn(get_dev_idx_p(ifindex), tx_state));
+
+}
+
+int set_tpl_sd(int ifindex, int tpl_state)
+{
+	return (set_tpl_fn(get_dev_idx_p(ifindex), tpl_state));
+
+}
+
+int set_bp_hw_reset_sd(int ifindex, int status)
+{
+	return (set_bp_hw_reset_fn(get_dev_idx_p(ifindex), status));
+
+}
+
+int set_wd_autoreset_sd(int ifindex, int param)
+{
+	return (set_wd_autoreset_fn(get_dev_idx_p(ifindex), param));
+
+}
+
+int get_wd_autoreset_sd(int ifindex)
+{
+	return (get_wd_autoreset_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int get_bypass_caps_sd(int ifindex)
+{
+	return (get_bypass_caps_fn(get_dev_idx_p(ifindex)));
+}
+
+int get_bypass_slave_sd(int ifindex)
+{
+	bpctl_dev_t *pbpctl_dev_out;
+	int ret = get_bypass_slave_fn(get_dev_idx_p(ifindex), &pbpctl_dev_out);
+	if (ret == 1)
+		return (pbpctl_dev_out->ifindex);
+	return -1;
+
+}
+
+int get_tx_sd(int ifindex)
+{
+	return (get_tx_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int get_tpl_sd(int ifindex)
+{
+	return (get_tpl_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int get_bp_hw_reset_sd(int ifindex)
+{
+	return (get_bp_hw_reset_fn(get_dev_idx_p(ifindex)));
+
+}
+
+int get_bypass_info_sd(int ifindex, struct bp_info *bp_info)
+{
+	return (get_bypass_info_fn
+		(get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver));
+}
+
+int bp_if_scan_sd(void)
+{
+	if_scan_init();
+	return 0;
+}
+
+EXPORT_SYMBOL_NOVERS(is_bypass_sd);
+EXPORT_SYMBOL_NOVERS(get_bypass_slave_sd);
+EXPORT_SYMBOL_NOVERS(get_bypass_caps_sd);
+EXPORT_SYMBOL_NOVERS(get_wd_set_caps_sd);
+EXPORT_SYMBOL_NOVERS(set_bypass_sd);
+EXPORT_SYMBOL_NOVERS(get_bypass_sd);
+EXPORT_SYMBOL_NOVERS(get_bypass_change_sd);
+EXPORT_SYMBOL_NOVERS(set_dis_bypass_sd);
+EXPORT_SYMBOL_NOVERS(get_dis_bypass_sd);
+EXPORT_SYMBOL_NOVERS(set_bypass_pwoff_sd);
+EXPORT_SYMBOL_NOVERS(get_bypass_pwoff_sd);
+EXPORT_SYMBOL_NOVERS(set_bypass_pwup_sd);
+EXPORT_SYMBOL_NOVERS(get_bypass_pwup_sd);
+EXPORT_SYMBOL_NOVERS(set_bypass_wd_sd);
+EXPORT_SYMBOL_NOVERS(get_bypass_wd_sd);
+EXPORT_SYMBOL_NOVERS(get_wd_expire_time_sd);
+EXPORT_SYMBOL_NOVERS(reset_bypass_wd_timer_sd);
+EXPORT_SYMBOL_NOVERS(set_std_nic_sd);
+EXPORT_SYMBOL_NOVERS(get_std_nic_sd);
+EXPORT_SYMBOL_NOVERS(set_tx_sd);
+EXPORT_SYMBOL_NOVERS(get_tx_sd);
+EXPORT_SYMBOL_NOVERS(set_tpl_sd);
+EXPORT_SYMBOL_NOVERS(get_tpl_sd);
+EXPORT_SYMBOL_NOVERS(set_bp_hw_reset_sd);
+EXPORT_SYMBOL_NOVERS(get_bp_hw_reset_sd);
+EXPORT_SYMBOL_NOVERS(set_tap_sd);
+EXPORT_SYMBOL_NOVERS(get_tap_sd);
+EXPORT_SYMBOL_NOVERS(get_tap_change_sd);
+EXPORT_SYMBOL_NOVERS(set_dis_tap_sd);
+EXPORT_SYMBOL_NOVERS(get_dis_tap_sd);
+EXPORT_SYMBOL_NOVERS(set_tap_pwup_sd);
+EXPORT_SYMBOL_NOVERS(get_tap_pwup_sd);
+EXPORT_SYMBOL_NOVERS(set_wd_exp_mode_sd);
+EXPORT_SYMBOL_NOVERS(get_wd_exp_mode_sd);
+EXPORT_SYMBOL_NOVERS(set_wd_autoreset_sd);
+EXPORT_SYMBOL_NOVERS(get_wd_autoreset_sd);
+EXPORT_SYMBOL_NOVERS(set_bp_disc_sd);
+EXPORT_SYMBOL_NOVERS(get_bp_disc_sd);
+EXPORT_SYMBOL_NOVERS(get_bp_disc_change_sd);
+EXPORT_SYMBOL_NOVERS(set_bp_dis_disc_sd);
+EXPORT_SYMBOL_NOVERS(get_bp_dis_disc_sd);
+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);
+
+#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;
+
+static struct proc_dir_entry *proc_getdir(char *name,
+					  struct proc_dir_entry *proc_dir)
+{
+	struct proc_dir_entry *pde = proc_dir;
+
+	for (pde = pde->subdir; pde; pde = pde->next) {
+		if (pde->namelen && (strcmp(name, pde->name) == 0)) {
+			/* directory exists */
+			break;
+		}
+	}
+	if (pde == (struct proc_dir_entry *)0) {
+		/* create the directory */
+#if (LINUX_VERSION_CODE > 0x20300)
+		pde = proc_mkdir(name, proc_dir);
+#else
+		pde = create_proc_entry(name, S_IFDIR, proc_dir);
+#endif
+		if (pde == (struct proc_dir_entry *)0) {
+
+			return (pde);
+		}
+	}
+
+	return (pde);
+}
+
+int bp_proc_create(void)
+{
+	bp_procfs_dir = proc_getdir(BP_PROC_DIR, init_net.proc_net);
+	if (bp_procfs_dir == (struct proc_dir_entry *)0) {
+		printk(KERN_DEBUG
+		       "Could not create procfs nicinfo directory %s\n",
+		       BP_PROC_DIR);
+		return -1;
+	}
+	return 0;
+}
+
+int
+bypass_proc_create_entry_sd(struct pfs_unit_sd *pfs_unit_curr,
+			    char *proc_name,
+			    write_proc_t * write_proc,
+			    read_proc_t * read_proc,
+			    struct proc_dir_entry *parent_pfs, void *data)
+{
+	strcpy(pfs_unit_curr->proc_name, proc_name);
+	pfs_unit_curr->proc_entry = create_proc_entry(pfs_unit_curr->proc_name,
+						      S_IFREG | S_IRUSR |
+						      S_IWUSR | S_IRGRP |
+						      S_IWGRP | S_IROTH |
+						      S_IWOTH, parent_pfs);
+	if (pfs_unit_curr->proc_entry == 0) {
+
+		return -1;
+	}
+
+	pfs_unit_curr->proc_entry->read_proc = read_proc;
+	pfs_unit_curr->proc_entry->write_proc = write_proc;
+	pfs_unit_curr->proc_entry->data = data;
+
+	return 0;
+
+}
+
+int
+get_bypass_info_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+	int len = 0;
+
+	len += sprintf(page, "Name\t\t\t%s\n", pbp_device_block->name);
+	len +=
+	    sprintf(page + len, "Firmware version\t0x%x\n",
+		    pbp_device_block->bp_fw_ver);
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_bypass_slave_pfs(char *page, char **start, off_t off, int count,
+		     int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0;
+	bpctl_dev_t *pbp_device_block_slave = NULL;
+	int idx_dev = 0;
+	struct net_device *net_slave_dev = NULL;
+
+	if ((pbp_device_block->func == 0) || (pbp_device_block->func == 2)) {
+		for (idx_dev = 0;
+		     ((bpctl_dev_arr[idx_dev].pdev != NULL)
+		      && (idx_dev < device_num)); idx_dev++) {
+			if ((bpctl_dev_arr[idx_dev].bus ==
+			     pbp_device_block->bus)
+			    && (bpctl_dev_arr[idx_dev].slot ==
+				pbp_device_block->slot)) {
+				if ((pbp_device_block->func == 0)
+				    && (bpctl_dev_arr[idx_dev].func == 1)) {
+					pbp_device_block_slave =
+					    &bpctl_dev_arr[idx_dev];
+					break;
+				}
+				if ((pbp_device_block->func == 2) &&
+				    (bpctl_dev_arr[idx_dev].func == 3)) {
+					pbp_device_block_slave =
+					    &bpctl_dev_arr[idx_dev];
+					break;
+				}
+			}
+		}
+	} else
+		pbp_device_block_slave = pbp_device_block;
+	if (!pbp_device_block_slave) {
+		len = sprintf(page, "fail\n");
+		*eof = 1;
+		return len;
+	}
+	net_slave_dev = pbp_device_block_slave->ndev;
+	if (net_slave_dev) {
+		if (net_slave_dev)
+			len = sprintf(page, "%s\n", net_slave_dev->name);
+		else
+			len = sprintf(page, "fail\n");
+
+	}
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_bypass_caps_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bypass_caps_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "-1\n");
+	else
+		len = sprintf(page, "0x%x\n", ret);
+	*eof = 1;
+	return len;
+
+}
+
+int
+get_wd_set_caps_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_wd_set_caps_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "-1\n");
+	else
+		len = sprintf(page, "0x%x\n", ret);
+	*eof = 1;
+	return len;
+}
+
+int
+set_bypass_pfs(struct file *file, const char *buffer,
+	       unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		bypass_param = 0;
+
+	set_bypass_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+set_tap_pfs(struct file *file, const char *buffer,
+	    unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_tap_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+set_disc_pfs(struct file *file, const char *buffer,
+	     unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_disc_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+get_bypass_pfs(char *page, char **start, off_t off, int count,
+	       int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bypass_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_tap_pfs(char *page, char **start, off_t off, int count,
+	    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_tap_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_disc_pfs(char *page, char **start, off_t off, int count,
+	     int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_disc_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_bypass_change_pfs(char *page, char **start, off_t off, int count,
+		      int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bypass_change_fn(pbp_device_block);
+	if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "fail\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_tap_change_pfs(char *page, char **start, off_t off, int count,
+		   int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_tap_change_fn(pbp_device_block);
+	if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "fail\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_disc_change_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_disc_change_fn(pbp_device_block);
+	if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "fail\n");
+
+	*eof = 1;
+	return len;
+}
+
+#define isdigit(c) (c >= '0' && c <= '9')
+__inline static int atoi(char **s)
+{
+	int i = 0;
+	while (isdigit(**s))
+		i = i * 10 + *((*s)++) - '0';
+	return i;
+}
+
+int
+set_bypass_wd_pfs(struct file *file, const char *buffer,
+		  unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	unsigned int timeout = 0;
+	char *timeout_ptr = kbuf;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	timeout_ptr = kbuf;
+	timeout = atoi(&timeout_ptr);
+
+	set_bypass_wd_fn(pbp_device_block, timeout);
+
+	return count;
+}
+
+int
+get_bypass_wd_pfs(char *page, char **start, off_t off, int count,
+		  int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0, timeout = 0;
+
+	ret = get_bypass_wd_fn(pbp_device_block, &timeout);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (timeout == -1)
+		len = sprintf(page, "unknown\n");
+	else if (timeout == 0)
+		len = sprintf(page, "disable\n");
+	else
+		len = sprintf(page, "%d\n", timeout);
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_wd_expire_time_pfs(char *page, char **start, off_t off, int count,
+		       int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0, timeout = 0;
+
+	ret = get_wd_expire_time_fn(pbp_device_block, &timeout);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (timeout == -1)
+		len = sprintf(page, "expire\n");
+	else if (timeout == 0)
+		len = sprintf(page, "disable\n");
+
+	else
+		len = sprintf(page, "%d\n", timeout);
+	*eof = 1;
+	return len;
+}
+
+int
+get_tpl_pfs(char *page, char **start, off_t off, int count,
+	    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_tpl_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+#ifdef PMC_FIX_FLAG
+int
+get_wait_at_pwup_pfs(char *page, char **start, off_t off, int count,
+		     int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bp_wait_at_pwup_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_hw_reset_pfs(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bp_hw_reset_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+#endif				/*PMC_WAIT_FLAG */
+
+int
+reset_bypass_wd_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = reset_bypass_wd_timer_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "disable\n");
+	else if (ret == 1)
+		len = sprintf(page, "success\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+set_dis_bypass_pfs(struct file *file, const char *buffer,
+		   unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		bypass_param = 0;
+
+	set_dis_bypass_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+set_dis_tap_pfs(struct file *file, const char *buffer,
+		unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_dis_tap_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+set_dis_disc_pfs(struct file *file, const char *buffer,
+		 unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_dis_disc_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+get_dis_bypass_pfs(char *page, char **start, off_t off, int count,
+		   int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_dis_bypass_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_dis_tap_pfs(char *page, char **start, off_t off, int count,
+		int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_dis_tap_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_dis_disc_pfs(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_dis_disc_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+set_bypass_pwup_pfs(struct file *file, const char *buffer,
+		    unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		bypass_param = 0;
+
+	set_bypass_pwup_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+set_bypass_pwoff_pfs(struct file *file, const char *buffer,
+		     unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		bypass_param = 0;
+
+	set_bypass_pwoff_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+set_tap_pwup_pfs(struct file *file, const char *buffer,
+		 unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_tap_pwup_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+set_disc_pwup_pfs(struct file *file, const char *buffer,
+		  unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_disc_pwup_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+get_bypass_pwup_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bypass_pwup_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_bypass_pwoff_pfs(char *page, char **start, off_t off, int count,
+		     int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bypass_pwoff_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_tap_pwup_pfs(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_tap_pwup_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_disc_pwup_pfs(char *page, char **start, off_t off, int count,
+		  int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_disc_pwup_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+set_std_nic_pfs(struct file *file, const char *buffer,
+		unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		bypass_param = 0;
+
+	set_std_nic_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+get_std_nic_pfs(char *page, char **start, off_t off, int count,
+		int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_std_nic_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_wd_exp_mode_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_wd_exp_mode_fn(pbp_device_block);
+	if (ret == 1)
+		len = sprintf(page, "tap\n");
+	else if (ret == 0)
+		len = sprintf(page, "bypass\n");
+	else if (ret == 2)
+		len = sprintf(page, "disc\n");
+
+	else
+		len = sprintf(page, "fail\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+set_wd_exp_mode_pfs(struct file *file, const char *buffer,
+		    unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "tap") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "bypass") == 0)
+		bypass_param = 0;
+	else if (strcmp(kbuf, "disc") == 0)
+		bypass_param = 2;
+
+	set_wd_exp_mode_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+get_wd_autoreset_pfs(char *page, char **start, off_t off, int count,
+		     int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_wd_autoreset_fn(pbp_device_block);
+	if (ret >= 0)
+		len = sprintf(page, "%d\n", ret);
+	else
+		len = sprintf(page, "fail\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+set_wd_autoreset_pfs(struct file *file, const char *buffer,
+		     unsigned long count, void *data)
+{
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+	u32 timeout = 0;
+	char *timeout_ptr = kbuf;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	timeout_ptr = kbuf;
+	timeout = atoi(&timeout_ptr);
+
+	set_wd_autoreset_fn(pbp_device_block, timeout);
+
+	return count;
+}
+
+int
+set_tpl_pfs(struct file *file, const char *buffer,
+	    unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tpl_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tpl_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tpl_param = 0;
+
+	set_tpl_fn(pbp_device_block, tpl_param);
+
+	return count;
+}
+
+#ifdef PMC_FIX_FLAG
+int
+set_wait_at_pwup_pfs(struct file *file, const char *buffer,
+		     unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tpl_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tpl_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tpl_param = 0;
+
+	set_bp_wait_at_pwup_fn(pbp_device_block, tpl_param);
+
+	return count;
+}
+
+int
+set_hw_reset_pfs(struct file *file, const char *buffer,
+		 unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tpl_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tpl_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tpl_param = 0;
+
+	set_bp_hw_reset_fn(pbp_device_block, tpl_param);
+
+	return count;
+}
+
+#endif				/*PMC_FIX_FLAG */
+
+int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block)
+{
+	struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set);
+	static struct proc_dir_entry *procfs_dir = NULL;
+	int ret = 0;
+
+	if (!pbp_device_block->ndev)
+		return -1;
+	sprintf(current_pfs->dir_name, "bypass_%s",
+		pbp_device_block->ndev->name);
+
+	if (!bp_procfs_dir)
+		return -1;
+
+	/* create device proc dir */
+	procfs_dir = proc_getdir(current_pfs->dir_name, bp_procfs_dir);
+	if (procfs_dir == 0) {
+		printk(KERN_DEBUG "Could not create procfs directory %s\n",
+		       current_pfs->dir_name);
+		return -1;
+	}
+	current_pfs->bypass_entry = procfs_dir;
+
+	if (bypass_proc_create_entry_sd(&(current_pfs->bypass_info), BYPASS_INFO_ENTRY_SD, NULL,	/* write */
+					get_bypass_info_pfs,	/* read  */
+					procfs_dir, pbp_device_block))
+		ret = -1;
+
+	if (pbp_device_block->bp_caps & SW_CTL_CAP) {
+
+		/* Create set param proc's */
+		if (bypass_proc_create_entry_sd(&(current_pfs->bypass_slave), BYPASS_SLAVE_ENTRY_SD, NULL,	/* write */
+						get_bypass_slave_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->bypass_caps), BYPASS_CAPS_ENTRY_SD, NULL,	/* write */
+						get_bypass_caps_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->wd_set_caps), WD_SET_CAPS_ENTRY_SD, NULL,	/* write */
+						get_wd_set_caps_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+		if (bypass_proc_create_entry_sd(&(current_pfs->bypass_wd), BYPASS_WD_ENTRY_SD, set_bypass_wd_pfs,	/* write */
+						get_bypass_wd_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->wd_expire_time), WD_EXPIRE_TIME_ENTRY_SD, NULL,	/* write */
+						get_wd_expire_time_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->reset_bypass_wd), RESET_BYPASS_WD_ENTRY_SD, NULL,	/* write */
+						reset_bypass_wd_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->std_nic), STD_NIC_ENTRY_SD, set_std_nic_pfs,	/* write */
+						get_std_nic_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (pbp_device_block->bp_caps & BP_CAP) {
+			if (bypass_proc_create_entry_sd(&(current_pfs->bypass), BYPASS_ENTRY_SD, set_bypass_pfs,	/* write */
+							get_bypass_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->dis_bypass), DIS_BYPASS_ENTRY_SD, set_dis_bypass_pfs,	/* write */
+							get_dis_bypass_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwup), BYPASS_PWUP_ENTRY_SD, set_bypass_pwup_pfs,	/* write */
+							get_bypass_pwup_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+			if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwoff), BYPASS_PWOFF_ENTRY_SD, set_bypass_pwoff_pfs,	/* write */
+							get_bypass_pwoff_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->bypass_change), BYPASS_CHANGE_ENTRY_SD, NULL,	/* write */
+							get_bypass_change_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+		}
+
+		if (pbp_device_block->bp_caps & TAP_CAP) {
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap), TAP_ENTRY_SD, set_tap_pfs,	/* write */
+							get_tap_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_TAP_ENTRY_SD, set_dis_tap_pfs,	/* write */
+							get_dis_tap_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), TAP_PWUP_ENTRY_SD, set_tap_pwup_pfs,	/* write */
+							get_tap_pwup_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), TAP_CHANGE_ENTRY_SD, NULL,	/* write */
+							get_tap_change_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+		}
+		if (pbp_device_block->bp_caps & DISC_CAP) {
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap), DISC_ENTRY_SD, set_disc_pfs,	/* write */
+							get_disc_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+#if 1
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_DISC_ENTRY_SD, set_dis_disc_pfs,	/* write */
+							get_dis_disc_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+#endif
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), DISC_PWUP_ENTRY_SD, set_disc_pwup_pfs,	/* write */
+							get_disc_pwup_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), DISC_CHANGE_ENTRY_SD, NULL,	/* write */
+							get_disc_change_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+		}
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->wd_exp_mode), WD_EXP_MODE_ENTRY_SD, set_wd_exp_mode_pfs,	/* write */
+						get_wd_exp_mode_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->wd_autoreset), WD_AUTORESET_ENTRY_SD, set_wd_autoreset_pfs,	/* write */
+						get_wd_autoreset_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+		if (bypass_proc_create_entry_sd(&(current_pfs->tpl), TPL_ENTRY_SD, set_tpl_pfs,	/* write */
+						get_tpl_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+#ifdef PMC_FIX_FLAG
+		if (bypass_proc_create_entry_sd(&(current_pfs->tpl), WAIT_AT_PWUP_ENTRY_SD, set_wait_at_pwup_pfs,	/* write */
+						get_wait_at_pwup_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+		if (bypass_proc_create_entry_sd(&(current_pfs->tpl), HW_RESET_ENTRY_SD, set_hw_reset_pfs,	/* write */
+						get_hw_reset_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+#endif
+
+	}
+	if (ret < 0)
+		printk(KERN_DEBUG "Create proc entry failed\n");
+
+	return ret;
+}
+
+int bypass_proc_remove_dev_sd(bpctl_dev_t * pbp_device_block)
+{
+
+	struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set;
+	struct proc_dir_entry *pde = current_pfs->bypass_entry, *pde_curr =
+	    NULL;
+	char name[256];
+
+	if (!pde)
+		return 0;
+	for (pde = pde->subdir; pde;) {
+		strcpy(name, pde->name);
+		pde_curr = pde;
+		pde = pde->next;
+		remove_proc_entry(name, current_pfs->bypass_entry);
+	}
+	if (!pde)
+		remove_proc_entry(current_pfs->dir_name, bp_procfs_dir);
+	current_pfs->bypass_entry = NULL;
+
+	return 0;
+}
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/bp_mod.h working/drivers/staging/silicom/bp_mod.h
--- linux-2.6/drivers/staging/silicom/bp_mod.h	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/bp_mod.h	2012-09-06 18:24:28.362047744 -0700
@@ -0,0 +1,703 @@
+/******************************************************************************/
+/*                                                                            */
+/* Bypass Control utility, Copyright (c) 2005 Silicom                         */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/*                                                                            */
+/* bp_mod.h                                                                   */
+/*                                                                            */
+/******************************************************************************/
+
+#ifndef BP_MOD_H
+#define BP_MOD_H
+#include "bits.h"
+
+#define EXPORT_SYMBOL_NOVERS EXPORT_SYMBOL
+
+#define usec_delay(x) udelay(x)
+#ifndef msec_delay_bp
+#define msec_delay_bp(x)	do { \
+            int  i; \
+            if(1) { \
+                   for(i = 0; i < 1000; i++) \
+                   {                     \
+                      udelay(x) ;        \
+                   }                     \
+			} else { \
+				msleep(x); \
+			} } while(0)
+
+#endif
+
+#include <linux/param.h>
+
+#ifndef jiffies_to_msecs
+#define jiffies_to_msecs(x) _kc_jiffies_to_msecs(x)
+static inline unsigned int jiffies_to_msecs(const unsigned long j)
+{
+#if HZ <= 1000 && !(1000 % HZ)
+	return (1000 / HZ) * j;
+#elif HZ > 1000 && !(HZ % 1000)
+	return (j + (HZ / 1000) - 1) / (HZ / 1000);
+#else
+	return (j * 1000) / HZ;
+#endif
+}
+#endif
+
+#define SILICOM_VID              0x1374
+#define SILICOM_SVID             0x1374
+
+#define SILICOM_PXG2BPFI_SSID    0x0026
+#define SILICOM_PXG2BPFILX_SSID  0x0027
+#define SILICOM_PXGBPI_SSID      0x0028
+#define SILICOM_PXGBPIG_SSID     0x0029
+#define SILICOM_PXG2TBFI_SSID    0x002a
+#define SILICOM_PXG4BPI_SSID     0x002c
+#define SILICOM_PXG4BPFI_SSID    0x002d
+#define SILICOM_PXG4BPFILX_SSID  0x002e
+#define SILICOM_PXG2BPFIL_SSID   0x002F
+#define SILICOM_PXG2BPFILLX_SSID 0x0030
+#define SILICOM_PEG4BPI_SSID     0x0031
+#define SILICOM_PEG2BPI_SSID     0x0037
+#define SILICOM_PEG4BPIN_SSID    0x0038
+#define SILICOM_PEG2BPFI_SSID    0x0039
+#define SILICOM_PEG2BPFILX_SSID  0x003A
+#define SILICOM_PMCXG2BPFI_SSID  0x003B
+#define NOKIA_PMCXG2BPFIN_SSID   0x0510
+#define NOKIA_PMCXG2BPIN_SSID    0x0513
+#define NOKIA_PMCXG4BPIN_SSID    0x0514
+#define NOKIA_PMCXG2BPFIN_SVID   0x13B8
+#define NOKIA_PMCXG2BPIN2_SSID    0x0515
+#define NOKIA_PMCXG4BPIN2_SSID    0x0516
+#define SILICOM_PMCX2BPI_SSID       0x041
+#define SILICOM_PMCX4BPI_SSID       0x042
+#define SILICOM_PXG2BISC1_SSID   0x003d
+#define SILICOM_PEG2TBFI_SSID    0x003E
+#define SILICOM_PXG2TBI_SSID     0x003f
+#define SILICOM_PXG4BPFID_SSID   0x0043
+#define SILICOM_PEG4BPFI_SSID    0x0040
+#define SILICOM_PEG4BPIPT_SSID   0x0044
+#define SILICOM_PXG6BPI_SSID     0x0045
+#define SILICOM_PEG4BPIL_SSID    0x0046
+#define SILICOM_PEG2BPI5_SSID    0x0052
+#define SILICOM_PEG6BPI_SSID    0x0053
+#define SILICOM_PEG4BPFI5_SSID   0x0050
+#define SILICOM_PEG4BPFI5LX_SSID   0x0051
+#define SILICOM_PEG2BISC6_SSID 0x54
+
+#define SILICOM_PEG6BPIFC_SSID 0x55
+
+#define SILICOM_PEG2BPFI5_SSID   0x0056
+#define SILICOM_PEG2BPFI5LX_SSID   0x0057
+
+#define SILICOM_PXEG4BPFI_SSID    0x0058
+
+#define SILICOM_PEG2BPFID_SSID   0x0047
+#define SILICOM_PEG2BPFIDLX_SSID  0x004C
+#define SILICOM_MEG2BPFILN_SSID  0x0048
+#define SILICOM_MEG2BPFINX_SSID  0x0049
+#define SILICOM_PEG4BPFILX_SSID  0x004A
+#define SILICOM_MHIO8AD_SSID    0x004F
+
+#define SILICOM_MEG2BPFILXLN_SSID 0x004b
+#define SILICOM_PEG2BPIX1_SSID    0x004d
+#define SILICOM_MEG2BPFILXNX_SSID 0x004e
+
+#define SILICOM_PE10G2BPISR_SSID  0x0102
+#define SILICOM_PE10G2BPILR_SSID  0x0103
+#define SILICOM_PE10G2BPICX4_SSID  0x0101
+
+#define SILICOM_XE10G2BPILR_SSID 0x0163
+#define SILICOM_XE10G2BPISR_SSID 0x0162
+#define SILICOM_XE10G2BPICX4_SSID 0x0161
+#define SILICOM_XE10G2BPIT_SSID   0x0160
+
+#define SILICOM_PE10GDBISR_SSID   0x0181
+#define SILICOM_PE10GDBILR_SSID   0x0182
+
+#define SILICOM_PE210G2DBi9SR_SSID	    0x0188
+#define SILICOM_PE210G2DBi9SRRB_SSID	0x0188
+#define SILICOM_PE210G2DBi9LR_SSID	    0x0189
+#define SILICOM_PE210G2DBi9LRRB_SSID	0x0189
+#define SILICOM_PE310G4DBi940SR_SSID	0x018C
+
+#define SILICOM_PE310G4BPi9T_SSID       0x130
+#define SILICOM_PE310G4BPi9SR_SSID        0x132
+#define SILICOM_PE310G4BPi9LR_SSID        0x133
+
+#define NOKIA_XE10G2BPIXR_SVID   0x13B8
+#define NOKIA_XE10G2BPIXR_SSID   0x051C
+
+#define INTEL_PEG4BPII_PID   0x10A0
+#define INTEL_PEG4BPFII_PID   0x10A1
+#define INTEL_PEG4BPII_SSID   0x11A0
+#define INTEL_PEG4BPFII_SSID   0x11A1
+
+#define INTEL_PEG4BPIIO_SSID   0x10A0
+#define INTEL_PEG4BPIIO_PID   0x105e
+
+#define BROADCOM_VID         0x14e4
+#define BROADCOM_PE10G2_PID  0x164e
+
+#define SILICOM_PE10G2BPTCX4_SSID 0x0141
+#define SILICOM_PE10G2BPTSR_SSID  0x0142
+#define SILICOM_PE10G2BPTLR_SSID  0x0143
+#define SILICOM_PE10G2BPTT_SSID   0x0140
+
+#define SILICOM_PEG4BPI6_SSID     0x0320
+#define SILICOM_PEG4BPFI6_SSID    0x0321
+#define SILICOM_PEG4BPFI6LX_SSID    0x0322
+#define SILICOM_PEG4BPFI6ZX_SSID    0x0323
+
+#define SILICOM_PEG2BPI6_SSID    0x0300
+#define SILICOM_PEG2BPFI6_SSID    0x0301
+#define SILICOM_PEG2BPFI6LX_SSID    0x0302
+#define SILICOM_PEG2BPFI6ZX_SSID    0x0303
+#define SILICOM_PEG2BPFI6FLXM_SSID  0x0304
+
+#define SILICOM_PEG2DBI6_SSID    0x0308
+#define SILICOM_PEG2DBFI6_SSID    0x0309
+#define SILICOM_PEG2DBFI6LX_SSID    0x030A
+#define SILICOM_PEG2DBFI6ZX_SSID    0x030B
+
+#define SILICOM_MEG2BPI6_SSID     0x0310
+#define SILICOM_XEG2BPI6_SSID    0x0318
+#define SILICOM_PEG4BPI6FC_SSID     0x0328
+#define SILICOM_PEG4BPFI6FC_SSID    0x0329
+#define SILICOM_PEG4BPFI6FCLX_SSID    0x032A
+#define SILICOM_PEG4BPFI6FCZX_SSID    0x032B
+
+#define SILICOM_PEG6BPI6_SSID     0x0340
+
+#define SILICOM_PEG2BPI6SC6_SSID     0x0360
+
+#define SILICOM_MEG2BPI6_SSID     0x0310
+#define SILICOM_XEG2BPI6_SSID     0x0318
+#define SILICOM_MEG4BPI6_SSID     0x0330
+
+#define SILICOM_PE2G4BPi80L_SSID    0x0380
+
+#define SILICOM_M6E2G8BPi80A_SSID    0x0474
+
+#define SILICOM_PE2G4BPi35_SSID    0x03d8
+
+#define SILICOM_PE2G4BPFi80_SSID    0x0381
+#define SILICOM_PE2G4BPFi80LX_SSID    0x0382
+#define SILICOM_PE2G4BPFi80ZX_SSID    0x0383
+
+#define SILICOM_PE2G4BPi80_SSID    0x0388
+
+#define SILICOM_PE2G2BPi80_SSID    0x0390
+#define SILICOM_PE2G2BPFi80_SSID    0x0391
+#define SILICOM_PE2G2BPFi80LX_SSID    0x0392
+#define SILICOM_PE2G2BPFi80ZX_SSID    0x0393
+
+#define SILICOM_PE2G4BPi35L_SSID    0x03D0
+#define SILICOM_PE2G4BPFi35_SSID    0x03D1
+#define SILICOM_PE2G4BPFi35LX_SSID    0x03D2
+#define SILICOM_PE2G4BPFi35ZX_SSID    0x03D3
+
+#define SILICOM_PE2G2BPi35_SSID    0x03c0
+#define SILICOM_PAC1200BPi35_SSID    0x03cc
+#define SILICOM_PE2G2BPFi35_SSID    0x03C1
+#define SILICOM_PE2G2BPFi35LX_SSID    0x03C2
+#define SILICOM_PE2G2BPFi35ZX_SSID    0x03C3
+
+#define SILICOM_PE2G6BPi35_SSID    0x03E0
+#define SILICOM_PE2G6BPi35CX_SSID  0x0AA0
+
+#define INTEL_PE210G2SPI9_SSID     0x00C
+
+#define SILICOM_M1EG2BPI6_SSID     0x400
+
+#define SILICOM_M1EG2BPFI6_SSID     0x0401
+#define SILICOM_M1EG2BPFI6LX_SSID     0x0402
+#define SILICOM_M1EG2BPFI6ZX_SSID     0x0403
+
+#define SILICOM_M1EG4BPI6_SSID     0x0420
+
+#define SILICOM_M1EG4BPFI6_SSID       0x0421
+#define SILICOM_M1EG4BPFI6LX_SSID     0x0422
+#define SILICOM_M1EG4BPFI6ZX_SSID     0x0423
+
+#define SILICOM_M1EG6BPI6_SSID     0x0440
+
+#define SILICOM_M1E2G4BPi80_SSID     0x0460
+#define SILICOM_M1E2G4BPFi80_SSID       0x0461
+#define SILICOM_M1E2G4BPFi80LX_SSID     0x0462
+#define SILICOM_M1E2G4BPFi80ZX_SSID     0x0463
+
+#define SILICOM_M6E2G8BPi80_SSID        0x0470
+#define SILICOM_PE210G2BPi40_SSID       0x01a0
+
+#define PEG540_IF_SERIES(pid) \
+          ((pid==SILICOM_PE210G2BPi40_SSID))
+
+#define OLD_IF_SERIES(pid) \
+        ((pid==SILICOM_PXG2BPFI_SSID)||   \
+          (pid==SILICOM_PXG2BPFILX_SSID))
+
+#define P2BPFI_IF_SERIES(pid) \
+        ((pid==SILICOM_PXG2BPFI_SSID)||   \
+          (pid==SILICOM_PXG2BPFILX_SSID)|| \
+          (pid==SILICOM_PEG2BPFI_SSID)|| \
+          (pid==SILICOM_PEG2BPFID_SSID)|| \
+          (pid==SILICOM_PEG2BPFIDLX_SSID)|| \
+         (pid==SILICOM_MEG2BPFILN_SSID)|| \
+         (pid==SILICOM_MEG2BPFINX_SSID)|| \
+         (pid==SILICOM_PEG4BPFILX_SSID)|| \
+         (pid==SILICOM_PEG4BPFI_SSID)|| \
+         (pid==SILICOM_PXEG4BPFI_SSID)|| \
+         (pid==SILICOM_PXG4BPFID_SSID)|| \
+         (pid==SILICOM_PEG2TBFI_SSID)|| \
+         (pid==SILICOM_PE10G2BPISR_SSID)|| \
+         (pid==SILICOM_PE10G2BPILR_SSID)|| \
+          (pid==SILICOM_PEG2BPFILX_SSID)|| \
+          (pid==SILICOM_PMCXG2BPFI_SSID) || \
+	  (pid==SILICOM_MHIO8AD_SSID) || \
+      (pid==SILICOM_PEG4BPFI5LX_SSID) || \
+      (pid==SILICOM_PEG4BPFI5_SSID) || \
+      (pid==SILICOM_PEG4BPFI6FC_SSID) || \
+      (pid==SILICOM_PEG4BPFI6FCLX_SSID) || \
+      (pid==SILICOM_PEG4BPFI6FCZX_SSID) || \
+          (pid==NOKIA_PMCXG2BPFIN_SSID)|| \
+          (pid==SILICOM_MEG2BPFILXLN_SSID)|| \
+          (pid==SILICOM_MEG2BPFILXNX_SSID)|| \
+          (pid==SILICOM_XE10G2BPIT_SSID)|| \
+           (pid==SILICOM_XE10G2BPICX4_SSID)|| \
+           (pid==SILICOM_XE10G2BPISR_SSID)|| \
+           (pid==NOKIA_XE10G2BPIXR_SSID)|| \
+           (pid==SILICOM_PE10GDBISR_SSID)|| \
+           (pid==SILICOM_PE10GDBILR_SSID)|| \
+           (pid==SILICOM_XE10G2BPILR_SSID))
+
+#define INTEL_IF_SERIES(pid) \
+        ((pid==INTEL_PEG4BPII_SSID)||   \
+        (pid==INTEL_PEG4BPIIO_SSID)|| \
+        (pid==INTEL_PEG4BPFII_SSID))
+
+#define NOKIA_SERIES(pid) \
+        ((pid==NOKIA_PMCXG2BPIN_SSID)||   \
+          (pid==NOKIA_PMCXG4BPIN_SSID)|| \
+          (pid==SILICOM_PMCX4BPI_SSID)|| \
+          (pid==NOKIA_PMCXG2BPFIN_SSID)|| \
+          (pid==SILICOM_PMCXG2BPFI_SSID)|| \
+           (pid==NOKIA_PMCXG2BPIN2_SSID)|| \
+           (pid==NOKIA_PMCXG4BPIN2_SSID)|| \
+           (pid==SILICOM_PMCX2BPI_SSID))
+
+#define DISCF_IF_SERIES(pid) \
+        (pid==SILICOM_PEG2TBFI_SSID)
+
+#define PEGF_IF_SERIES(pid) \
+         ((pid==SILICOM_PEG2BPFI_SSID)||    \
+         (pid==SILICOM_PEG2BPFID_SSID)||    \
+         (pid==SILICOM_PEG2BPFIDLX_SSID)||    \
+         (pid==SILICOM_PEG2BPFILX_SSID)||    \
+          (pid==SILICOM_PEG4BPFI_SSID)||    \
+          (pid==SILICOM_PXEG4BPFI_SSID)||    \
+          (pid==SILICOM_MEG2BPFILN_SSID)|| \
+         (pid==SILICOM_MEG2BPFINX_SSID)|| \
+         (pid==SILICOM_PEG4BPFILX_SSID)|| \
+         (pid==SILICOM_PEG2TBFI_SSID)|| \
+         (pid==SILICOM_MEG2BPFILXLN_SSID)|| \
+         (pid==SILICOM_MEG2BPFILXNX_SSID))
+
+#define TPL_IF_SERIES(pid) \
+        ((pid==SILICOM_PXG2BPFIL_SSID)||   \
+          (pid==SILICOM_PXG2BPFILLX_SSID)|| \
+          (pid==SILICOM_PXG2TBFI_SSID)|| \
+	  (pid==SILICOM_PXG4BPFID_SSID)|| \
+         (pid==SILICOM_PXG4BPFI_SSID))
+
+#define BP10G_IF_SERIES(pid) \
+          ((pid==SILICOM_PE10G2BPISR_SSID)|| \
+          (pid==SILICOM_PE10G2BPICX4_SSID)|| \
+          (pid==SILICOM_PE10G2BPILR_SSID)|| \
+          (pid==SILICOM_XE10G2BPIT_SSID)|| \
+           (pid==SILICOM_XE10G2BPICX4_SSID)|| \
+           (pid==SILICOM_XE10G2BPISR_SSID)|| \
+           (pid==NOKIA_XE10G2BPIXR_SSID)|| \
+           (pid==SILICOM_PE10GDBISR_SSID)|| \
+           (pid==SILICOM_PE10GDBILR_SSID)|| \
+           (pid==SILICOM_XE10G2BPILR_SSID))
+
+#define BP10GB_IF_SERIES(pid) \
+          ((pid==SILICOM_PE10G2BPTCX4_SSID)|| \
+          (pid==SILICOM_PE10G2BPTSR_SSID)|| \
+          (pid==SILICOM_PE10G2BPTLR_SSID)|| \
+          (pid==SILICOM_PE10G2BPTT_SSID))
+
+#define BP10G_CX4_SERIES(pid) \
+    (pid==SILICOM_PE10G2BPICX4_SSID)
+
+#define BP10GB_CX4_SERIES(pid) \
+    (pid==SILICOM_PE10G2BPTCX4_SSID)
+
+#define SILICOM_M2EG2BPFI6_SSID       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_M2EG6BPI6_SSID     0x0540
+
+#define SILICOM_M1E10G2BPI9CX4_SSID  0x481
+#define SILICOM_M1E10G2BPI9SR_SSID   0x482
+#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_PE210G2BPI9CX4_SSID  0x121
+#define SILICOM_PE210G2BPI9SR_SSID   0x122
+#define SILICOM_PE210G2BPI9LR_SSID   0x123
+#define SILICOM_PE210G2BPI9T_SSID    0x120
+
+#define DBI_IF_SERIES(pid) \
+((pid==SILICOM_PE10GDBISR_SSID)|| \
+           (pid==SILICOM_PE10GDBILR_SSID)|| \
+           (pid==SILICOM_XE10G2BPILR_SSID)|| \
+           (pid==SILICOM_PE210G2DBi9LR_SSID))
+
+#define PEGF5_IF_SERIES(pid) \
+((pid==SILICOM_PEG2BPFI5_SSID)|| \
+          (pid==SILICOM_PEG2BPFI5LX_SSID)|| \
+          (pid==SILICOM_PEG4BPFI6_SSID)|| \
+          (pid==SILICOM_PEG4BPFI6LX_SSID)|| \
+           (pid==SILICOM_PEG4BPFI6ZX_SSID)|| \
+           (pid==SILICOM_PEG2BPFI6_SSID)|| \
+           (pid==SILICOM_PEG2BPFI6LX_SSID)|| \
+           (pid==SILICOM_PEG2BPFI6ZX_SSID)|| \
+           (pid==SILICOM_PEG2BPFI6FLXM_SSID)|| \
+           (pid==SILICOM_PEG2DBFI6_SSID)|| \
+           (pid==SILICOM_PEG2DBFI6LX_SSID)|| \
+           (pid==SILICOM_PEG2DBFI6ZX_SSID)|| \
+           (pid==SILICOM_PEG4BPI6FC_SSID)|| \
+           (pid==SILICOM_PEG4BPFI6FCLX_SSID)|| \
+           (pid==SILICOM_PEG4BPI6FC_SSID)|| \
+           (pid==SILICOM_M1EG2BPFI6_SSID)|| \
+           (pid==SILICOM_M1EG2BPFI6LX_SSID)|| \
+           (pid==SILICOM_M1EG2BPFI6ZX_SSID)|| \
+           (pid==SILICOM_M1EG4BPFI6_SSID)|| \
+           (pid==SILICOM_M1EG4BPFI6LX_SSID)|| \
+           (pid==SILICOM_M1EG4BPFI6ZX_SSID)|| \
+           (pid==SILICOM_M2EG2BPFI6_SSID)|| \
+           (pid==SILICOM_M2EG2BPFI6LX_SSID)|| \
+           (pid==SILICOM_M2EG2BPFI6ZX_SSID)|| \
+           (pid==SILICOM_M2EG4BPFI6_SSID)|| \
+           (pid==SILICOM_M2EG4BPFI6LX_SSID)|| \
+           (pid==SILICOM_M2EG4BPFI6ZX_SSID)|| \
+           (pid==SILICOM_PEG4BPFI6FCZX_SSID))
+
+#define PEG5_IF_SERIES(pid) \
+((pid==SILICOM_PEG4BPI6_SSID)|| \
+(pid==SILICOM_PEG2BPI6_SSID)|| \
+(pid==SILICOM_PEG4BPI6FC_SSID)|| \
+(pid==SILICOM_PEG6BPI6_SSID)|| \
+(pid==SILICOM_PEG2BPI6SC6_SSID)|| \
+(pid==SILICOM_MEG2BPI6_SSID)|| \
+(pid==SILICOM_XEG2BPI6_SSID)|| \
+(pid==SILICOM_MEG4BPI6_SSID)|| \
+(pid==SILICOM_M1EG2BPI6_SSID)|| \
+(pid==SILICOM_M1EG4BPI6_SSID)|| \
+(pid==SILICOM_M1EG6BPI6_SSID)|| \
+(pid==SILICOM_PEG6BPI_SSID)|| \
+(pid==SILICOM_PEG4BPIL_SSID)|| \
+(pid==SILICOM_PEG2BISC6_SSID)|| \
+(pid==SILICOM_PEG2BPI5_SSID))
+
+#define PEG80_IF_SERIES(pid) \
+((pid==SILICOM_M1E2G4BPi80_SSID)|| \
+(pid==SILICOM_M6E2G8BPi80_SSID)|| \
+(pid==SILICOM_PE2G4BPi80L_SSID)|| \
+(pid==SILICOM_M6E2G8BPi80A_SSID)|| \
+(pid==SILICOM_PE2G2BPi35_SSID)|| \
+(pid==SILICOM_PAC1200BPi35_SSID)|| \
+(pid==SILICOM_PE2G4BPi35_SSID)|| \
+(pid==SILICOM_PE2G4BPi35L_SSID)|| \
+(pid==SILICOM_PE2G6BPi35_SSID)|| \
+(pid==SILICOM_PE2G2BPi80_SSID)|| \
+(pid==SILICOM_PE2G4BPi80_SSID)|| \
+(pid==SILICOM_PE2G4BPFi80_SSID)|| \
+(pid==SILICOM_PE2G4BPFi80LX_SSID)|| \
+(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \
+(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \
+(pid==SILICOM_PE2G2BPFi80_SSID)|| \
+(pid==SILICOM_PE2G2BPFi80LX_SSID)|| \
+(pid==SILICOM_PE2G2BPFi80ZX_SSID)|| \
+(pid==SILICOM_PE2G2BPFi35_SSID)|| \
+(pid==SILICOM_PE2G2BPFi35LX_SSID)|| \
+(pid==SILICOM_PE2G2BPFi35ZX_SSID)|| \
+(pid==SILICOM_PE2G4BPFi35_SSID)|| \
+(pid==SILICOM_PE2G4BPFi35LX_SSID)|| \
+(pid==SILICOM_PE2G4BPFi35ZX_SSID))
+
+#define PEGF80_IF_SERIES(pid) \
+((pid==SILICOM_PE2G4BPFi80_SSID)|| \
+(pid==SILICOM_PE2G4BPFi80LX_SSID)|| \
+(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \
+(pid==SILICOM_PE2G4BPFi80ZX_SSID)|| \
+(pid==SILICOM_M1E2G4BPFi80_SSID)|| \
+(pid==SILICOM_M1E2G4BPFi80LX_SSID)|| \
+(pid==SILICOM_M1E2G4BPFi80ZX_SSID)|| \
+(pid==SILICOM_PE2G2BPFi80_SSID)|| \
+(pid==SILICOM_PE2G2BPFi80LX_SSID)|| \
+(pid==SILICOM_PE2G2BPFi80ZX_SSID)|| \
+(pid==SILICOM_PE2G2BPFi35_SSID)|| \
+(pid==SILICOM_PE2G2BPFi35LX_SSID)|| \
+(pid==SILICOM_PE2G2BPFi35ZX_SSID)|| \
+(pid==SILICOM_PE2G4BPFi35_SSID)|| \
+(pid==SILICOM_PE2G4BPFi35LX_SSID)|| \
+(pid==SILICOM_PE2G4BPFi35ZX_SSID))
+
+#define BP10G9_IF_SERIES(pid) \
+((pid==INTEL_PE210G2SPI9_SSID)|| \
+(pid==SILICOM_M1E10G2BPI9CX4_SSID)|| \
+(pid==SILICOM_M1E10G2BPI9SR_SSID)|| \
+(pid==SILICOM_M1E10G2BPI9LR_SSID)|| \
+(pid==SILICOM_M1E10G2BPI9T_SSID)|| \
+(pid==SILICOM_M2E10G2BPI9CX4_SSID)|| \
+(pid==SILICOM_M2E10G2BPI9SR_SSID)|| \
+(pid==SILICOM_M2E10G2BPI9LR_SSID)|| \
+(pid==SILICOM_M2E10G2BPI9T_SSID)|| \
+(pid==SILICOM_PE210G2BPI9CX4_SSID)|| \
+(pid==SILICOM_PE210G2BPI9SR_SSID)|| \
+(pid==SILICOM_PE210G2BPI9LR_SSID)|| \
+(pid==SILICOM_PE210G2DBi9SR_SSID)|| \
+(pid==SILICOM_PE210G2DBi9SRRB_SSID)|| \
+(pid==SILICOM_PE210G2DBi9LR_SSID)|| \
+(pid==SILICOM_PE210G2DBi9LRRB_SSID)|| \
+(pid==SILICOM_PE310G4DBi940SR_SSID)|| \
+(pid==SILICOM_PEG2BISC6_SSID)|| \
+(pid==SILICOM_PE310G4BPi9T_SSID)|| \
+(pid==SILICOM_PE310G4BPi9SR_SSID)|| \
+(pid==SILICOM_PE310G4BPi9LR_SSID)|| \
+(pid==SILICOM_PE210G2BPI9T_SSID))
+
+/*******************************************************/
+/* 1G INTERFACE ****************************************/
+/*******************************************************/
+
+/* Intel Registers */
+#define BPCTLI_CTRL          0x00000
+#define BPCTLI_CTRL_SWDPIO0  0x00400000
+#define BPCTLI_CTRL_SWDPIN0  0x00040000
+
+#define BPCTLI_CTRL_EXT 0x00018	/* Extended Device Control - RW */
+#define BPCTLI_STATUS   0x00008	/* Device Status - RO */
+
+/* HW related */
+#define BPCTLI_CTRL_EXT_SDP6_DATA 0x00000040	/* Value of SW Defineable Pin 6 */
+#define BPCTLI_CTRL_EXT_SDP7_DATA 0x00000080	/* Value of SW Defineable Pin 7 */
+#define BPCTLI_CTRL_SDP0_DATA     0x00040000	/* SWDPIN 0 value */
+#define BPCTLI_CTRL_EXT_SDP6_DIR  0x00000400	/* Direction of SDP6 0=in 1=out */
+#define BPCTLI_CTRL_EXT_SDP7_DIR  0x00000800	/* Direction of SDP7 0=in 1=out */
+#define BPCTLI_CTRL_SDP0_DIR      0x00400000	/* SDP0 Input or output */
+#define BPCTLI_CTRL_SWDPIN1       0x00080000
+#define BPCTLI_CTRL_SDP1_DIR      0x00800000
+
+#define BPCTLI_STATUS_LU          0x00000002	/* Link up.0=no,1=link */
+
+#define BPCTLI_CTRL_SDP0_SHIFT     18
+#define BPCTLI_CTRL_EXT_SDP6_SHIFT 6
+
+#define BPCTLI_STATUS_TBIMODE     0x00000020
+#define BPCTLI_CTRL_EXT_LINK_MODE_PCIE_SERDES  0x00C00000
+#define BPCTLI_CTRL_EXT_LINK_MODE_MASK         0x00C00000
+
+#define BPCTLI_CTRL_EXT_MCLK_DIR  BPCTLI_CTRL_EXT_SDP7_DIR
+#define BPCTLI_CTRL_EXT_MCLK_DATA BPCTLI_CTRL_EXT_SDP7_DATA
+#define BPCTLI_CTRL_EXT_MDIO_DIR  BPCTLI_CTRL_EXT_SDP6_DIR
+#define BPCTLI_CTRL_EXT_MDIO_DATA BPCTLI_CTRL_EXT_SDP6_DATA
+
+#define BPCTLI_CTRL_EXT_MCLK_DIR5  BPCTLI_CTRL_SDP1_DIR
+#define BPCTLI_CTRL_EXT_MCLK_DATA5 BPCTLI_CTRL_SWDPIN1
+#define BPCTLI_CTRL_EXT_MCLK_DIR80  BPCTLI_CTRL_EXT_SDP6_DIR
+#define BPCTLI_CTRL_EXT_MCLK_DATA80 BPCTLI_CTRL_EXT_SDP6_DATA
+#define BPCTLI_CTRL_EXT_MDIO_DIR5  BPCTLI_CTRL_SWDPIO0
+#define BPCTLI_CTRL_EXT_MDIO_DATA5 BPCTLI_CTRL_SWDPIN0
+#define BPCTLI_CTRL_EXT_MDIO_DIR80  BPCTLI_CTRL_SWDPIO0
+#define BPCTLI_CTRL_EXT_MDIO_DATA80 BPCTLI_CTRL_SWDPIN0
+
+#define BPCTL_WRITE_REG(a, reg, value) \
+	(writel((value), (void *)(((a)->mem_map) + BPCTLI_##reg)))
+
+#define BPCTL_READ_REG(a, reg) ( \
+        readl((void *)((a)->mem_map) + BPCTLI_##reg))
+
+#define BPCTL_WRITE_FLUSH(a) BPCTL_READ_REG(a, STATUS)
+
+#define BPCTL_BP_WRITE_REG(a, reg, value) ({ \
+        BPCTL_WRITE_REG(a, reg, value); \
+        BPCTL_WRITE_FLUSH(a);})
+
+/**************************************************************/
+/************** 82575 Interface********************************/
+/**************************************************************/
+
+#define BPCTLI_MII_CR_POWER_DOWN       0x0800
+#define BPCTLI_PHY_CONTROL      0x00	/* Control Register */
+#define BPCTLI_MDIC     0x00020	/* MDI Control - RW */
+#define BPCTLI_IGP01E1000_PHY_PAGE_SELECT        0x1F	/* Page Select */
+#define BPCTLI_MAX_PHY_REG_ADDRESS    0x1F	/* 5 bit address bus (0-0x1F) */
+
+#define BPCTLI_MDIC_DATA_MASK 0x0000FFFF
+#define BPCTLI_MDIC_REG_MASK  0x001F0000
+#define BPCTLI_MDIC_REG_SHIFT 16
+#define BPCTLI_MDIC_PHY_MASK  0x03E00000
+#define BPCTLI_MDIC_PHY_SHIFT 21
+#define BPCTLI_MDIC_OP_WRITE  0x04000000
+#define BPCTLI_MDIC_OP_READ   0x08000000
+#define BPCTLI_MDIC_READY     0x10000000
+#define BPCTLI_MDIC_INT_EN    0x20000000
+#define BPCTLI_MDIC_ERROR     0x40000000
+
+#define BPCTLI_SWFW_PHY0_SM  0x02
+#define BPCTLI_SWFW_PHY1_SM  0x04
+
+#define BPCTLI_SW_FW_SYNC  0x05B5C	/* Software-Firmware Synchronization - RW */
+
+#define BPCTLI_SWSM      0x05B50	/* SW Semaphore */
+#define BPCTLI_FWSM      0x05B54	/* FW Semaphore */
+
+#define BPCTLI_SWSM_SMBI         0x00000001	/* Driver Semaphore bit */
+#define BPCTLI_SWSM_SWESMBI      0x00000002	/* FW Semaphore bit */
+#define BPCTLI_MAX_PHY_MULTI_PAGE_REG 0xF
+#define BPCTLI_GEN_POLL_TIMEOUT          640
+
+/********************************************************/
+
+/********************************************************/
+/* 10G INTERFACE ****************************************/
+/********************************************************/
+
+#define BP10G_I2CCTL              0x28
+
+/* I2CCTL Bit Masks */
+#define BP10G_I2C_CLK_IN    0x00000001
+#define BP10G_I2C_CLK_OUT   0x00000002
+#define BP10G_I2C_DATA_IN   0x00000004
+#define BP10G_I2C_DATA_OUT  0x00000008
+
+#define BP10G_ESDP                0x20
+
+#define BP10G_SDP0_DIR            0x100
+#define BP10G_SDP1_DIR            0x200
+#define BP10G_SDP3_DIR            0x800
+#define BP10G_SDP4_DIR            BIT_12
+#define BP10G_SDP5_DIR            0x2000
+#define BP10G_SDP0_DATA           0x001
+#define BP10G_SDP1_DATA           0x002
+#define BP10G_SDP3_DATA           0x008
+#define BP10G_SDP4_DATA           0x010
+#define BP10G_SDP5_DATA           0x020
+
+#define BP10G_SDP2_DIR            0x400
+#define BP10G_SDP2_DATA            0x4
+
+#define BP10G_EODSDP              0x28
+
+#define BP10G_SDP6_DATA_IN        0x001
+#define BP10G_SDP6_DATA_OUT       0x002
+
+#define BP10G_SDP7_DATA_IN        0x004
+#define BP10G_SDP7_DATA_OUT       0x008
+
+#define BP10G_MCLK_DATA_OUT       BP10G_SDP7_DATA_OUT
+#define BP10G_MDIO_DATA_OUT       BP10G_SDP6_DATA_OUT
+#define BP10G_MDIO_DATA_IN        BP10G_SDP6_DATA_IN
+
+#define BP10G_MDIO_DATA           /*BP10G_SDP5_DATA*/ BP10G_SDP3_DATA
+#define BP10G_MDIO_DIR            /*BP10G_SDP5_DIR*/  BP10G_SDP3_DATA
+
+/*#define BP10G_MCLK_DATA_OUT9       BP10G_I2C_CLK_OUT
+#define BP10G_MDIO_DATA_OUT9       BP10G_I2C_DATA_OUT*/
+
+				       /*#define BP10G_MCLK_DATA_OUT9*//*BP10G_I2C_DATA_OUT */
+#define BP10G_MDIO_DATA_OUT9           BP10G_I2C_DATA_OUT	/*BP10G_I2C_CLK_OUT */
+
+/* VIA EOSDP ! */
+#define BP10G_MCLK_DATA_OUT9           BP10G_SDP4_DATA
+#define BP10G_MCLK_DIR_OUT9            BP10G_SDP4_DIR
+
+/*#define BP10G_MDIO_DATA_IN9        BP10G_I2C_DATA_IN*/
+
+#define BP10G_MDIO_DATA_IN9           BP10G_I2C_DATA_IN	/*BP10G_I2C_CLK_IN */
+
+#define BP540_MDIO_DATA           /*BP10G_SDP5_DATA*/ BP10G_SDP0_DATA
+#define BP540_MDIO_DIR            /*BP10G_SDP5_DIR*/  BP10G_SDP0_DIR
+#define BP540_MCLK_DATA       BP10G_SDP2_DATA
+#define BP540_MCLK_DIR       BP10G_SDP2_DIR
+
+#define BP10G_WRITE_REG(a, reg, value) \
+	(writel((value), (void *)(((a)->mem_map) + BP10G_##reg)))
+
+#define BP10G_READ_REG(a, reg) ( \
+        readl((void *)((a)->mem_map) + BP10G_##reg))
+
+/*****BROADCOM*******************************************/
+
+#define BP10GB_MISC_REG_GPIO						 0xa490
+#define BP10GB_GPIO3_P0                              BIT_3
+#define BP10GB_GPIO3_P1                              BIT_7
+
+#define BP10GB_GPIO3_SET_P0                          BIT_11
+#define BP10GB_GPIO3_CLR_P0                          BIT_19
+#define BP10GB_GPIO3_OE_P0                           BIT_27
+
+#define BP10GB_GPIO3_SET_P1                          BIT_15
+#define BP10GB_GPIO3_CLR_P1                          BIT_23
+#define BP10GB_GPIO3_OE_P1                           BIT_31
+
+#define BP10GB_GPIO0_P1                              0x10
+#define BP10GB_GPIO0_P0                              0x1
+#define BP10GB_GPIO0_CLR_P0                          0x10000
+#define BP10GB_GPIO0_CLR_P1                          0x100000
+#define BP10GB_GPIO0_SET_P0                          0x100
+#define BP10GB_GPIO0_SET_P1                          0x1000
+
+#define BP10GB_GPIO0_OE_P1                           0x10000000
+#define BP10GB_GPIO0_OE_P0                           0x1000000
+
+#define BP10GB_MISC_REG_SPIO						 0xa4fc
+#define BP10GB_GPIO4_OE                              BIT_28
+#define BP10GB_GPIO5_OE                              BIT_29
+#define BP10GB_GPIO4_CLR                             BIT_20
+#define BP10GB_GPIO5_CLR                             BIT_21
+#define BP10GB_GPIO4_SET                             BIT_12
+#define BP10GB_GPIO5_SET                             BIT_13
+#define BP10GB_GPIO4                                 BIT_4
+#define BP10GB_GPIO5                                 BIT_5
+
+#define BP10GB_MCLK_DIR  BP10GB_GPIO5_OE
+#define BP10GB_MDIO_DIR  BP10GB_GPIO4_OE
+
+#define BP10GB_MCLK_DATA BP10GB_GPIO5
+#define BP10GB_MDIO_DATA BP10GB_GPIO4
+
+#define BP10GB_MCLK_SET BP10GB_GPIO5_SET
+#define BP10GB_MDIO_SET BP10GB_GPIO4_SET
+
+#define BP10GB_MCLK_CLR BP10GB_GPIO5_CLR
+#define BP10GB_MDIO_CLR BP10GB_GPIO4_CLR
+
+#define BP10GB_WRITE_REG(a, reg, value) \
+	(writel((value), (void *)(((a)->mem_map) + BP10GB_##reg)))
+
+#define BP10GB_READ_REG(a, reg) ( \
+        readl((void *)((a)->mem_map) + BP10GB_##reg))
+
+#endif
+
+int bp_proc_create(void);
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/bp_proc.c working/drivers/staging/silicom/bp_proc.c
--- linux-2.6/drivers/staging/silicom/bp_proc.c	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/bp_proc.c	2012-09-06 18:24:28.366047744 -0700
@@ -0,0 +1,1351 @@
+/******************************************************************************/
+/*                                                                            */
+/* Copyright (c) 2004-2006 Silicom, Ltd                                       */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+
+#include <linux/version.h>
+#if defined(CONFIG_SMP) && ! defined(__SMP__)
+#define __SMP__
+#endif
+
+#include <linux/proc_fs.h>
+#include <linux/netdevice.h>
+#include <asm/uaccess.h>
+//#include <linux/smp_lock.h>
+#include "bp_mod.h"
+
+#define BP_PROC_DIR "bypass"
+//#define BYPASS_SUPPORT "bypass"
+
+#ifdef  BYPASS_SUPPORT
+
+#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"
+#endif				//bypass_support
+static struct proc_dir_entry *bp_procfs_dir;
+
+static struct proc_dir_entry *proc_getdir(char *name,
+					  struct proc_dir_entry *proc_dir)
+{
+	struct proc_dir_entry *pde = proc_dir;
+	for (pde = pde->subdir; pde; pde = pde->next) {
+		if (pde->namelen && (strcmp(name, pde->name) == 0)) {
+			/* directory exists */
+			break;
+		}
+	}
+	if (pde == (struct proc_dir_entry *)0) {
+		/* create the directory */
+		pde = create_proc_entry(name, S_IFDIR, proc_dir);
+		if (pde == (struct proc_dir_entry *)0) {
+			return (pde);
+		}
+	}
+	return (pde);
+}
+
+#ifdef BYPASS_SUPPORT
+
+int
+bypass_proc_create_entry_sd(struct pfs_unit *pfs_unit_curr,
+			    char *proc_name,
+			    write_proc_t * write_proc,
+			    read_proc_t * read_proc,
+			    struct proc_dir_entry *parent_pfs, void *data)
+{
+	strcpy(pfs_unit_curr->proc_name, proc_name);
+	pfs_unit_curr->proc_entry = create_proc_entry(pfs_unit_curr->proc_name,
+						      S_IFREG | S_IRUSR |
+						      S_IWUSR | S_IRGRP |
+						      S_IWGRP | S_IROTH |
+						      S_IWOTH, parent_pfs);
+	if (pfs_unit_curr->proc_entry == 0) {
+
+		return -1;
+	}
+
+	pfs_unit_curr->proc_entry->read_proc = read_proc;
+	pfs_unit_curr->proc_entry->write_proc = write_proc;
+	pfs_unit_curr->proc_entry->data = data;
+
+	return 0;
+
+}
+
+int
+get_bypass_info_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+	int len = 0;
+
+	len += sprintf(page, "Name\t\t\t%s\n", pbp_device_block->bp_name);
+	len +=
+	    sprintf(page + len, "Firmware version\t0x%x\n",
+		    pbp_device_block->bp_fw_ver);
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_bypass_slave_pfs(char *page, char **start, off_t off, int count,
+		     int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	struct pci_dev *pci_slave_dev = pbp_device_block->bp_slave;
+	struct net_device *net_slave_dev;
+	int len = 0;
+
+	if (is_bypass_fn(pbp_device_block)) {
+		net_slave_dev = pci_get_drvdata(pci_slave_dev);
+		if (net_slave_dev)
+			len = sprintf(page, "%s\n", net_slave_dev->name);
+		else
+			len = sprintf(page, "fail\n");
+	} else
+		len = sprintf(page, "fail\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_bypass_caps_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bypass_caps_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "-1\n");
+	else
+		len = sprintf(page, "0x%x\n", ret);
+	*eof = 1;
+	return len;
+
+}
+
+int
+get_wd_set_caps_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_wd_set_caps_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "-1\n");
+	else
+		len = sprintf(page, "0x%x\n", ret);
+	*eof = 1;
+	return len;
+}
+
+int
+set_bypass_pfs(struct file *file, const char *buffer,
+	       unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		bypass_param = 0;
+
+	set_bypass_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+set_tap_pfs(struct file *file, const char *buffer,
+	    unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_tap_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+set_disc_pfs(struct file *file, const char *buffer,
+	     unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_disc_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+get_bypass_pfs(char *page, char **start, off_t off, int count,
+	       int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bypass_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_tap_pfs(char *page, char **start, off_t off, int count,
+	    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_tap_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_disc_pfs(char *page, char **start, off_t off, int count,
+	     int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_disc_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_bypass_change_pfs(char *page, char **start, off_t off, int count,
+		      int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bypass_change_fn(pbp_device_block);
+	if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "fail\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_tap_change_pfs(char *page, char **start, off_t off, int count,
+		   int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_tap_change_fn(pbp_device_block);
+	if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "fail\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_disc_change_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_disc_change_fn(pbp_device_block);
+	if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "fail\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+set_bypass_wd_pfs(struct file *file, const char *buffer,
+		  unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	unsigned int timeout = 0;
+	char *timeout_ptr = kbuf;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	timeout_ptr = kbuf;
+	timeout = atoi(&timeout_ptr);
+
+	set_bypass_wd_fn(pbp_device_block, timeout);
+
+	return count;
+}
+
+int
+get_bypass_wd_pfs(char *page, char **start, off_t off, int count,
+		  int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0, timeout = 0;
+
+	ret = get_bypass_wd_fn(pbp_device_block, &timeout);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (timeout == -1)
+		len = sprintf(page, "unknown\n");
+	else if (timeout == 0)
+		len = sprintf(page, "disable\n");
+	else
+		len = sprintf(page, "%d\n", timeout);
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_wd_expire_time_pfs(char *page, char **start, off_t off, int count,
+		       int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0, timeout = 0;
+
+	ret = get_wd_expire_time_fn(pbp_device_block, &timeout);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (timeout == -1)
+		len = sprintf(page, "expire\n");
+	else if (timeout == 0)
+		len = sprintf(page, "disable\n");
+
+	else
+		len = sprintf(page, "%d\n", timeout);
+	*eof = 1;
+	return len;
+}
+
+int
+get_tpl_pfs(char *page, char **start, off_t off, int count,
+	    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_tpl_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+#ifdef PMC_FIX_FLAG
+int
+get_wait_at_pwup_pfs(char *page, char **start, off_t off, int count,
+		     int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bp_wait_at_pwup_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_hw_reset_pfs(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bp_hw_reset_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 1)
+		len = sprintf(page, "on\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+
+	*eof = 1;
+	return len;
+}
+
+#endif				/*PMC_WAIT_FLAG */
+
+int
+reset_bypass_wd_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = reset_bypass_wd_timer_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "disable\n");
+	else if (ret == 1)
+		len = sprintf(page, "success\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+set_dis_bypass_pfs(struct file *file, const char *buffer,
+		   unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		bypass_param = 0;
+
+	set_dis_bypass_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+set_dis_tap_pfs(struct file *file, const char *buffer,
+		unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_dis_tap_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+set_dis_disc_pfs(struct file *file, const char *buffer,
+		 unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_dis_disc_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+get_dis_bypass_pfs(char *page, char **start, off_t off, int count,
+		   int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_dis_bypass_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_dis_tap_pfs(char *page, char **start, off_t off, int count,
+		int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_dis_tap_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_dis_disc_pfs(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_dis_disc_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+set_bypass_pwup_pfs(struct file *file, const char *buffer,
+		    unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		bypass_param = 0;
+
+	set_bypass_pwup_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+set_bypass_pwoff_pfs(struct file *file, const char *buffer,
+		     unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		bypass_param = 0;
+
+	set_bypass_pwoff_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+set_tap_pwup_pfs(struct file *file, const char *buffer,
+		 unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_tap_pwup_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+set_disc_pwup_pfs(struct file *file, const char *buffer,
+		  unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tap_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tap_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tap_param = 0;
+
+	set_disc_pwup_fn(pbp_device_block, tap_param);
+
+	return count;
+}
+
+int
+get_bypass_pwup_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bypass_pwup_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_bypass_pwoff_pfs(char *page, char **start, off_t off, int count,
+		     int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_bypass_pwoff_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_tap_pwup_pfs(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_tap_pwup_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_disc_pwup_pfs(char *page, char **start, off_t off, int count,
+		  int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_disc_pwup_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+set_std_nic_pfs(struct file *file, const char *buffer,
+		unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		bypass_param = 0;
+
+	set_std_nic_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+get_std_nic_pfs(char *page, char **start, off_t off, int count,
+		int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_std_nic_fn(pbp_device_block);
+	if (ret == BP_NOT_CAP)
+		len = sprintf(page, "fail\n");
+	else if (ret == 0)
+		len = sprintf(page, "off\n");
+	else
+		len = sprintf(page, "on\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+get_wd_exp_mode_pfs(char *page, char **start, off_t off, int count,
+		    int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_wd_exp_mode_fn(pbp_device_block);
+	if (ret == 1)
+		len = sprintf(page, "tap\n");
+	else if (ret == 0)
+		len = sprintf(page, "bypass\n");
+	else if (ret == 2)
+		len = sprintf(page, "disc\n");
+
+	else
+		len = sprintf(page, "fail\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+set_wd_exp_mode_pfs(struct file *file, const char *buffer,
+		    unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int bypass_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "tap") == 0)
+		bypass_param = 1;
+	else if (strcmp(kbuf, "bypass") == 0)
+		bypass_param = 0;
+	else if (strcmp(kbuf, "disc") == 0)
+		bypass_param = 2;
+
+	set_wd_exp_mode_fn(pbp_device_block, bypass_param);
+
+	return count;
+}
+
+int
+get_wd_autoreset_pfs(char *page, char **start, off_t off, int count,
+		     int *eof, void *data)
+{
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int len = 0, ret = 0;
+
+	ret = get_wd_autoreset_fn(pbp_device_block);
+	if (ret >= 0)
+		len = sprintf(page, "%d\n", ret);
+	else
+		len = sprintf(page, "fail\n");
+
+	*eof = 1;
+	return len;
+}
+
+int
+set_wd_autoreset_pfs(struct file *file, const char *buffer,
+		     unsigned long count, void *data)
+{
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+	u32 timeout = 0;
+	char *timeout_ptr = kbuf;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	timeout_ptr = kbuf;
+	timeout = atoi(&timeout_ptr);
+
+	set_wd_autoreset_fn(pbp_device_block, timeout);
+
+	return count;
+}
+
+int
+set_tpl_pfs(struct file *file, const char *buffer,
+	    unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tpl_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tpl_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tpl_param = 0;
+
+	set_tpl_fn(pbp_device_block, tpl_param);
+
+	return count;
+}
+
+#ifdef PMC_FIX_FLAG
+int
+set_wait_at_pwup_pfs(struct file *file, const char *buffer,
+		     unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tpl_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tpl_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tpl_param = 0;
+
+	set_bp_wait_at_pwup_fn(pbp_device_block, tpl_param);
+
+	return count;
+}
+
+int
+set_hw_reset_pfs(struct file *file, const char *buffer,
+		 unsigned long count, void *data)
+{
+
+	char kbuf[256];
+	bpctl_dev_t *pbp_device_block = (bpctl_dev_t *) data;
+
+	int tpl_param = 0, length = 0;
+
+	if (count > (sizeof(kbuf) - 1))
+		return -1;
+
+	if (copy_from_user(&kbuf, buffer, count)) {
+		return -1;
+	}
+
+	kbuf[count] = '\0';
+	length = strlen(kbuf);
+	if (kbuf[length - 1] == '\n')
+		kbuf[--length] = '\0';
+
+	if (strcmp(kbuf, "on") == 0)
+		tpl_param = 1;
+	else if (strcmp(kbuf, "off") == 0)
+		tpl_param = 0;
+
+	set_bp_hw_reset_fn(pbp_device_block, tpl_param);
+
+	return count;
+}
+
+#endif				/*PMC_FIX_FLAG */
+
+int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block)
+{
+	struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set);
+	static struct proc_dir_entry *procfs_dir = NULL;
+	int ret = 0;
+
+	sprintf(current_pfs->dir_name, "bypass_%s", dev->name);
+
+	if (!bp_procfs_dir)
+		return -1;
+
+	/* create device proc dir */
+	procfs_dir = proc_getdir(current_pfs->dir_name, bp_procfs_dir);
+	if (procfs_dir == 0) {
+		printk(KERN_DEBUG "Could not create procfs directory %s\n",
+		       current_pfs->dir_name);
+		return -1;
+	}
+	current_pfs->bypass_entry = procfs_dir;
+
+	if (bypass_proc_create_entry(&(current_pfs->bypass_info), BYPASS_INFO_ENTRY_SD, NULL,	/* write */
+				     get_bypass_info_pfs,	/* read  */
+				     procfs_dir, pbp_device_block))
+		ret = -1;
+
+	if (pbp_device_block->bp_caps & SW_CTL_CAP) {
+
+		/* Create set param proc's */
+		if (bypass_proc_create_entry_sd(&(current_pfs->bypass_slave), BYPASS_SLAVE_ENTRY_SD, NULL,	/* write */
+						get_bypass_slave_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->bypass_caps), BYPASS_CAPS_ENTRY_SD, NULL,	/* write */
+						get_bypass_caps_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->wd_set_caps), WD_SET_CAPS_ENTRY_SD, NULL,	/* write */
+						get_wd_set_caps_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+		if (bypass_proc_create_entry_sd(&(current_pfs->bypass_wd), BYPASS_WD_ENTRY_SD, set_bypass_wd_pfs,	/* write */
+						get_bypass_wd_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->wd_expire_time), WD_EXPIRE_TIME_ENTRY_SD, NULL,	/* write */
+						get_wd_expire_time_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->reset_bypass_wd), RESET_BYPASS_WD_ENTRY_SD, NULL,	/* write */
+						reset_bypass_wd_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->std_nic), STD_NIC_ENTRY_SD, set_std_nic_pfs,	/* write */
+						get_std_nic_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (pbp_device_block->bp_caps & BP_CAP) {
+			if (bypass_proc_create_entry_sd(&(current_pfs->bypass), BYPASS_ENTRY_SD, set_bypass_pfs,	/* write */
+							get_bypass_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->dis_bypass), DIS_BYPASS_ENTRY_SD, set_dis_bypass_pfs,	/* write */
+							get_dis_bypass_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwup), BYPASS_PWUP_ENTRY_SD, set_bypass_pwup_pfs,	/* write */
+							get_bypass_pwup_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+			if (bypass_proc_create_entry_sd(&(current_pfs->bypass_pwoff), BYPASS_PWOFF_ENTRY_SD, set_bypass_pwoff_pfs,	/* write */
+							get_bypass_pwoff_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->bypass_change), BYPASS_CHANGE_ENTRY_SD, NULL,	/* write */
+							get_bypass_change_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+		}
+
+		if (pbp_device_block->bp_caps & TAP_CAP) {
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap), TAP_ENTRY_SD, set_tap_pfs,	/* write */
+							get_tap_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_TAP_ENTRY_SD, set_dis_tap_pfs,	/* write */
+							get_dis_tap_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), TAP_PWUP_ENTRY_SD, set_tap_pwup_pfs,	/* write */
+							get_tap_pwup_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), TAP_CHANGE_ENTRY_SD, NULL,	/* write */
+							get_tap_change_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+		}
+		if (pbp_device_block->bp_caps & DISC_CAP) {
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap), DISC_ENTRY_SD, set_disc_pfs,	/* write */
+							get_disc_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+#if 1
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->dis_tap), DIS_DISC_ENTRY_SD, set_dis_disc_pfs,	/* write */
+							get_dis_disc_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+#endif
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap_pwup), DISC_PWUP_ENTRY_SD, set_disc_pwup_pfs,	/* write */
+							get_disc_pwup_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+
+			if (bypass_proc_create_entry_sd(&(current_pfs->tap_change), DISC_CHANGE_ENTRY_SD, NULL,	/* write */
+							get_disc_change_pfs,	/* read  */
+							procfs_dir,
+							pbp_device_block))
+				ret = -1;
+		}
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->wd_exp_mode), WD_EXP_MODE_ENTRY_SD, set_wd_exp_mode_pfs,	/* write */
+						get_wd_exp_mode_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+		if (bypass_proc_create_entry_sd(&(current_pfs->wd_autoreset), WD_AUTORESET_ENTRY_SD, set_wd_autoreset_pfs,	/* write */
+						get_wd_autoreset_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+		if (bypass_proc_create_entry_sd(&(current_pfs->tpl), TPL_ENTRY_SD, set_tpl_pfs,	/* write */
+						get_tpl_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+#ifdef PMC_FIX_FLAG
+		if (bypass_proc_create_entry_sd(&(current_pfs->tpl), WAIT_AT_PWUP_ENTRY_SD, set_wait_at_pwup_pfs,	/* write */
+						get_wait_at_pwup_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+		if (bypass_proc_create_entry_sd(&(current_pfs->tpl), HW_RESET_ENTRY_SD, set_hw_reset_pfs,	/* write */
+						get_hw_reset_pfs,	/* read  */
+						procfs_dir, pbp_device_block))
+			ret = -1;
+
+#endif
+
+	}
+	if (ret < 0)
+		printk(KERN_DEBUG "Create proc entry failed\n");
+
+	return ret;
+}
+
+int bypass_proc_remove_dev_sd(bpctl_dev_t * pbp_device_block)
+{
+
+	struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set;
+	struct proc_dir_entry *pde = current_pfs->bypass_entry, *pde_curr =
+	    NULL;
+	char name[256];
+
+	for (pde = pde->subdir; pde;) {
+		strcpy(name, pde->name);
+		pde_curr = pde;
+		pde = pde->next;
+		remove_proc_entry(name, current_pfs->bypass_entry);
+	}
+	if (!pde)
+		remove_proc_entry(current_pfs->dir_name, bp_procfs_dir);
+
+	return 0;
+}
+
+#endif				/* BYPASS_SUPPORT */
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/bypass.h working/drivers/staging/silicom/bypass.h
--- linux-2.6/drivers/staging/silicom/bypass.h	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/bypass.h	2012-09-06 18:24:28.367047744 -0700
@@ -0,0 +1,202 @@
+/******************************************************************************/
+/*                                                                            */
+/* Bypass Control utility, Copyright (c) 2005 Silicom                         */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+
+#ifndef BYPASS_H
+#define BYPASS_H
+
+/* Bypass related */
+
+#define SYNC_CMD_VAL               2	/* 10b */
+#define SYNC_CMD_LEN               2
+
+#define WR_CMD_VAL                 2	/* 10b */
+#define WR_CMD_LEN                 2
+
+#define RD_CMD_VAL                 1	/* 10b */
+#define RD_CMD_LEN                 2
+
+#define ADDR_CMD_LEN               4
+
+#define WR_DATA_LEN                8
+#define RD_DATA_LEN                8
+
+#define PIC_SIGN_REG_ADDR          0x7
+#define PIC_SIGN_VALUE         0xcd
+
+#define STATUS_REG_ADDR           0
+#define WDT_EN_MASK            0x01	//BIT_0
+#define CMND_EN_MASK           0x02	//BIT_1
+#define DIS_BYPASS_CAP_MASK    0x04	//BIT_2 /* Bypass Cap is disable*/
+#define DFLT_PWRON_MASK        0x08	//BIT_3
+#define BYPASS_OFF_MASK        0x10	//BIT_4
+#define BYPASS_FLAG_MASK       0x20	//BIT_5
+#define STD_NIC_MASK           (DIS_BYPASS_CAP_MASK | BYPASS_OFF_MASK | DFLT_PWRON_MASK)
+#define WD_EXP_FLAG_MASK       0x40	//BIT_6
+#define DFLT_PWROFF_MASK       0x80	//BIT_7
+#define STD_NIC_PWOFF_MASK     (DIS_BYPASS_CAP_MASK | BYPASS_OFF_MASK | DFLT_PWRON_MASK | DFLT_PWROFF_MASK)
+
+#define PRODUCT_CAP_REG_ADDR   0x5
+#define BYPASS_SUPPORT_MASK    0x01	//BIT_0
+#define TAP_SUPPORT_MASK       0x02	//BIT_1
+#define NORMAL_UNSUPPORT_MASK  0x04	/*BIT_2 */
+#define DISC_SUPPORT_MASK      0x08	//BIT_3
+#define TPL2_SUPPORT_MASK      0x10	//BIT_4
+#define DISC_PORT_SUPPORT_MASK 0x20	//BIT_5
+
+#define STATUS_TAP_REG_ADDR    0x6
+#define WDTE_TAP_BPN_MASK      0x01	//BIT_1 /* 1 when wdt expired -> TAP, 0 - Bypass */
+#define DIS_TAP_CAP_MASK       0x04	//BIT_2 /* TAP Cap is disable*/
+#define DFLT_PWRON_TAP_MASK    0x08	//BIT_3
+#define TAP_OFF_MASK           0x10	//BIT_4
+#define TAP_FLAG_MASK          0x20	//BIT_5
+#define TX_DISA_MASK            0x40
+#define TX_DISB_MASK            0x80
+
+#define STD_NIC_TAP_MASK       (DIS_TAP_CAP_MASK | TAP_OFF_MASK | DFLT_PWRON_TAP_MASK)
+
+#define STATUS_DISC_REG_ADDR    13
+#define WDTE_DISC_BPN_MASK      0x01	//BIT_0 /* 1 when wdt expired -> TAP, 0 - Bypass */
+#define STD_NIC_ON_MASK         0x02	//BIT_1
+#define DIS_DISC_CAP_MASK       0x04	//BIT_2 /* TAP Cap is disable*/
+#define DFLT_PWRON_DISC_MASK    0x08	//BIT_3
+#define DISC_OFF_MASK           0x10	//BIT_4
+#define DISC_FLAG_MASK          0x20	//BIT_5
+#define TPL2_FLAG_MASK          0x40	//BIT_6
+#define STD_NIC_DISC_MASK       DIS_DISC_CAP_MASK
+
+#define CONT_CONFIG_REG_ADDR    12
+#define EN_HW_RESET_MASK       0x2	/* BIT_1 */
+#define WAIT_AT_PWUP_MASK      0x1	/* BIT_0 */
+
+#define VER_REG_ADDR               0x1
+#define BP_FW_VER_A0         0xa0
+#define BP_FW_VER_A1         0xa1
+
+#define INT_VER_MASK           0xf0
+#define EXT_VER_MASK           0xf
+/* */
+#define PXG2BPI_VER            0x0
+#define PXG2TBPI_VER           0x1
+#define PXE2TBPI_VER           0x2
+#define PXG4BPFI_VER           0x4
+#define BP_FW_EXT_VER7         0x6
+#define BP_FW_EXT_VER8         0x8
+#define BP_FW_EXT_VER9         0x9
+
+#define OLD_IF_VER              -1
+
+#define CMND_REG_ADDR              10	/* 1010b */
+#define WDT_REG_ADDR               4
+#define TMRL_REG_ADDR              2
+#define TMRH_REG_ADDR              3
+
+/* NEW_FW */
+#define WDT_INTERVAL               1	//5     //8
+#define WDT_CMND_INTERVAL          200	//50
+#define CMND_INTERVAL              200	//100  /* usec */
+#define PULSE_TIME                 100
+
+/* OLD_FW */
+#define INIT_CMND_INTERVAL         40
+#define PULSE_INTERVAL             5
+#define WDT_TIME_CNT               3
+
+/* Intel Commands */
+
+#define CMND_OFF_INT               0xf
+#define PWROFF_BYPASS_ON_INT       0x5
+#define BYPASS_ON_INT              0x6
+#define DIS_BYPASS_CAP_INT         0x4
+#define RESET_WDT_INT              0x1
+
+/* Intel timing */
+
+#define BYPASS_DELAY_INT           4	/* msec */
+#define CMND_INTERVAL_INT          2	/* msec */
+
+/* Silicom Commands */
+#define CMND_ON                    0x4
+#define CMND_OFF                   0x2
+#define BYPASS_ON                  0xa
+#define BYPASS_OFF                 0x8
+#define PORT_LINK_EN               0xe
+#define PORT_LINK_DIS              0xc
+#define WDT_ON                     0x10	/* 0x1f (11111) - max */
+#define TIMEOUT_UNIT           100
+#define TIMEOUT_MAX_STEP       15
+#define WDT_TIMEOUT_MIN        100	/*  msec */
+#define WDT_TIMEOUT_MAX        3276800	/*  msec */
+#define WDT_AUTO_MIN_INT           500
+#define WDT_TIMEOUT_DEF        WDT_TIMEOUT_MIN
+#define WDT_OFF                    0x6
+#define WDT_RELOAD                 0x9
+#define RESET_CONT                 0x20
+#define DIS_BYPASS_CAP             0x22
+#define EN_BYPASS_CAP              0x24
+#define BYPASS_STATE_PWRON         0x26
+#define NORMAL_STATE_PWRON         0x28
+#define BYPASS_STATE_PWROFF        0x27
+#define NORMAL_STATE_PWROFF        0x29
+#define TAP_ON                     0xb
+#define TAP_OFF                    0x9
+#define TAP_STATE_PWRON            0x2a
+#define DIS_TAP_CAP                0x2c
+#define EN_TAP_CAP                 0x2e
+#define STD_NIC_OFF       0x86
+#define STD_NIC_ON       0x84
+#define DISC_ON           0x85
+#define DISC_OFF          0x8a
+#define DISC_STATE_PWRON  0x87
+#define DIS_DISC_CAP      0x88
+#define EN_DISC_CAP       0x89
+#define TPL2_ON                    0x8c
+#define TPL2_OFF                   0x8b
+#define BP_WAIT_AT_PWUP_EN        0x80
+#define BP_WAIT_AT_PWUP_DIS       0x81
+#define BP_HW_RESET_EN             0x82
+#define BP_HW_RESET_DIS            0x83
+
+#define TX_DISA                0x8d
+#define TX_DISB                0x8e
+#define TX_ENA                 0xA0
+#define TX_ENB                 0xA1
+
+#define TX_DISA_PWRUP          0xA2
+#define TX_DISB_PWRUP          0xA3
+#define TX_ENA_PWRUP           0xA4
+#define TX_ENB_PWRUP           0xA5
+
+#define BYPASS_CAP_DELAY           21	/* msec */
+#define DFLT_PWRON_DELAY           10	/* msec */
+#define LATCH_DELAY                13	/* msec */
+#define EEPROM_WR_DELAY             8	/* msec */
+
+#define BP_LINK_MON_DELAY          4	/* sec */
+
+#define BP_FW_EXT_VER0                 0xa0
+#define BP_FW_EXT_VER1                 0xa1
+#define BP_FW_EXT_VER2                0xb1
+
+#define BP_OK        0
+#define BP_NOT_CAP  -1
+#define WDT_STATUS_EXP -2
+#define WDT_STATUS_UNKNOWN -1
+#define WDT_STATUS_EN 1
+#define WDT_STATUS_DIS 0
+
+#ifdef BP_SELF_TEST
+#define ETH_P_BPTEST 0xabba
+
+#define BPTEST_DATA_LEN 60
+#endif
+
+#endif				/* BYPASS_H */
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/bypasslib/bp_ioctl.h working/drivers/staging/silicom/bypasslib/bp_ioctl.h
--- linux-2.6/drivers/staging/silicom/bypasslib/bp_ioctl.h	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/bypasslib/bp_ioctl.h	2012-09-06 18:24:28.367047744 -0700
@@ -0,0 +1,199 @@
+/******************************************************************************/
+/*                                                                            */
+/* bypass library, Copyright (c) 2004-2006 Silicom, Ltd                       */
+/* Corporation.                                                               */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/*                                                                            */
+/*                                                                            */
+/******************************************************************************/
+
+#ifndef BP_IOCTL_H
+#define BP_IOCTL_H
+
+#define BP_CAP                   0x01	//BIT_0
+#define BP_STATUS_CAP            0x02	//BIT_1
+#define BP_STATUS_CHANGE_CAP     0x04	//BIT_2
+#define SW_CTL_CAP               0x08	//BIT_3
+#define BP_DIS_CAP               0x10	//BIT_4
+#define BP_DIS_STATUS_CAP        0x20	//BIT_5
+#define STD_NIC_CAP              0x40	//BIT_6
+#define BP_PWOFF_ON_CAP          0x80	//BIT_7
+#define BP_PWOFF_OFF_CAP         0x0100	//BIT_8
+#define BP_PWOFF_CTL_CAP         0x0200	//BIT_9
+#define BP_PWUP_ON_CAP           0x0400	//BIT_10
+#define BP_PWUP_OFF_CAP          0x0800	//BIT_11
+#define BP_PWUP_CTL_CAP          0x1000	//BIT_12
+#define WD_CTL_CAP               0x2000	//BIT_13
+#define WD_STATUS_CAP            0x4000	//BIT_14
+#define WD_TIMEOUT_CAP           0x8000	//BIT_15
+#define TX_CTL_CAP               0x10000	//BIT_16
+#define TX_STATUS_CAP            0x20000	//BIT_17
+#define TAP_CAP                  0x40000	//BIT_18
+#define TAP_STATUS_CAP           0x80000	//BIT_19
+#define TAP_STATUS_CHANGE_CAP    0x100000	//BIT_20
+#define TAP_DIS_CAP              0x200000	//BIT_21
+#define TAP_DIS_STATUS_CAP       0x400000	//BIT_22
+#define TAP_PWUP_ON_CAP          0x800000	//BIT_23
+#define TAP_PWUP_OFF_CAP         0x1000000	//BIT 24
+#define TAP_PWUP_CTL_CAP         0x2000000	//BIT 25
+#define NIC_CAP_NEG              0x4000000	//BIT 26
+#define TPL_CAP                  0x8000000	//BIT 27
+#define DISC_CAP                 0x10000000	//BIT 28
+#define DISC_DIS_CAP             0x20000000	//BIT 29
+#define DISC_PWUP_CTL_CAP        0x40000000	//BIT 30
+
+#define WD_MIN_TIME_MASK(val)      (val & 0xf)
+#define WD_STEP_COUNT_MASK(val)    ((val & 0xf) << 5)
+#define WDT_STEP_TIME              0x10	//BIT_4
+
+#define WD_MIN_TIME_GET(desc)   (desc & 0xf)
+#define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf
+
+typedef enum {
+	IS_BYPASS = 1,
+	GET_BYPASS_SLAVE,
+	GET_BYPASS_CAPS,
+	GET_WD_SET_CAPS,
+	SET_BYPASS,
+	GET_BYPASS,
+	GET_BYPASS_CHANGE,
+	SET_BYPASS_WD,
+	GET_BYPASS_WD,
+	GET_WD_EXPIRE_TIME,
+	RESET_BYPASS_WD_TIMER,
+	SET_DIS_BYPASS,
+	GET_DIS_BYPASS,
+	SET_BYPASS_PWOFF,
+	GET_BYPASS_PWOFF,
+	SET_BYPASS_PWUP,
+	GET_BYPASS_PWUP,
+	SET_STD_NIC,
+	GET_STD_NIC,
+	SET_TX,
+	GET_TX,
+	SET_TAP,
+	GET_TAP,
+	GET_TAP_CHANGE,
+	SET_DIS_TAP,
+	GET_DIS_TAP,
+	SET_TAP_PWUP,
+	GET_TAP_PWUP,
+	SET_WD_EXP_MODE,
+	GET_WD_EXP_MODE,
+	SET_WD_AUTORESET,
+	GET_WD_AUTORESET,
+	SET_TPL,
+	GET_TPL,
+	SET_DISC,
+	GET_DISC,
+	GET_DISC_CHANGE,
+	SET_DIS_DISC,
+	GET_DIS_DISC,
+	SET_DISC_PWUP,
+	GET_DISC_PWUP,
+
+	GET_BYPASS_INFO = 100,
+	GET_BP_WAIT_AT_PWUP,
+	SET_BP_WAIT_AT_PWUP,
+	GET_BP_HW_RESET,
+	SET_BP_HW_RESET,
+} CMND_TYPE;
+
+typedef enum {
+	IF_SCAN_SD,
+	GET_DEV_NUM_SD,
+	IS_BYPASS_SD,
+	GET_BYPASS_SLAVE_SD,
+	GET_BYPASS_CAPS_SD,
+	GET_WD_SET_CAPS_SD,
+	SET_BYPASS_SD,
+	GET_BYPASS_SD,
+	GET_BYPASS_CHANGE_SD,
+	SET_BYPASS_WD_SD,
+	GET_BYPASS_WD_SD,
+	GET_WD_EXPIRE_TIME_SD,
+	RESET_BYPASS_WD_TIMER_SD,
+	SET_DIS_BYPASS_SD,
+	GET_DIS_BYPASS_SD,
+	SET_BYPASS_PWOFF_SD,
+	GET_BYPASS_PWOFF_SD,
+	SET_BYPASS_PWUP_SD,
+	GET_BYPASS_PWUP_SD,
+	SET_STD_NIC_SD,
+	GET_STD_NIC_SD,
+	SET_TX_SD,
+	GET_TX_SD,
+	SET_TAP_SD,
+	GET_TAP_SD,
+	GET_TAP_CHANGE_SD,
+	SET_DIS_TAP_SD,
+	GET_DIS_TAP_SD,
+	SET_TAP_PWUP_SD,
+	GET_TAP_PWUP_SD,
+	SET_WD_EXP_MODE_SD,
+	GET_WD_EXP_MODE_SD,
+	SET_WD_AUTORESET_SD,
+	GET_WD_AUTORESET_SD,
+	SET_TPL_SD,
+	GET_TPL_SD,
+	SET_DISC_SD,
+	GET_DISC_SD,
+	GET_DISC_CHANGE_SD,
+	SET_DIS_DISC_SD,
+	GET_DIS_DISC_SD,
+	SET_DISC_PWUP_SD,
+	GET_DISC_PWUP_SD,
+
+	GET_BYPASS_INFO_SD = 100,
+	GET_BP_WAIT_AT_PWUP_SD,
+	SET_BP_WAIT_AT_PWUP_SD,
+	GET_BP_HW_RESET_SD,
+	SET_BP_HW_RESET_SD,
+
+} CMND_TYPE_SD;
+
+#define SIOCGIFBYPASS SIOCDEVPRIVATE+10
+
+struct bp_info {
+	char prod_name[14];
+	unsigned char fw_ver;
+};
+
+/* for passing single values */
+struct if_bypass {
+	char if_name[IFNAMSIZ];
+	int cmd;
+	int data;
+};
+struct if_bypass_info {
+	char if_name[IFNAMSIZ];
+	char cmd;
+	struct bp_info bp_info;
+};
+
+/*
+* The major device number. We can't rely on dynamic
+* registration any more, because ioctls need to know
+* it.
+*/
+
+#define MAGIC_NUM 'J'
+
+/* for passing single values */
+struct bpctl_cmd {
+	int status;
+	int data[8];
+	int in_param[8];
+	int out_param[8];
+};
+
+#define IOCTL_TX_MSG(cmd) _IOWR(MAGIC_NUM, cmd, struct bpctl_cmd)
+
+#define DEVICE_NODE "/dev/bpctl0"
+#define DEVICE_NAME "bpctl"
+
+#endif
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/bypasslib/bplibk.h working/drivers/staging/silicom/bypasslib/bplibk.h
--- linux-2.6/drivers/staging/silicom/bypasslib/bplibk.h	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/bypasslib/bplibk.h	2012-09-06 18:24:28.368047744 -0700
@@ -0,0 +1,47 @@
+/******************************************************************************/
+/*                                                                            */
+/* bypass library, Copyright (c) 2004 Silicom, Ltd                            */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/*                                                                            */
+/* bplib.h                                                                    */
+/*                                                                            */
+/******************************************************************************/
+#ifndef BYPASS_H
+#define BYPASS_H
+
+#include "bp_ioctl.h"
+#include "libbp_sd.h"
+
+#define IF_NAME            "eth"
+#define SILICOM_VID        0x1374
+#define SILICOM_BP_PID_MIN 0x24
+#define SILICOM_BP_PID_MAX 0x5f
+#define INTEL_PEG4BPII_PID  0x10a0
+#define INTEL_PEG4BPFII_PID 0x10a1
+
+#define PEGII_IF_SERIES(vid, pid) \
+        ((vid==0x8086)&& \
+        ((pid==INTEL_PEG4BPII_PID)||   \
+          (pid==INTEL_PEG4BPFII_PID)))
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10))
+#define pci_get_class pci_find_class
+
+#define pci_get_device pci_find_device
+
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
+#define EXPORT_SYMBOL_NOVERS EXPORT_SYMBOL
+#endif
+
+#ifdef BP_VENDOR_SUPPORT
+char *bp_desc_array[] =
+    { "e1000bp", "e1000bpe", "slcm5700", "bnx2xbp", "ixgbp", "ixgbpe", NULL };
+#endif
+
+#endif
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/bypasslib/bypass.c working/drivers/staging/silicom/bypasslib/bypass.c
--- linux-2.6/drivers/staging/silicom/bypasslib/bypass.c	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/bypasslib/bypass.c	2012-09-06 18:24:28.368047744 -0700
@@ -0,0 +1,529 @@
+/******************************************************************************/
+/*                                                                            */
+/* bypass library, Copyright (c) 2004-2007 Silicom, Ltd                       */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/*                                                                            */
+/* bypass.c                                                                    */
+/*                                                                            */
+/******************************************************************************/
+
+#include <linux/version.h>
+#if defined(CONFIG_SMP) && ! defined(__SMP__)
+#define __SMP__
+#endif
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <asm/unistd.h>
+
+#include <linux/sched.h>
+#include <linux/wait.h>
+
+#include <linux/netdevice.h>	// struct device, and other headers
+#include <linux/kernel_stat.h>
+#include <linux/pci.h>
+#include <linux/rtnetlink.h>
+#include <linux/ethtool.h>
+
+#include <net/net_namespace.h>
+
+#include "bplibk.h"
+
+#define MOD_NAME "bypass"
+
+#define VERSION "\n"MOD_NAME" version 9.0.4\n"
+
+MODULE_AUTHOR("www.silicom.co.il");
+
+MODULE_LICENSE("GPL");
+
+int init_lib_module(void);
+void cleanup_lib_module(void);
+
+static int do_cmd(struct net_device *dev, struct ifreq *ifr, int cmd, int *data)
+{
+	int ret = -1;
+	struct if_bypass *bypass_cb;
+	static int (*ioctl) (struct net_device *, struct ifreq *, int);
+
+	bypass_cb = (struct if_bypass *)ifr;
+	bypass_cb->cmd = cmd;
+	bypass_cb->data = *data;
+	if ((dev->netdev_ops) && (ioctl = dev->netdev_ops->ndo_do_ioctl)) {
+		ret = ioctl(dev, ifr, SIOCGIFBYPASS);
+		*data = bypass_cb->data;
+	}
+
+	return ret;
+}
+
+static int doit(int cmd, int if_index, int *data)
+{
+	struct ifreq ifr;
+	int ret = -1;
+	struct net_device *dev;
+	struct net_device *n;
+	for_each_netdev_safe(&init_net, dev, n) {
+
+		if (dev->ifindex == if_index) {
+			ret = do_cmd(dev, &ifr, cmd, data);
+			if (ret < 0)
+				ret = -1;
+
+		}
+	}
+
+	return ret;
+}
+
+#define bp_symbol_get(fn_name) symbol_get(fn_name)
+#define bp_symbol_put(fn_name) symbol_put(fn_name)
+
+#define SET_BPLIB_INT_FN(fn_name, arg_type, arg, ret) \
+    ({ int (* fn_ex)(arg_type)=NULL; \
+    fn_ex=bp_symbol_get(fn_name##_sd); \
+       if(fn_ex) {  \
+        ret= fn_ex(arg); \
+       bp_symbol_put(fn_name##_sd); \
+       } else ret=-1; \
+    })
+
+#define  SET_BPLIB_INT_FN2(fn_name, arg_type, arg, arg_type1, arg1, ret) \
+    ({ int (* fn_ex)(arg_type,arg_type1)=NULL; \
+        fn_ex=bp_symbol_get(fn_name##_sd); \
+       if(fn_ex) {  \
+        ret= fn_ex(arg,arg1); \
+        bp_symbol_put(fn_name##_sd); \
+       } else ret=-1; \
+    })
+#define SET_BPLIB_INT_FN3(fn_name, arg_type, arg, arg_type1, arg1,arg_type2, arg2, ret) \
+    ({ int (* fn_ex)(arg_type,arg_type1, arg_type2)=NULL; \
+        fn_ex=bp_symbol_get(fn_name##_sd); \
+       if(fn_ex) {  \
+        ret= fn_ex(arg,arg1,arg2); \
+        bp_symbol_put(fn_name##_sd); \
+       } else ret=-1; \
+    })
+
+#define DO_BPLIB_GET_ARG_FN(fn_name,ioctl_val, if_index) \
+    ({    int data, ret=0; \
+            if(is_dev_sd(if_index)){ \
+            SET_BPLIB_INT_FN(fn_name, int, if_index, ret); \
+            return ret; \
+            }  \
+            return doit(ioctl_val,if_index, &data); \
+    })
+
+#define DO_BPLIB_SET_ARG_FN(fn_name,ioctl_val,if_index,arg) \
+    ({    int data, ret=0; \
+            if(is_dev_sd(if_index)){ \
+            SET_BPLIB_INT_FN2(fn_name, int, if_index, int, arg, ret); \
+            return ret; \
+            }  \
+	    data=arg; \
+            return doit(ioctl_val,if_index, &data); \
+    })
+
+static int is_dev_sd(int if_index)
+{
+	int ret = 0;
+	SET_BPLIB_INT_FN(is_bypass, int, if_index, ret);
+	return (ret >= 0 ? 1 : 0);
+}
+
+int is_bypass_dev(int if_index)
+{
+	struct pci_dev *pdev = NULL;
+	struct net_device *dev = NULL;
+	struct ifreq ifr;
+	int ret = 0, data = 0;
+
+	while ((pdev = pci_get_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) {
+		if ((dev = pci_get_drvdata(pdev)) != NULL)
+			if (((dev = pci_get_drvdata(pdev)) != NULL) &&
+			    (dev->ifindex == if_index)) {
+				if ((pdev->vendor == SILICOM_VID) &&
+				    (pdev->device >= SILICOM_BP_PID_MIN) &&
+				    (pdev->device <= SILICOM_BP_PID_MAX))
+					goto send_cmd;
+#if defined(BP_VENDOR_SUPPORT) && defined(ETHTOOL_GDRVINFO)
+				else {
+					struct ethtool_drvinfo info;
+					const struct ethtool_ops *ops =
+					    dev->ethtool_ops;
+					int k = 0;
+
+					if (ops->get_drvinfo) {
+						memset(&info, 0, sizeof(info));
+						info.cmd = ETHTOOL_GDRVINFO;
+						ops->get_drvinfo(dev, &info);
+						for (; bp_desc_array[k]; k++)
+							if (!
+							    (strcmp
+							     (bp_desc_array[k],
+							      info.driver)))
+								goto send_cmd;
+
+					}
+
+				}
+#endif
+				return -1;
+			}
+	}
+ send_cmd:
+	ret = do_cmd(dev, &ifr, IS_BYPASS, &data);
+	return (ret < 0 ? -1 : ret);
+}
+
+int is_bypass(int if_index)
+{
+	int ret = 0;
+	SET_BPLIB_INT_FN(is_bypass, int, if_index, ret);
+
+	if (ret < 0)
+		return is_bypass_dev(if_index);
+	return ret;
+}
+
+int get_bypass_slave(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_bypass_slave, GET_BYPASS_SLAVE, if_index);
+}
+
+int get_bypass_caps(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_bypass_caps, GET_BYPASS_CAPS, if_index);
+}
+
+int get_wd_set_caps(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_wd_set_caps, GET_WD_SET_CAPS, if_index);
+}
+
+int set_bypass(int if_index, int bypass_mode)
+{
+	DO_BPLIB_SET_ARG_FN(set_bypass, SET_BYPASS, if_index, bypass_mode);
+}
+
+int get_bypass(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_bypass, GET_BYPASS, if_index);
+}
+
+int get_bypass_change(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_bypass_change, GET_BYPASS_CHANGE, if_index);
+}
+
+int set_dis_bypass(int if_index, int dis_bypass)
+{
+	DO_BPLIB_SET_ARG_FN(set_dis_bypass, SET_DIS_BYPASS, if_index,
+			    dis_bypass);
+}
+
+int get_dis_bypass(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_dis_bypass, GET_DIS_BYPASS, if_index);
+}
+
+int set_bypass_pwoff(int if_index, int bypass_mode)
+{
+	DO_BPLIB_SET_ARG_FN(set_bypass_pwoff, SET_BYPASS_PWOFF, if_index,
+			    bypass_mode);
+}
+
+int get_bypass_pwoff(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_bypass_pwoff, GET_BYPASS_PWOFF, if_index);
+}
+
+int set_bypass_pwup(int if_index, int bypass_mode)
+{
+	DO_BPLIB_SET_ARG_FN(set_bypass_pwup, SET_BYPASS_PWUP, if_index,
+			    bypass_mode);
+}
+
+int get_bypass_pwup(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_bypass_pwup, GET_BYPASS_PWUP, if_index);
+}
+
+int set_bypass_wd(int if_index, int ms_timeout, int *ms_timeout_set)
+{
+	int data = ms_timeout, ret = 0;
+	if (is_dev_sd(if_index))
+		SET_BPLIB_INT_FN3(set_bypass_wd, int, if_index, int, ms_timeout,
+				  int *, ms_timeout_set, ret);
+	else {
+		ret = doit(SET_BYPASS_WD, if_index, &data);
+		if (ret > 0) {
+			*ms_timeout_set = ret;
+			ret = 0;
+		}
+	}
+	return ret;
+}
+
+int get_bypass_wd(int if_index, int *ms_timeout_set)
+{
+	int *data = ms_timeout_set, ret = 0;
+	if (is_dev_sd(if_index))
+		SET_BPLIB_INT_FN2(get_bypass_wd, int, if_index, int *,
+				  ms_timeout_set, ret);
+	else
+		ret = doit(GET_BYPASS_WD, if_index, data);
+	return ret;
+}
+
+int get_wd_expire_time(int if_index, int *ms_time_left)
+{
+	int *data = ms_time_left, ret = 0;
+	if (is_dev_sd(if_index))
+		SET_BPLIB_INT_FN2(get_wd_expire_time, int, if_index, int *,
+				  ms_time_left, ret);
+	else {
+		ret = doit(GET_WD_EXPIRE_TIME, if_index, data);
+		if ((ret == 0) && (*data != 0))
+			ret = 1;
+	}
+	return ret;
+}
+
+int reset_bypass_wd_timer(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(reset_bypass_wd_timer, RESET_BYPASS_WD_TIMER,
+			    if_index);
+}
+
+int set_std_nic(int if_index, int bypass_mode)
+{
+	DO_BPLIB_SET_ARG_FN(set_std_nic, SET_STD_NIC, if_index, bypass_mode);
+}
+
+int get_std_nic(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_std_nic, GET_STD_NIC, if_index);
+}
+
+int set_tx(int if_index, int tx_state)
+{
+	DO_BPLIB_SET_ARG_FN(set_tx, SET_TX, if_index, tx_state);
+}
+
+int get_tx(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_tx, GET_TX, if_index);
+}
+
+int set_tap(int if_index, int tap_mode)
+{
+	DO_BPLIB_SET_ARG_FN(set_tap, SET_TAP, if_index, tap_mode);
+}
+
+int get_tap(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_tap, GET_TAP, if_index);
+}
+
+int get_tap_change(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_tap_change, GET_TAP_CHANGE, if_index);
+}
+
+int set_dis_tap(int if_index, int dis_tap)
+{
+	DO_BPLIB_SET_ARG_FN(set_dis_tap, SET_DIS_TAP, if_index, dis_tap);
+}
+
+int get_dis_tap(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_dis_tap, GET_DIS_TAP, if_index);
+}
+
+int set_tap_pwup(int if_index, int tap_mode)
+{
+	DO_BPLIB_SET_ARG_FN(set_tap_pwup, SET_TAP_PWUP, if_index, tap_mode);
+}
+
+int get_tap_pwup(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_tap_pwup, GET_TAP_PWUP, if_index);
+}
+
+int set_bp_disc(int if_index, int disc_mode)
+{
+	DO_BPLIB_SET_ARG_FN(set_bp_disc, SET_DISC, if_index, disc_mode);
+}
+
+int get_bp_disc(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_bp_disc, GET_DISC, if_index);
+}
+
+int get_bp_disc_change(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_bp_disc_change, GET_DISC_CHANGE, if_index);
+}
+
+int set_bp_dis_disc(int if_index, int dis_disc)
+{
+	DO_BPLIB_SET_ARG_FN(set_bp_dis_disc, SET_DIS_DISC, if_index, dis_disc);
+}
+
+int get_bp_dis_disc(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_bp_dis_disc, GET_DIS_DISC, if_index);
+}
+
+int set_bp_disc_pwup(int if_index, int disc_mode)
+{
+	DO_BPLIB_SET_ARG_FN(set_bp_disc_pwup, SET_DISC_PWUP, if_index,
+			    disc_mode);
+}
+
+int get_bp_disc_pwup(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_bp_disc_pwup, GET_DISC_PWUP, if_index);
+}
+
+int set_wd_exp_mode(int if_index, int mode)
+{
+	DO_BPLIB_SET_ARG_FN(set_wd_exp_mode, SET_WD_EXP_MODE, if_index, mode);
+}
+
+int get_wd_exp_mode(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_wd_exp_mode, GET_WD_EXP_MODE, if_index);
+}
+
+int set_wd_autoreset(int if_index, int time)
+{
+	DO_BPLIB_SET_ARG_FN(set_wd_autoreset, SET_WD_AUTORESET, if_index, time);
+}
+
+int get_wd_autoreset(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_wd_autoreset, GET_WD_AUTORESET, if_index);
+}
+
+int set_tpl(int if_index, int tpl_mode)
+{
+	DO_BPLIB_SET_ARG_FN(set_tpl, SET_TPL, if_index, tpl_mode);
+}
+
+int get_tpl(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_tpl, GET_TPL, if_index);
+}
+
+int set_bp_hw_reset(int if_index, int mode)
+{
+	DO_BPLIB_SET_ARG_FN(set_tpl, SET_BP_HW_RESET, if_index, mode);
+}
+
+int get_bp_hw_reset(int if_index)
+{
+	DO_BPLIB_GET_ARG_FN(get_tpl, GET_BP_HW_RESET, if_index);
+}
+
+int get_bypass_info(int if_index, struct bp_info *bp_info)
+{
+	int ret = 0;
+	if (is_dev_sd(if_index)) {
+		SET_BPLIB_INT_FN2(get_bypass_info, int, if_index,
+				  struct bp_info *, bp_info, ret);
+	} else {
+		static int (*ioctl) (struct net_device *, struct ifreq *, int);
+		struct net_device *dev;
+
+		struct net_device *n;
+		for_each_netdev_safe(&init_net, dev, n) {
+			if (dev->ifindex == if_index) {
+				struct if_bypass_info *bypass_cb;
+				struct ifreq ifr;
+
+				memset(&ifr, 0, sizeof(ifr));
+				bypass_cb = (struct if_bypass_info *)𝔦
+				bypass_cb->cmd = GET_BYPASS_INFO;
+
+				if ((dev->netdev_ops) &&
+				    (ioctl = dev->netdev_ops->ndo_do_ioctl)) {
+					ret = ioctl(dev, &ifr, SIOCGIFBYPASS);
+				}
+
+				else
+					ret = -1;
+				if (ret == 0)
+					memcpy(bp_info, &bypass_cb->bp_info,
+					       sizeof(struct bp_info));
+				ret = (ret < 0 ? -1 : 0);
+				break;
+			}
+		}
+	}
+	return ret;
+}
+
+int init_lib_module()
+{
+
+	printk(VERSION);
+	return 0;
+}
+
+void cleanup_lib_module()
+{
+}
+
+EXPORT_SYMBOL_NOVERS(is_bypass);
+EXPORT_SYMBOL_NOVERS(get_bypass_slave);
+EXPORT_SYMBOL_NOVERS(get_bypass_caps);
+EXPORT_SYMBOL_NOVERS(get_wd_set_caps);
+EXPORT_SYMBOL_NOVERS(set_bypass);
+EXPORT_SYMBOL_NOVERS(get_bypass);
+EXPORT_SYMBOL_NOVERS(get_bypass_change);
+EXPORT_SYMBOL_NOVERS(set_dis_bypass);
+EXPORT_SYMBOL_NOVERS(get_dis_bypass);
+EXPORT_SYMBOL_NOVERS(set_bypass_pwoff);
+EXPORT_SYMBOL_NOVERS(get_bypass_pwoff);
+EXPORT_SYMBOL_NOVERS(set_bypass_pwup);
+EXPORT_SYMBOL_NOVERS(get_bypass_pwup);
+EXPORT_SYMBOL_NOVERS(set_bypass_wd);
+EXPORT_SYMBOL_NOVERS(get_bypass_wd);
+EXPORT_SYMBOL_NOVERS(get_wd_expire_time);
+EXPORT_SYMBOL_NOVERS(reset_bypass_wd_timer);
+EXPORT_SYMBOL_NOVERS(set_std_nic);
+EXPORT_SYMBOL_NOVERS(get_std_nic);
+EXPORT_SYMBOL_NOVERS(set_tx);
+EXPORT_SYMBOL_NOVERS(get_tx);
+EXPORT_SYMBOL_NOVERS(set_tap);
+EXPORT_SYMBOL_NOVERS(get_tap);
+EXPORT_SYMBOL_NOVERS(get_tap_change);
+EXPORT_SYMBOL_NOVERS(set_dis_tap);
+EXPORT_SYMBOL_NOVERS(get_dis_tap);
+EXPORT_SYMBOL_NOVERS(set_tap_pwup);
+EXPORT_SYMBOL_NOVERS(get_tap_pwup);
+EXPORT_SYMBOL_NOVERS(set_bp_disc);
+EXPORT_SYMBOL_NOVERS(get_bp_disc);
+EXPORT_SYMBOL_NOVERS(get_bp_disc_change);
+EXPORT_SYMBOL_NOVERS(set_bp_dis_disc);
+EXPORT_SYMBOL_NOVERS(get_bp_dis_disc);
+EXPORT_SYMBOL_NOVERS(set_bp_disc_pwup);
+EXPORT_SYMBOL_NOVERS(get_bp_disc_pwup);
+EXPORT_SYMBOL_NOVERS(set_wd_exp_mode);
+EXPORT_SYMBOL_NOVERS(get_wd_exp_mode);
+EXPORT_SYMBOL_NOVERS(set_wd_autoreset);
+EXPORT_SYMBOL_NOVERS(get_wd_autoreset);
+EXPORT_SYMBOL_NOVERS(set_tpl);
+EXPORT_SYMBOL_NOVERS(get_tpl);
+EXPORT_SYMBOL_NOVERS(set_bp_hw_reset);
+EXPORT_SYMBOL_NOVERS(get_bp_hw_reset);
+EXPORT_SYMBOL_NOVERS(get_bypass_info);
+
+module_init(init_lib_module);
+module_exit(cleanup_lib_module);
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/bypasslib/libbp_sd.h working/drivers/staging/silicom/bypasslib/libbp_sd.h
--- linux-2.6/drivers/staging/silicom/bypasslib/libbp_sd.h	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/bypasslib/libbp_sd.h	2012-09-06 18:24:28.370047744 -0700
@@ -0,0 +1,509 @@
+/******************************************************************************/
+/*                                                                            */
+/* bypass library, Copyright (c) 2004 Silicom, Ltd                            */
+/* Corporation.                                                               */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* Ver 1.0.0                                                                  */
+/*                                                                            */
+/* libbypass.h                                                                */
+/*                                                                            */
+/******************************************************************************/
+
+/**
+ * is_bypass - check if device is a Bypass controlling device
+ * @if_index: network device index
+ *
+ * Output:
+ *  1 -  if device is bypass controlling device, 
+ *  0 -  if device is bypass slave device
+ * -1 -  device not support Bypass
+ **/
+int is_bypass_sd(int if_index);
+
+/**
+ * get_bypass_slave - get second port participate in the Bypass pair
+ * @if_index: network device index
+ *
+ * Output:
+ *  network device index of the slave device
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int get_bypass_slave_sd(int if_index);
+
+/**
+ * get_bypass_caps - get second port participate in the Bypass pair
+ * @if_index: network device index
+ *
+ * Output:
+ * flags word on success;flag word is a 32-bit mask word with each bit defines different 
+ * capability as described bellow.
+ * Value of 1 for supporting this feature. 0 for not supporting this feature.
+ * -1 - on failure (if the device is not capable of the operation or not a Bypass device)
+ * Bit	feature	                description
+ * 
+ * 0	BP_CAP	                The interface is Bypass capable in general
+ * 
+ * 1	BP_STATUS_CAP	        The interface can report of the current Bypass mode
+ * 
+ * 2	BP_STATUS_CHANGE_CAP	The interface can report on a change to bypass mode from 
+ *                              the last time the mode was defined
+ * 
+ * 3	SW_CTL_CAP	            The interface is Software controlled capable for bypass/non bypass modes.
+ * 
+ * 4	BP_DIS_CAP	            The interface is capable of disabling the Bypass mode at all times. 
+ *                              This mode will retain its mode even during power loss and also after 
+ *                              power recovery. This will overcome on any bypass operation due to 
+ *                              watchdog timeout or set bypass command.
+ * 
+ * 5	BP_DIS_STATUS_CAP	    The interface can report of the current DIS_BP_CAP
+ * 
+ * 6	STD_NIC_CAP	            The interface is capable to be configured to operate as standard, non Bypass, 
+ *                              NIC interface (have direct connection to interfaces at all power modes)
+ * 
+ * 7	BP_PWOFF_NO_CAP	        The interface can be in Bypass mode at power off state
+ * 
+ * 8	BP_PWOFF_OFF_CAP	    The interface can disconnect the Bypass mode at power off state without 
+ *                              effecting all the other states of operation
+ * 
+ * 9	BP_PWOFF_CTL_CAP	    The behavior of the Bypass mode at Power-off state can be controlled by 
+ *                              software without effecting any other state
+ * 
+ *10    BP_PWUP_ON_CAP	        The interface can be in Bypass mode when power is turned on 
+ *                              (until the system take control of the bypass functionality)
+ * 
+ *11	BP_PWUP_OFF_CAP	        The interface can disconnect from Bypass mode when power is turned on 
+ *                              (until the system take control of the bypass functionality)
+ * 
+ *12	BP_PWUP_CTL_CAP	        The behavior of the Bypass mode at Power-up can be controlled by software
+ * 
+ *13	WD_CTL_CAP	            The interface has watchdog capabilities to turn to Bypass mode when not reset 
+ *                              for defined period of time.
+ * 
+ *14	WD_STATUS_CAP	        The interface can report on the watchdog status (Active/inactive)
+ * 
+ *15	WD_TIMEOUT_CAP	        The interface can report the time left till watchdog triggers to Bypass mode.
+ * 
+ *16-31 RESERVED	
+ *
+ * **/
+int get_bypass_caps_sd(int if_index);
+
+/**
+ * get_wd_set_caps - Obtain watchdog timer setting capabilities
+ * @if_index: network device index
+ *
+ * Output:
+ * 
+ * Set of numbers defining the various parameters of the watchdog capable 
+ * to be set to as described bellow.
+ * -1 - on failure (device not support Bypass or it's a slave device)
+ * 
+ * Bit	feature	        description
+ * 
+ * 0-3	WD_MIN_TIME	    The interface WD minimal time period  in 100mS units
+ * 
+ * 4	WD_STEP_TIME	The steps of the WD timer in 
+ *                      0 - for linear steps (WD_MIN_TIME * X)
+ *                      1 - for multiply by 2 from previous step (WD_MIN_TIME * 2^X)
+ * 
+ * 5-8	WD_STEP_COUNT	Number of steps the WD timer supports in 2^X 
+ *                      (X bit available for defining the value)
+ * 
+ * 
+ * 
+ **/
+int get_wd_set_caps_sd(int if_index);
+
+/**
+ * set_bypass - set Bypass state
+ * @if_index: network device index of the controlling device
+ * @bypass_mode:  bypass mode (1=on, 0=off) 
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int set_bypass_sd(int if_index, int bypass_mode);
+
+/**
+ * get_bypass - Get Bypass mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int get_bypass_sd(int if_index);
+
+/**
+ * get_bypass_change - Get change of Bypass mode state from last status check
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int get_bypass_change_sd(int if_index);
+
+/**
+ * set_dis_bypass - Set Disable Bypass mode
+ * @if_index: network device index of the controlling device
+ * @dis_bypass: disable bypass(1=dis, 0=en)
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int set_dis_bypass_sd(int if_index, int dis_bypass);
+
+/**
+ * get_dis_bypass - Get Disable Bypass mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (normal Bypass mode/ Disable bypass)
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int get_dis_bypass_sd(int if_index);
+
+/**
+ * set_bypass_pwoff - Set Bypass mode at power-off state
+ * @if_index: network device index of the controlling device
+ * @bypass_mode: bypass mode setting at power off state (1=BP en, 0=BP Dis)
+ * Output:
+ *  0 - on success 
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int set_bypass_pwoff_sd(int if_index, int bypass_mode);
+
+/**
+ * get_bypass_pwoff - Get Bypass mode state at power-off state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (Disable bypass at power off state / normal Bypass mode)
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int get_bypass_pwoff_sd(int if_index);
+
+/**
+ * set_bypass_pwup - Set Bypass mode at power-up state
+ * @if_index: network device index of the controlling device
+ * @bypass_mode: bypass mode setting at power up state (1=BP en, 0=BP Dis)
+ * Output:
+ *  0 - on success 
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int set_bypass_pwup_sd(int if_index, int bypass_mode);
+
+/**
+ * get_bypass_pwup - Get Bypass mode state at power-up state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (Disable bypass at power up state / normal Bypass mode)
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int get_bypass_pwup_sd(int if_index);
+
+/**
+ * set_bypass_wd - Set watchdog state
+ * @if_index: network device index of the controlling device
+ * @ms_timeout: requested timeout (in ms units), 0 for disabling the watchdog timer
+ * @ms_timeout_set(output): requested timeout (in ms units), 
+ *                          that the adapter supports and will be used by the watchdog
+ * Output:
+ * 0  - on success 
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set);
+
+/**
+ * get_bypass_wd - Get watchdog state
+ * @if_index: network device index of the controlling device
+ * @ms_timeout (output): WDT timeout (in ms units), 
+ *                       -1 for unknown wdt status
+ *                        0 if WDT is disabled
+ * Output:
+ * 0  - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int get_bypass_wd_sd(int if_index, int *ms_timeout_set);
+
+/**
+ * get_wd_expire_time - Get watchdog expire
+ * @if_index: network device index of the controlling device
+ * @ms_time_left (output): time left till watchdog time expire, 
+ *                       -1 if WDT has expired
+ *                       0  if WDT is disabled
+ * Output:
+ * 0  - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device or unknown wdt status) 
+ **/
+int get_wd_expire_time_sd(int if_index, int *ms_time_left);
+
+/**
+ * reset_bypass_wd_timer - Reset watchdog timer
+ * @if_index: network device index of the controlling device
+ * 
+ * Output:
+ * 1  - on success
+ * 0 - watchdog is not configured
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device or unknown wdt status) 
+ **/
+int reset_bypass_wd_timer_sd(int if_index);
+
+/**
+ * set_std_nic - Standard NIC mode of operation
+ * @if_index: network device index of the controlling device
+ * @nic_mode: 0/1 (Default Bypass mode / Standard NIC mode)
+ * 
+ * Output:
+ * 0  - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int set_std_nic_sd(int if_index, int nic_mode);
+
+/**
+ * get_std_nic - Get Standard NIC mode setting
+ * @if_index: network device index of the controlling device
+ * 
+ * Output:
+ * 0/1 (Default Bypass mode / Standard NIC mode) on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int get_std_nic_sd(int if_index);
+
+/**
+ * set_tx - set transmitter enable/disable 
+ * @if_index: network device index of the controlling device
+ * @tx_state: 0/1 (Transmit Disable / Transmit Enable)
+ * 
+ * Output:
+ * 0  - on success
+ * -1 - on failure (device is not capable of the operation ) 
+ **/
+int set_tx_sd(int if_index, int tx_state);
+
+/**
+ * get_std_nic - get transmitter state (disable / enable)
+ * @if_index: network device index of the controlling device
+ * 
+ * Output:
+ * 0/1 (ransmit Disable / Transmit Enable) on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass) 
+ **/
+int get_tx_sd(int if_index);
+
+/**
+ * set_tap - set TAP state
+ * @if_index: network device index of the controlling device
+ * @tap_mode: 1 tap mode , 0 normal nic mode 
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device not support TAP or it's a slave device) 
+ **/
+int set_tap_sd(int if_index, int tap_mode);
+
+/**
+ * get_tap - Get TAP mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support TAP or it's a slave device) 
+ **/
+int get_tap_sd(int if_index);
+
+/**
+ * get_tap_change - Get change of TAP mode state from last status check
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support TAP or it's a slave device) 
+ **/
+int get_tap_change_sd(int if_index);
+
+/**
+ * set_dis_tap - Set Disable TAP mode
+ * @if_index: network device index of the controlling device
+ * @dis_tap: disable tap(1=dis, 0=en)
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support TAP 
+ *                  or it's a slave device) 
+ **/
+int set_dis_tap_sd(int if_index, int dis_tap);
+
+/**
+ * get_dis_tap - Get Disable TAP mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (normal TAP mode/ Disable TAP)
+ * -1 - on failure (device is not capable of the operation ordevice not support TAP 
+ *                  or it's a slave device) 
+ **/
+int get_dis_tap_sd(int if_index);
+
+/**
+ * set_tap_pwup - Set TAP mode at power-up state
+ * @if_index: network device index of the controlling device
+ * @bypass_mode: tap mode setting at power up state (1=TAP en, 0=TAP Dis)
+ * Output:
+ *  0 - on success 
+ * -1 - on failure (device is not capable of the operation ordevice not support TAP 
+ *                  or it's a slave device) 
+ **/
+int set_tap_pwup_sd(int if_index, int tap_mode);
+
+/**
+ * get_tap_pwup - Get TAP mode state at power-up state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (Disable TAP at power up state / normal TAP mode)
+ * -1 - on failure (device is not capable of the operation ordevice not support TAP 
+ *                  or it's a slave device) 
+ **/
+int get_tap_pwup_sd(int if_index);
+
+/**
+ * set_bp_disc - set Disconnect state
+ * @if_index: network device index of the controlling device
+ * @tap_mode: 1 disc mode , 0 non-disc mode 
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device not support Disconnect or it's a slave device) 
+ **/
+int set_bp_disc_sd(int if_index, int disc_mode);
+
+/**
+ * get_bp_disc - Get Disconnect mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support Disconnect or it's a slave device) 
+ **/
+int get_bp_disc_sd(int if_index);
+
+/**
+ * get_bp_disc_change - Get change of Disconnect mode state from last status check
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support Disconnect or it's a slave device) 
+ **/
+int get_bp_disc_change_sd(int if_index);
+
+/**
+ * set_bp_dis_disc - Set Disable Disconnect mode
+ * @if_index: network device index of the controlling device
+ * @dis_tap: disable tap(1=dis, 0=en)
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device is not capable ofthe operation ordevice not support Disconnect 
+ *                  or it's a slave device) 
+ **/
+int set_bp_dis_disc_sd(int if_index, int dis_disc);
+
+/**
+ * get_dis_tap - Get Disable Disconnect mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (normal Disconnect mode/ Disable Disconnect)
+ * -1 - on failure (device is not capable of the operation ordevice not support Disconnect 
+ *                  or it's a slave device) 
+ **/
+int get_bp_dis_disc_sd(int if_index);
+
+/**
+ * set_bp_disc_pwup - Set Disconnect mode at power-up state
+ * @if_index: network device index of the controlling device
+ * @disc_mode: tap mode setting at power up state (1=Disc en, 0=Disc Dis)
+ * Output:
+ *  0 - on success 
+ * -1 - on failure (device is not capable of the operation ordevice not support Disconnect 
+ *                  or it's a slave device) 
+ **/
+int set_bp_disc_pwup_sd(int if_index, int disc_mode);
+
+/**
+ * get_bp_disc_pwup - Get Disconnect mode state at power-up state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (Disable Disconnect at power up state / normal Disconnect mode)
+ * -1 - on failure (device is not capable of the operation ordevice not support TAP 
+ *                  or it's a slave device) 
+ **/
+int get_bp_disc_pwup_sd(int if_index);
+
+/**
+ * set_wd_exp_mode - Set adapter state when WDT expired.
+ * @if_index: network device index of the controlling device
+ * @bypass_mode:  adapter mode (1=tap mode, 0=bypass mode) 
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int set_wd_exp_mode_sd(int if_index, int bypass_mode);
+
+/**
+ * get_wd_exp_mode - Get adapter state when WDT expired.
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (bypass/tap) on success
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int get_wd_exp_mode_sd(int if_index);
+
+/**
+ * set_wd_autoreset - reset WDT periodically.
+ * @if_index: network device index of the controlling device
+ * @bypass_mode:  adapter mode (1=tap mode, 0=bypass mode) 
+ * Output:
+ * 1  - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device or unknown wdt status) 
+ **/
+int set_wd_autoreset_sd(int if_index, int time);
+
+/**
+ * set_wd_autoreset - reset WDT periodically.
+ * @if_index: network device index of the controlling device
+ * @bypass_mode:  adapter mode (1=tap mode, 0=bypass mode) 
+ * Output:
+ * 1  - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device or unknown wdt status) 
+ **/
+int get_wd_autoreset_sd(int if_index);
+
+/**
+ * set_tpl - set TPL state
+ * @if_index: network device index of the controlling device
+ * @tpl_mode: 1 tpl mode , 0 normal nic mode 
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device not support TPL) 
+ **/
+int set_tpl_sd(int if_index, int tpl_mode);
+
+/**
+ * get_tpl - Get TPL mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support TPL or it's a slave device) 
+ **/
+int get_tpl_sd(int if_index);
+
+int get_bypass_info_sd(int if_index, struct bp_info *bp_info);
+int bp_if_scan_sd(void);
+/*int get_dev_num_sd(void);*/
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/bypasslib/Makefile working/drivers/staging/silicom/bypasslib/Makefile
--- linux-2.6/drivers/staging/silicom/bypasslib/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/bypasslib/Makefile	2012-09-06 18:24:28.371047744 -0700
@@ -0,0 +1,6 @@
+#
+# Makefile for the Bypass network device drivers.
+#
+
+obj-$(CONFIG_SBYPASS) += bypass.o
+
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/Kconfig working/drivers/staging/silicom/Kconfig
--- linux-2.6/drivers/staging/silicom/Kconfig	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/Kconfig	2012-09-06 18:24:28.371047744 -0700
@@ -0,0 +1,43 @@
+#
+# Silicom device configuration
+#
+
+config NET_VENDOR_SILICOM
+	bool "Silicom devices"
+	default y
+	depends on (SSB_POSSIBLE && HAS_DMA) || PCI 
+	---help---
+	  If you have a network card (Ethernet) belonging to this class,
+	  say Y.
+
+	  Note that the answer to this question does not directly affect
+	  the kernel: saying N will just case the configurator to skip all
+	  the questions regarding Silicom chipsets. If you say Y, you will be asked
+	  for your specific chipset/driver in the following questions.
+
+if NET_VENDOR_SILICOM
+
+config SBYPASS
+	tristate "Silicom BypassCTL library support"
+	---help---
+	  If you have a network (Ethernet) controller of this type, say Y
+
+	  To compile this driver as a module, choose M here. The module
+	  will be called bypass.
+
+config BPCTL
+	tristate "Silicom BypassCTL net support"
+	depends on PCI
+	select SBYPASS
+	select NET_CORE
+	select MII
+	---help---
+	  If you have a network (Ethernet) controller of this type, say Y
+	  or M and read the Ethernet-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>.
+
+	  To compile this driver as a module, choose M here. The module
+	  will be called bpctl_mod.
+
+
+endif # NET_VENDOR_SILICOM
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/libbp_sd.h working/drivers/staging/silicom/libbp_sd.h
--- linux-2.6/drivers/staging/silicom/libbp_sd.h	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/libbp_sd.h	2012-09-06 18:24:28.372047744 -0700
@@ -0,0 +1,551 @@
+/******************************************************************************/
+/*                                                                            */
+/* bypass library, Copyright (c) 2004 Silicom, Ltd                            */
+/* Corporation.                                                               */
+/*                                                                            */
+/* This program is free software; you can redistribute it and/or modify       */
+/* it under the terms of the GNU General Public License as published by       */
+/* the Free Software Foundation, located in the file LICENSE.                 */
+/*                                                                            */
+/* Ver 1.0.0                                                                  */
+/*                                                                            */
+/* libbypass.h                                                                */
+/*                                                                            */
+/******************************************************************************/
+
+#define BP_CAP                   0x01	//BIT_0
+#define BP_STATUS_CAP            0x02	//BIT_1
+#define BP_STATUS_CHANGE_CAP     0x04	//BIT_2
+#define SW_CTL_CAP               0x08	//BIT_3
+#define BP_DIS_CAP               0x10	//BIT_4
+#define BP_DIS_STATUS_CAP        0x20	//BIT_5
+#define STD_NIC_CAP              0x40	//BIT_6
+#define BP_PWOFF_ON_CAP          0x80	//BIT_7
+#define BP_PWOFF_OFF_CAP         0x0100	//BIT_8
+#define BP_PWOFF_CTL_CAP         0x0200	//BIT_9
+#define BP_PWUP_ON_CAP           0x0400	//BIT_10
+#define BP_PWUP_OFF_CAP          0x0800	//BIT_11
+#define BP_PWUP_CTL_CAP          0x1000	//BIT_12
+#define WD_CTL_CAP               0x2000	//BIT_13
+#define WD_STATUS_CAP            0x4000	//BIT_14
+#define WD_TIMEOUT_CAP           0x8000	//BIT_15
+#define TX_CTL_CAP               0x10000	//BIT_16
+#define TX_STATUS_CAP            0x20000	//BIT_17
+#define TAP_CAP                  0x40000	//BIT_18
+#define TAP_STATUS_CAP           0x80000	//BIT_19
+#define TAP_STATUS_CHANGE_CAP    0x100000	//BIT_20
+#define TAP_DIS_CAP              0x200000	//BIT_21
+#define TAP_DIS_STATUS_CAP       0x400000	//BIT_22
+#define TAP_PWUP_ON_CAP          0x800000	//BIT_23
+#define TAP_PWUP_OFF_CAP         0x1000000	//BIT 24
+#define TAP_PWUP_CTL_CAP         0x2000000	//BIT 25
+#define NIC_CAP_NEG              0x4000000	//BIT 26
+
+#define WD_MIN_TIME_GET(desc)   (desc & 0xf)
+#define WD_STEP_COUNT_GET(desc) (desc>>5) & 0xf
+#define WDT_STEP_TIME           0x10
+
+struct bp_info {
+	char prod_name[14];
+	unsigned char fw_ver;
+};
+
+/**
+ * is_bypass - check if device is a Bypass controlling device
+ * @if_index: network device index
+ *
+ * Output:
+ *  1 -  if device is bypass controlling device, 
+ *  0 -  if device is bypass slave device
+ * -1 -  device not support Bypass
+ **/
+int is_bypass_sd(int if_index);
+
+/**
+ * get_bypass_slave - get second port participate in the Bypass pair
+ * @if_index: network device index
+ *
+ * Output:
+ *  network device index of the slave device
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int get_bypass_slave_sd(int if_index);
+
+/**
+ * get_bypass_caps - get second port participate in the Bypass pair
+ * @if_index: network device index
+ *
+ * Output:
+ * flags word on success;flag word is a 32-bit mask word with each bit defines different 
+ * capability as described bellow.
+ * Value of 1 for supporting this feature. 0 for not supporting this feature.
+ * -1 - on failure (if the device is not capable of the operation or not a Bypass device)
+ * Bit	feature	                description
+ * 
+ * 0	BP_CAP	                The interface is Bypass capable in general
+ * 
+ * 1	BP_STATUS_CAP	        The interface can report of the current Bypass mode
+ * 
+ * 2	BP_STATUS_CHANGE_CAP	The interface can report on a change to bypass mode from 
+ *                              the last time the mode was defined
+ * 
+ * 3	SW_CTL_CAP	            The interface is Software controlled capable for bypass/non bypass modes.
+ * 
+ * 4	BP_DIS_CAP	            The interface is capable of disabling the Bypass mode at all times. 
+ *                              This mode will retain its mode even during power loss and also after 
+ *                              power recovery. This will overcome on any bypass operation due to 
+ *                              watchdog timeout or set bypass command.
+ * 
+ * 5	BP_DIS_STATUS_CAP	    The interface can report of the current DIS_BP_CAP
+ * 
+ * 6	STD_NIC_CAP	            The interface is capable to be configured to operate as standard, non Bypass, 
+ *                              NIC interface (have direct connection to interfaces at all power modes)
+ * 
+ * 7	BP_PWOFF_NO_CAP	        The interface can be in Bypass mode at power off state
+ * 
+ * 8	BP_PWOFF_OFF_CAP	    The interface can disconnect the Bypass mode at power off state without 
+ *                              effecting all the other states of operation
+ * 
+ * 9	BP_PWOFF_CTL_CAP	    The behavior of the Bypass mode at Power-off state can be controlled by 
+ *                              software without effecting any other state
+ * 
+ *10    BP_PWUP_ON_CAP	        The interface can be in Bypass mode when power is turned on 
+ *                              (until the system take control of the bypass functionality)
+ * 
+ *11	BP_PWUP_OFF_CAP	        The interface can disconnect from Bypass mode when power is turned on 
+ *                              (until the system take control of the bypass functionality)
+ * 
+ *12	BP_PWUP_CTL_CAP	        The behavior of the Bypass mode at Power-up can be controlled by software
+ * 
+ *13	WD_CTL_CAP	            The interface has watchdog capabilities to turn to Bypass mode when not reset 
+ *                              for defined period of time.
+ * 
+ *14	WD_STATUS_CAP	        The interface can report on the watchdog status (Active/inactive)
+ * 
+ *15	WD_TIMEOUT_CAP	        The interface can report the time left till watchdog triggers to Bypass mode.
+ * 
+ *16-31 RESERVED	
+ *
+ * **/
+int get_bypass_caps_sd(int if_index);
+
+/**
+ * get_wd_set_caps - Obtain watchdog timer setting capabilities
+ * @if_index: network device index
+ *
+ * Output:
+ * 
+ * Set of numbers defining the various parameters of the watchdog capable 
+ * to be set to as described bellow.
+ * -1 - on failure (device not support Bypass or it's a slave device)
+ * 
+ * Bit	feature	        description
+ * 
+ * 0-3	WD_MIN_TIME	    The interface WD minimal time period  in 100mS units
+ * 
+ * 4	WD_STEP_TIME	The steps of the WD timer in 
+ *                      0 - for linear steps (WD_MIN_TIME * X)
+ *                      1 - for multiply by 2 from previous step (WD_MIN_TIME * 2^X)
+ * 
+ * 5-8	WD_STEP_COUNT	Number of steps the WD timer supports in 2^X 
+ *                      (X bit available for defining the value)
+ * 
+ * 
+ * 
+ **/
+int get_wd_set_caps_sd(int if_index);
+
+/**
+ * set_bypass - set Bypass state
+ * @if_index: network device index of the controlling device
+ * @bypass_mode:  bypass mode (1=on, 0=off) 
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int set_bypass_sd(int if_index, int bypass_mode);
+
+/**
+ * get_bypass - Get Bypass mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int get_bypass_sd(int if_index);
+
+/**
+ * get_bypass_change - Get change of Bypass mode state from last status check
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int get_bypass_change_sd(int if_index);
+
+/**
+ * set_dis_bypass - Set Disable Bypass mode
+ * @if_index: network device index of the controlling device
+ * @dis_bypass: disable bypass(1=dis, 0=en)
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int set_dis_bypass_sd(int if_index, int dis_bypass);
+
+/**
+ * get_dis_bypass - Get Disable Bypass mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (normal Bypass mode/ Disable bypass)
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int get_dis_bypass_sd(int if_index);
+
+/**
+ * set_bypass_pwoff - Set Bypass mode at power-off state
+ * @if_index: network device index of the controlling device
+ * @bypass_mode: bypass mode setting at power off state (1=BP en, 0=BP Dis)
+ * Output:
+ *  0 - on success 
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int set_bypass_pwoff_sd(int if_index, int bypass_mode);
+
+/**
+ * get_bypass_pwoff - Get Bypass mode state at power-off state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (Disable bypass at power off state / normal Bypass mode)
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int get_bypass_pwoff_sd(int if_index);
+
+/**
+ * set_bypass_pwup - Set Bypass mode at power-up state
+ * @if_index: network device index of the controlling device
+ * @bypass_mode: bypass mode setting at power up state (1=BP en, 0=BP Dis)
+ * Output:
+ *  0 - on success 
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int set_bypass_pwup_sd(int if_index, int bypass_mode);
+
+/**
+ * get_bypass_pwup - Get Bypass mode state at power-up state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (Disable bypass at power up state / normal Bypass mode)
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int get_bypass_pwup_sd(int if_index);
+
+/**
+ * set_bypass_wd - Set watchdog state
+ * @if_index: network device index of the controlling device
+ * @ms_timeout: requested timeout (in ms units), 0 for disabling the watchdog timer
+ * @ms_timeout_set(output): requested timeout (in ms units), 
+ *                          that the adapter supports and will be used by the watchdog
+ * Output:
+ * 0  - on success 
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set);
+
+/**
+ * get_bypass_wd - Get watchdog state
+ * @if_index: network device index of the controlling device
+ * @ms_timeout (output): WDT timeout (in ms units), 
+ *                       -1 for unknown wdt status
+ *                        0 if WDT is disabled
+ * Output:
+ * 0  - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int get_bypass_wd_sd(int if_index, int *ms_timeout_set);
+
+/**
+ * get_wd_expire_time - Get watchdog expire
+ * @if_index: network device index of the controlling device
+ * @ms_time_left (output): time left till watchdog time expire, 
+ *                       -1 if WDT has expired
+ *                       0  if WDT is disabled
+ * Output:
+ * 0  - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device or unknown wdt status) 
+ **/
+int get_wd_expire_time_sd(int if_index, int *ms_time_left);
+
+/**
+ * reset_bypass_wd_timer - Reset watchdog timer
+ * @if_index: network device index of the controlling device
+ * 
+ * Output:
+ * 1  - on success
+ * 0 - watchdog is not configured
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device or unknown wdt status) 
+ **/
+int reset_bypass_wd_timer_sd(int if_index);
+
+/**
+ * set_std_nic - Standard NIC mode of operation
+ * @if_index: network device index of the controlling device
+ * @nic_mode: 0/1 (Default Bypass mode / Standard NIC mode)
+ * 
+ * Output:
+ * 0  - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int set_std_nic_sd(int if_index, int nic_mode);
+
+/**
+ * get_std_nic - Get Standard NIC mode setting
+ * @if_index: network device index of the controlling device
+ * 
+ * Output:
+ * 0/1 (Default Bypass mode / Standard NIC mode) on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device) 
+ **/
+int get_std_nic_sd(int if_index);
+
+/**
+ * set_tx - set transmitter enable/disable 
+ * @if_index: network device index of the controlling device
+ * @tx_state: 0/1 (Transmit Disable / Transmit Enable)
+ * 
+ * Output:
+ * 0  - on success
+ * -1 - on failure (device is not capable of the operation ) 
+ **/
+int set_tx_sd(int if_index, int tx_state);
+
+/**
+ * get_tx - get transmitter state (disable / enable)
+ * @if_index: network device index of the controlling device
+ * 
+ * Output:
+ * 0/1 (ransmit Disable / Transmit Enable) on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass) 
+ **/
+int get_tx_sd(int if_index);
+
+/**
+ * set_tpl - set TPL enable/disable 
+ * @if_index: network device index of the controlling device
+ * @tx_state: 0/1 (TPL Disable / TPL Enable)
+ * 
+ * Output:
+ * 0  - on success
+ * -1 - on failure (device is not capable of the operation ) 
+ **/
+int set_tpl_sd(int if_index, int tpl_state);
+
+/**
+ * get_tpl - get TPL state (disable / enable)
+ * @if_index: network device index of the controlling device
+ * 
+ * Output:
+ * 0/1 (TPL Disable / TPL Enable) on success
+ * -1 - on failure (device is not capable of the operation) 
+ **/
+int get_tpl_sd(int if_index);
+
+int get_bp_hw_reset_sd(int if_index);
+
+int set_bp_hw_reset_sd(int if_index, int status);
+
+/**
+ * set_tap - set TAP state
+ * @if_index: network device index of the controlling device
+ * @tap_mode: 1 tap mode , 0 normal nic mode 
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device not support TAP or it's a slave device) 
+ **/
+int set_tap_sd(int if_index, int tap_mode);
+
+/**
+ * get_tap - Get TAP mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support TAP or it's a slave device) 
+ **/
+int get_tap_sd(int if_index);
+
+/**
+ * get_tap_change - Get change of TAP mode state from last status check
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support TAP or it's a slave device) 
+ **/
+int get_tap_change_sd(int if_index);
+
+/**
+ * set_dis_tap - Set Disable TAP mode
+ * @if_index: network device index of the controlling device
+ * @dis_tap: disable tap(1=dis, 0=en)
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support TAP 
+ *                  or it's a slave device) 
+ **/
+int set_dis_tap_sd(int if_index, int dis_tap);
+
+/**
+ * get_dis_tap - Get Disable TAP mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (normal TAP mode/ Disable TAP)
+ * -1 - on failure (device is not capable of the operation ordevice not support TAP 
+ *                  or it's a slave device) 
+ **/
+int get_dis_tap_sd(int if_index);
+
+/**
+ * set_tap_pwup - Set TAP mode at power-up state
+ * @if_index: network device index of the controlling device
+ * @bypass_mode: tap mode setting at power up state (1=TAP en, 0=TAP Dis)
+ * Output:
+ *  0 - on success 
+ * -1 - on failure (device is not capable of the operation ordevice not support TAP 
+ *                  or it's a slave device) 
+ **/
+int set_tap_pwup_sd(int if_index, int tap_mode);
+
+/**
+ * get_tap_pwup - Get TAP mode state at power-up state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (Disable TAP at power up state / normal TAP mode)
+ * -1 - on failure (device is not capable of the operation ordevice not support TAP 
+ *                  or it's a slave device) 
+ **/
+int get_tap_pwup_sd(int if_index);
+
+/**
+ * set_wd_exp_mode - Set adapter state when WDT expired.
+ * @if_index: network device index of the controlling device
+ * @bypass_mode:  adapter mode (1=tap mode, 0=bypass mode) 
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int set_wd_exp_mode_sd(int if_index, int bypass_mode);
+
+/**
+ * get_wd_exp_mode - Get adapter state when WDT expired.
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (bypass/tap) on success
+ * -1 - on failure (device not support Bypass or it's a slave device) 
+ **/
+int get_wd_exp_mode_sd(int if_index);
+
+/**
+ * set_wd_autoreset - reset WDT periodically.
+ * @if_index: network device index of the controlling device
+ * @bypass_mode:  adapter mode (1=tap mode, 0=bypass mode) 
+ * Output:
+ * 1  - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device or unknown wdt status) 
+ **/
+int set_wd_autoreset_sd(int if_index, int time);
+
+/**
+ * set_wd_autoreset - reset WDT periodically.
+ * @if_index: network device index of the controlling device
+ * @bypass_mode:  adapter mode (1=tap mode, 0=bypass mode) 
+ * Output:
+ * 1  - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support Bypass 
+ *                  or it's a slave device or unknown wdt status) 
+ **/
+int get_wd_autoreset_sd(int if_index);
+/**
+ * set_disc - set DISC state
+ * @if_index: network device index of the controlling device
+ * @tap_mode: 1 DISC mode , 0 normal nic mode 
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device not support disconnect or it's a slave device) 
+ **/
+int set_bp_disc_sd(int if_index, int disc_mode);
+
+/**
+ * get_disc - Get disc mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support disconnect or it's a slave device) 
+ **/
+int get_bp_disc_sd(int if_index);
+
+/**
+ * get_disc_change - Get change of DISC mode state from last status check
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - (off/on) on success
+ * -1 - on failure (device not support disconnect or it's a slave device) 
+ **/
+int get_bp_disc_change_sd(int if_index);
+
+/**
+ * set_dis_disc - Set Disable DISC mode
+ * @if_index: network device index of the controlling device
+ * @dis_disc: disable disconnect(1=dis, 0=en)
+ * Output:
+ *  0 - on success
+ * -1 - on failure (device is not capable of the operation ordevice not support DISC 
+ *                  or it's a slave device) 
+ **/
+int set_bp_dis_disc_sd(int if_index, int dis_disc);
+
+/**
+ * get_dis_disc - Get Disable DISC mode state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (normal DISC mode/ Disable DISC)
+ * -1 - on failure (device is not capable of the operation ordevice not support TAP 
+ *                  or it's a slave device) 
+ **/
+int get_bp_dis_disc_sd(int if_index);
+
+/**
+ * set_disc_pwup - Set DISC mode at power-up state
+ * @if_index: network device index of the controlling device
+ * @disc_mode: DISC mode setting at power up state (1= en, 0= Dis)
+ * Output:
+ *  0 - on success 
+ * -1 - on failure (device is not capable of the operation ordevice not support DISC 
+ *                  or it's a slave device) 
+ **/
+int set_bp_disc_pwup_sd(int if_index, int disc_mode);
+
+/**
+ * get_disc_pwup - Get DISC mode state at power-up state
+ * @if_index: network device index of the controlling device
+ * Output:
+ *  0/1 - on success (Disable DISC at power up state / normal DISC mode)
+ * -1 - on failure (device is not capable of the operation ordevice not support DISC 
+ *                  or it's a slave device) 
+ **/
+int get_bp_disc_pwup_sd(int if_index);
+
+int get_bypass_info_sd(int if_index, struct bp_info *bp_info);
+int bp_if_scan_sd(void);
+/*int get_dev_num_sd(void);*/
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/Makefile working/drivers/staging/silicom/Makefile
--- linux-2.6/drivers/staging/silicom/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/Makefile	2012-09-06 18:24:28.373047744 -0700
@@ -0,0 +1,9 @@
+#
+# Makefile for the Bypass network device drivers.
+#
+
+obj-$(CONFIG_BPCTL) += bpctl_mod.o
+obj-$(CONFIG_SBYPASS) += bypasslib/
+
+
+bpctl_mod-objs := bp_mod.o  bp_proc.o
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/README working/drivers/staging/silicom/README
--- linux-2.6/drivers/staging/silicom/README	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/README	2012-09-06 18:31:29.862059013 -0700
@@ -0,0 +1,14 @@
+
+Theory of Operation:
+
+The Silicom Bypass Network Interface Cards (NICs) are network cards with paired ports (2 or 4). 
+The pairs either act as a "wire" allowing the network packets to pass or insert the device in 
+between the two ports.  When paired with the on-board hardware watchdog or other failsafe, 
+they provide high availability for the network in the face of software outages or maintenance.
+
+The software requirements are for a kernel level driver that interfaces with the bypass and watchdog,
+as well as for control software. User control can be either the provided standalone executable 
+(/bin/bpctl) or the API exposed by the Silicom library.
+
+
+
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/staging/silicom/TODO working/drivers/staging/silicom/TODO
--- linux-2.6/drivers/staging/silicom/TODO	1969-12-31 16:00:00.000000000 -0800
+++ working/drivers/staging/silicom/TODO	2012-09-06 18:32:33.209060729 -0700
@@ -0,0 +1,7 @@
+TODO:
+	- checkpatch.pl cleanups
+	- locking audit
+	- single module with all functionality
+	- userland 
+
+



More information about the devel mailing list