Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 2 May 2013 00:51:54 +0000 (17:51 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 2 May 2013 00:51:54 +0000 (17:51 -0700)
Pull VFS updates from Al Viro,

Misc cleanups all over the place, mainly wrt /proc interfaces (switch
create_proc_entry to proc_create(), get rid of the deprecated
create_proc_read_entry() in favor of using proc_create_data() and
seq_file etc).

7kloc removed.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (204 commits)
  don't bother with deferred freeing of fdtables
  proc: Move non-public stuff from linux/proc_fs.h to fs/proc/internal.h
  proc: Make the PROC_I() and PDE() macros internal to procfs
  proc: Supply a function to remove a proc entry by PDE
  take cgroup_open() and cpuset_open() to fs/proc/base.c
  ppc: Clean up scanlog
  ppc: Clean up rtas_flash driver somewhat
  hostap: proc: Use remove_proc_subtree()
  drm: proc: Use remove_proc_subtree()
  drm: proc: Use minor->index to label things, not PDE->name
  drm: Constify drm_proc_list[]
  zoran: Don't print proc_dir_entry data in debug
  reiserfs: Don't access the proc_dir_entry in r_open(), r_start() r_show()
  proc: Supply an accessor for getting the data from a PDE's parent
  airo: Use remove_proc_subtree()
  rtl8192u: Don't need to save device proc dir PDE
  rtl8187se: Use a dir under /proc/net/r8180/
  proc: Add proc_mkdir_data()
  proc: Move some bits from linux/proc_fs.h to linux/{of.h,signal.h,tty.h}
  proc: Move PDE_NET() to fs/proc/proc_net.c
  ...

103 files changed:
1  2 
arch/arm/mach-omap1/pm.c
arch/mips/mm/init.c
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/irq.c
arch/s390/kernel/syscalls.S
arch/score/mm/init.c
arch/x86/ia32/ia32_aout.c
arch/x86/mm/init_64.c
arch/x86/platform/efi/efi.c
drivers/acpi/battery.c
drivers/acpi/button.c
drivers/block/cciss.c
drivers/block/loop.c
drivers/firmware/efi/efi-pstore.c
drivers/firmware/efi/efivars.c
drivers/media/dvb-core/dvb_frontend.c
drivers/media/dvb-core/dvb_net.c
drivers/media/pci/cx25821/cx25821-audio-upstream.c
drivers/media/rc/ir-lirc-codec.c
drivers/net/wireless/ath/wil6210/debugfs.c
drivers/net/wireless/ray_cs.c
drivers/of/base.c
drivers/platform/x86/thinkpad_acpi.c
drivers/pnp/pnpbios/proc.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/qla2xxx/qla_os.c
drivers/staging/csr/drv.c
drivers/staging/dgrp/dgrp_common.h
drivers/staging/dgrp/dgrp_dpa_ops.c
drivers/staging/dgrp/dgrp_net_ops.c
drivers/staging/rts5139/rts51x_scsi.c
drivers/staging/rts5139/rts51x_scsi.h
drivers/staging/silicom/bpctl_mod.c
drivers/staging/vt6655/device_main.c
drivers/staging/vt6656/main_usb.c
drivers/tty/serial/serial_core.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/goku_udc.c
drivers/usb/gadget/lpc32xx_udc.c
drivers/usb/host/sl811-hcd.c
drivers/usb/storage/scsiglue.c
fs/Makefile
fs/aio.c
fs/binfmt_aout.c
fs/binfmt_elf_fdpic.c
fs/btrfs/file.c
fs/compat.c
fs/coredump.c
fs/efivarfs/file.c
fs/efivarfs/inode.c
fs/efivarfs/super.c
fs/exec.c
fs/ext4/mballoc.c
fs/ext4/super.c
fs/inode.c
fs/jbd2/journal.c
fs/namespace.c
fs/notify/inotify/inotify_user.c
fs/pnode.c
fs/pnode.h
fs/proc/base.c
fs/proc/internal.h
fs/proc/kcore.c
fs/proc/root.c
fs/read_write.c
fs/read_write.h
fs/splice.c
include/linux/cgroup.h
include/linux/cpuset.h
include/linux/fs.h
include/linux/pid_namespace.h
include/linux/signal.h
include/linux/tty.h
include/net/bluetooth/bluetooth.h
ipc/msgutil.c
ipc/util.c
kernel/cgroup.c
kernel/cpuset.c
kernel/exit.c
kernel/pid.c
kernel/pid_namespace.c
kernel/user.c
kernel/user_namespace.c
mm/filemap.c
mm/vmalloc.c
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_sock.c
net/bluetooth/hidp/sock.c
net/bluetooth/l2cap_sock.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/core/neighbour.c
net/core/pktgen.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv6/proc.c
net/netfilter/x_tables.c
net/netfilter/xt_hashlimit.c
net/socket.c
net/sunrpc/cache.c

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 67615d6,0000000..202d2c8
mode 100644,000000..100644
--- /dev/null
@@@ -1,251 -1,0 +1,252 @@@
 +#include <linux/efi.h>
 +#include <linux/module.h>
 +#include <linux/pstore.h>
++#include <linux/slab.h>
 +#include <linux/ucs2_string.h>
 +
 +#define DUMP_NAME_LEN 52
 +
 +static bool efivars_pstore_disable =
 +      IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
 +
 +module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
 +
 +#define PSTORE_EFI_ATTRIBUTES \
 +      (EFI_VARIABLE_NON_VOLATILE | \
 +       EFI_VARIABLE_BOOTSERVICE_ACCESS | \
 +       EFI_VARIABLE_RUNTIME_ACCESS)
 +
 +static int efi_pstore_open(struct pstore_info *psi)
 +{
 +      efivar_entry_iter_begin();
 +      psi->data = NULL;
 +      return 0;
 +}
 +
 +static int efi_pstore_close(struct pstore_info *psi)
 +{
 +      efivar_entry_iter_end();
 +      psi->data = NULL;
 +      return 0;
 +}
 +
 +struct pstore_read_data {
 +      u64 *id;
 +      enum pstore_type_id *type;
 +      int *count;
 +      struct timespec *timespec;
 +      char **buf;
 +};
 +
 +static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
 +{
 +      efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
 +      struct pstore_read_data *cb_data = data;
 +      char name[DUMP_NAME_LEN];
 +      int i;
 +      int cnt;
 +      unsigned int part;
 +      unsigned long time, size;
 +
 +      if (efi_guidcmp(entry->var.VendorGuid, vendor))
 +              return 0;
 +
 +      for (i = 0; i < DUMP_NAME_LEN; i++)
 +              name[i] = entry->var.VariableName[i];
 +
 +      if (sscanf(name, "dump-type%u-%u-%d-%lu",
 +                 cb_data->type, &part, &cnt, &time) == 4) {
 +              *cb_data->id = part;
 +              *cb_data->count = cnt;
 +              cb_data->timespec->tv_sec = time;
 +              cb_data->timespec->tv_nsec = 0;
 +      } else if (sscanf(name, "dump-type%u-%u-%lu",
 +                        cb_data->type, &part, &time) == 3) {
 +              /*
 +               * Check if an old format,
 +               * which doesn't support holding
 +               * multiple logs, remains.
 +               */
 +              *cb_data->id = part;
 +              *cb_data->count = 0;
 +              cb_data->timespec->tv_sec = time;
 +              cb_data->timespec->tv_nsec = 0;
 +      } else
 +              return 0;
 +
 +      entry->var.DataSize = 1024;
 +      __efivar_entry_get(entry, &entry->var.Attributes,
 +                         &entry->var.DataSize, entry->var.Data);
 +      size = entry->var.DataSize;
 +
 +      *cb_data->buf = kmalloc(size, GFP_KERNEL);
 +      if (*cb_data->buf == NULL)
 +              return -ENOMEM;
 +      memcpy(*cb_data->buf, entry->var.Data, size);
 +      return size;
 +}
 +
 +static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
 +                             int *count, struct timespec *timespec,
 +                             char **buf, struct pstore_info *psi)
 +{
 +      struct pstore_read_data data;
 +
 +      data.id = id;
 +      data.type = type;
 +      data.count = count;
 +      data.timespec = timespec;
 +      data.buf = buf;
 +
 +      return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data,
 +                                 (struct efivar_entry **)&psi->data);
 +}
 +
 +static int efi_pstore_write(enum pstore_type_id type,
 +              enum kmsg_dump_reason reason, u64 *id,
 +              unsigned int part, int count, size_t size,
 +              struct pstore_info *psi)
 +{
 +      char name[DUMP_NAME_LEN];
 +      efi_char16_t efi_name[DUMP_NAME_LEN];
 +      efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
 +      int i, ret = 0;
 +
 +      sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count,
 +              get_seconds());
 +
 +      for (i = 0; i < DUMP_NAME_LEN; i++)
 +              efi_name[i] = name[i];
 +
 +      efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES,
 +                            !pstore_cannot_block_path(reason),
 +                            size, psi->buf);
 +
 +      if (reason == KMSG_DUMP_OOPS)
 +              efivar_run_worker();
 +
 +      *id = part;
 +      return ret;
 +};
 +
 +struct pstore_erase_data {
 +      u64 id;
 +      enum pstore_type_id type;
 +      int count;
 +      struct timespec time;
 +      efi_char16_t *name;
 +};
 +
 +/*
 + * Clean up an entry with the same name
 + */
 +static int efi_pstore_erase_func(struct efivar_entry *entry, void *data)
 +{
 +      struct pstore_erase_data *ed = data;
 +      efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
 +      efi_char16_t efi_name_old[DUMP_NAME_LEN];
 +      efi_char16_t *efi_name = ed->name;
 +      unsigned long ucs2_len = ucs2_strlen(ed->name);
 +      char name_old[DUMP_NAME_LEN];
 +      int i;
 +
 +      if (efi_guidcmp(entry->var.VendorGuid, vendor))
 +              return 0;
 +
 +      if (ucs2_strncmp(entry->var.VariableName,
 +                        efi_name, (size_t)ucs2_len)) {
 +              /*
 +               * Check if an old format, which doesn't support
 +               * holding multiple logs, remains.
 +               */
 +              sprintf(name_old, "dump-type%u-%u-%lu", ed->type,
 +                      (unsigned int)ed->id, ed->time.tv_sec);
 +
 +              for (i = 0; i < DUMP_NAME_LEN; i++)
 +                      efi_name_old[i] = name_old[i];
 +
 +              if (ucs2_strncmp(entry->var.VariableName, efi_name_old,
 +                                ucs2_strlen(efi_name_old)))
 +                      return 0;
 +      }
 +
 +      /* found */
 +      __efivar_entry_delete(entry);
 +      list_del(&entry->list);
 +
 +      return 1;
 +}
 +
 +static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
 +                          struct timespec time, struct pstore_info *psi)
 +{
 +      struct pstore_erase_data edata;
 +      struct efivar_entry *entry = NULL;
 +      char name[DUMP_NAME_LEN];
 +      efi_char16_t efi_name[DUMP_NAME_LEN];
 +      int found, i;
 +
 +      sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count,
 +              time.tv_sec);
 +
 +      for (i = 0; i < DUMP_NAME_LEN; i++)
 +              efi_name[i] = name[i];
 +
 +      edata.id = id;
 +      edata.type = type;
 +      edata.count = count;
 +      edata.time = time;
 +      edata.name = efi_name;
 +
 +      efivar_entry_iter_begin();
 +      found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);
 +      efivar_entry_iter_end();
 +
 +      if (found)
 +              efivar_unregister(entry);
 +
 +      return 0;
 +}
 +
 +static struct pstore_info efi_pstore_info = {
 +      .owner          = THIS_MODULE,
 +      .name           = "efi",
 +      .open           = efi_pstore_open,
 +      .close          = efi_pstore_close,
 +      .read           = efi_pstore_read,
 +      .write          = efi_pstore_write,
 +      .erase          = efi_pstore_erase,
 +};
 +
 +static __init int efivars_pstore_init(void)
 +{
 +      if (!efi_enabled(EFI_RUNTIME_SERVICES))
 +              return 0;
 +
 +      if (!efivars_kobject())
 +              return 0;
 +
 +      if (efivars_pstore_disable)
 +              return 0;
 +
 +      efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
 +      if (!efi_pstore_info.buf)
 +              return -ENOMEM;
 +
 +      efi_pstore_info.bufsize = 1024;
 +      spin_lock_init(&efi_pstore_info.buf_lock);
 +
 +      pstore_register(&efi_pstore_info);
 +
 +      return 0;
 +}
 +
 +static __exit void efivars_pstore_exit(void)
 +{
 +}
 +
 +module_init(efivars_pstore_init);
 +module_exit(efivars_pstore_exit);
 +
 +MODULE_DESCRIPTION("EFI variable backend for pstore");
 +MODULE_LICENSE("GPL");
index 5e94897,0000000..b623c59
mode 100644,000000..100644
--- /dev/null
@@@ -1,616 -1,0 +1,617 @@@
 +/*
 + * Originally from efivars.c,
 + *
 + * Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com>
 + * Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com>
 + *
 + * This code takes all variables accessible from EFI runtime and
 + *  exports them via sysfs
 + *
 + *  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; either version 2 of the License, or
 + *  (at your option) any later version.
 + *
 + *  This program is distributed in the hope that it will be useful,
 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + *  GNU General Public License for more details.
 + *
 + *  You should have received a copy of the GNU General Public License
 + *  along with this program; if not, write to the Free Software
 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 + *
 + * Changelog:
 + *
 + *  17 May 2004 - Matt Domsch <Matt_Domsch@dell.com>
 + *   remove check for efi_enabled in exit
 + *   add MODULE_VERSION
 + *
 + *  26 Apr 2004 - Matt Domsch <Matt_Domsch@dell.com>
 + *   minor bug fixes
 + *
 + *  21 Apr 2004 - Matt Tolentino <matthew.e.tolentino@intel.com)
 + *   converted driver to export variable information via sysfs
 + *   and moved to drivers/firmware directory
 + *   bumped revision number to v0.07 to reflect conversion & move
 + *
 + *  10 Dec 2002 - Matt Domsch <Matt_Domsch@dell.com>
 + *   fix locking per Peter Chubb's findings
 + *
 + *  25 Mar 2002 - Matt Domsch <Matt_Domsch@dell.com>
 + *   move uuid_unparse() to include/asm-ia64/efi.h:efi_guid_unparse()
 + *
 + *  12 Feb 2002 - Matt Domsch <Matt_Domsch@dell.com>
 + *   use list_for_each_safe when deleting vars.
 + *   remove ifdef CONFIG_SMP around include <linux/smp.h>
 + *   v0.04 release to linux-ia64@linuxia64.org
 + *
 + *  20 April 2001 - Matt Domsch <Matt_Domsch@dell.com>
 + *   Moved vars from /proc/efi to /proc/efi/vars, and made
 + *   efi.c own the /proc/efi directory.
 + *   v0.03 release to linux-ia64@linuxia64.org
 + *
 + *  26 March 2001 - Matt Domsch <Matt_Domsch@dell.com>
 + *   At the request of Stephane, moved ownership of /proc/efi
 + *   to efi.c, and now efivars lives under /proc/efi/vars.
 + *
 + *  12 March 2001 - Matt Domsch <Matt_Domsch@dell.com>
 + *   Feedback received from Stephane Eranian incorporated.
 + *   efivar_write() checks copy_from_user() return value.
 + *   efivar_read/write() returns proper errno.
 + *   v0.02 release to linux-ia64@linuxia64.org
 + *
 + *  26 February 2001 - Matt Domsch <Matt_Domsch@dell.com>
 + *   v0.01 release to linux-ia64@linuxia64.org
 + */
 +
 +#include <linux/efi.h>
 +#include <linux/module.h>
++#include <linux/slab.h>
 +#include <linux/ucs2_string.h>
 +
 +#define EFIVARS_VERSION "0.08"
 +#define EFIVARS_DATE "2004-May-17"
 +
 +MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
 +MODULE_DESCRIPTION("sysfs interface to EFI Variables");
 +MODULE_LICENSE("GPL");
 +MODULE_VERSION(EFIVARS_VERSION);
 +
 +LIST_HEAD(efivar_sysfs_list);
 +EXPORT_SYMBOL_GPL(efivar_sysfs_list);
 +
 +static struct kset *efivars_kset;
 +
 +static struct bin_attribute *efivars_new_var;
 +static struct bin_attribute *efivars_del_var;
 +
 +struct efivar_attribute {
 +      struct attribute attr;
 +      ssize_t (*show) (struct efivar_entry *entry, char *buf);
 +      ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count);
 +};
 +
 +#define EFIVAR_ATTR(_name, _mode, _show, _store) \
 +struct efivar_attribute efivar_attr_##_name = { \
 +      .attr = {.name = __stringify(_name), .mode = _mode}, \
 +      .show = _show, \
 +      .store = _store, \
 +};
 +
 +#define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr)
 +#define to_efivar_entry(obj)  container_of(obj, struct efivar_entry, kobj)
 +
 +/*
 + * Prototype for sysfs creation function
 + */
 +static int
 +efivar_create_sysfs_entry(struct efivar_entry *new_var);
 +
 +static ssize_t
 +efivar_guid_read(struct efivar_entry *entry, char *buf)
 +{
 +      struct efi_variable *var = &entry->var;
 +      char *str = buf;
 +
 +      if (!entry || !buf)
 +              return 0;
 +
 +      efi_guid_unparse(&var->VendorGuid, str);
 +      str += strlen(str);
 +      str += sprintf(str, "\n");
 +
 +      return str - buf;
 +}
 +
 +static ssize_t
 +efivar_attr_read(struct efivar_entry *entry, char *buf)
 +{
 +      struct efi_variable *var = &entry->var;
 +      char *str = buf;
 +
 +      if (!entry || !buf)
 +              return -EINVAL;
 +
 +      var->DataSize = 1024;
 +      if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
 +              return -EIO;
 +
 +      if (var->Attributes & EFI_VARIABLE_NON_VOLATILE)
 +              str += sprintf(str, "EFI_VARIABLE_NON_VOLATILE\n");
 +      if (var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)
 +              str += sprintf(str, "EFI_VARIABLE_BOOTSERVICE_ACCESS\n");
 +      if (var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)
 +              str += sprintf(str, "EFI_VARIABLE_RUNTIME_ACCESS\n");
 +      if (var->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD)
 +              str += sprintf(str, "EFI_VARIABLE_HARDWARE_ERROR_RECORD\n");
 +      if (var->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
 +              str += sprintf(str,
 +                      "EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\n");
 +      if (var->Attributes &
 +                      EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
 +              str += sprintf(str,
 +                      "EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\n");
 +      if (var->Attributes & EFI_VARIABLE_APPEND_WRITE)
 +              str += sprintf(str, "EFI_VARIABLE_APPEND_WRITE\n");
 +      return str - buf;
 +}
 +
 +static ssize_t
 +efivar_size_read(struct efivar_entry *entry, char *buf)
 +{
 +      struct efi_variable *var = &entry->var;
 +      char *str = buf;
 +
 +      if (!entry || !buf)
 +              return -EINVAL;
 +
 +      var->DataSize = 1024;
 +      if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
 +              return -EIO;
 +
 +      str += sprintf(str, "0x%lx\n", var->DataSize);
 +      return str - buf;
 +}
 +
 +static ssize_t
 +efivar_data_read(struct efivar_entry *entry, char *buf)
 +{
 +      struct efi_variable *var = &entry->var;
 +
 +      if (!entry || !buf)
 +              return -EINVAL;
 +
 +      var->DataSize = 1024;
 +      if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data))
 +              return -EIO;
 +
 +      memcpy(buf, var->Data, var->DataSize);
 +      return var->DataSize;
 +}
 +/*
 + * We allow each variable to be edited via rewriting the
 + * entire efi variable structure.
 + */
 +static ssize_t
 +efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
 +{
 +      struct efi_variable *new_var, *var = &entry->var;
 +      int err;
 +
 +      if (count != sizeof(struct efi_variable))
 +              return -EINVAL;
 +
 +      new_var = (struct efi_variable *)buf;
 +      /*
 +       * If only updating the variable data, then the name
 +       * and guid should remain the same
 +       */
 +      if (memcmp(new_var->VariableName, var->VariableName, sizeof(var->VariableName)) ||
 +              efi_guidcmp(new_var->VendorGuid, var->VendorGuid)) {
 +              printk(KERN_ERR "efivars: Cannot edit the wrong variable!\n");
 +              return -EINVAL;
 +      }
 +
 +      if ((new_var->DataSize <= 0) || (new_var->Attributes == 0)){
 +              printk(KERN_ERR "efivars: DataSize & Attributes must be valid!\n");
 +              return -EINVAL;
 +      }
 +
 +      if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
 +          efivar_validate(new_var, new_var->Data, new_var->DataSize) == false) {
 +              printk(KERN_ERR "efivars: Malformed variable content\n");
 +              return -EINVAL;
 +      }
 +
 +      memcpy(&entry->var, new_var, count);
 +
 +      err = efivar_entry_set(entry, new_var->Attributes,
 +                             new_var->DataSize, new_var->Data, false);
 +      if (err) {
 +              printk(KERN_WARNING "efivars: set_variable() failed: status=%d\n", err);
 +              return -EIO;
 +      }
 +
 +      return count;
 +}
 +
 +static ssize_t
 +efivar_show_raw(struct efivar_entry *entry, char *buf)
 +{
 +      struct efi_variable *var = &entry->var;
 +
 +      if (!entry || !buf)
 +              return 0;
 +
 +      var->DataSize = 1024;
 +      if (efivar_entry_get(entry, &entry->var.Attributes,
 +                           &entry->var.DataSize, entry->var.Data))
 +              return -EIO;
 +
 +      memcpy(buf, var, sizeof(*var));
 +
 +      return sizeof(*var);
 +}
 +
 +/*
 + * Generic read/write functions that call the specific functions of
 + * the attributes...
 + */
 +static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
 +                              char *buf)
 +{
 +      struct efivar_entry *var = to_efivar_entry(kobj);
 +      struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
 +      ssize_t ret = -EIO;
 +
 +      if (!capable(CAP_SYS_ADMIN))
 +              return -EACCES;
 +
 +      if (efivar_attr->show) {
 +              ret = efivar_attr->show(var, buf);
 +      }
 +      return ret;
 +}
 +
 +static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr,
 +                              const char *buf, size_t count)
 +{
 +      struct efivar_entry *var = to_efivar_entry(kobj);
 +      struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
 +      ssize_t ret = -EIO;
 +
 +      if (!capable(CAP_SYS_ADMIN))
 +              return -EACCES;
 +
 +      if (efivar_attr->store)
 +              ret = efivar_attr->store(var, buf, count);
 +
 +      return ret;
 +}
 +
 +static const struct sysfs_ops efivar_attr_ops = {
 +      .show = efivar_attr_show,
 +      .store = efivar_attr_store,
 +};
 +
 +static void efivar_release(struct kobject *kobj)
 +{
 +      struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj);
 +      kfree(var);
 +}
 +
 +static EFIVAR_ATTR(guid, 0400, efivar_guid_read, NULL);
 +static EFIVAR_ATTR(attributes, 0400, efivar_attr_read, NULL);
 +static EFIVAR_ATTR(size, 0400, efivar_size_read, NULL);
 +static EFIVAR_ATTR(data, 0400, efivar_data_read, NULL);
 +static EFIVAR_ATTR(raw_var, 0600, efivar_show_raw, efivar_store_raw);
 +
 +static struct attribute *def_attrs[] = {
 +      &efivar_attr_guid.attr,
 +      &efivar_attr_size.attr,
 +      &efivar_attr_attributes.attr,
 +      &efivar_attr_data.attr,
 +      &efivar_attr_raw_var.attr,
 +      NULL,
 +};
 +
 +static struct kobj_type efivar_ktype = {
 +      .release = efivar_release,
 +      .sysfs_ops = &efivar_attr_ops,
 +      .default_attrs = def_attrs,
 +};
 +
 +static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
 +                           struct bin_attribute *bin_attr,
 +                           char *buf, loff_t pos, size_t count)
 +{
 +      struct efi_variable *new_var = (struct efi_variable *)buf;
 +      struct efivar_entry *new_entry;
 +      int err;
 +
 +      if (!capable(CAP_SYS_ADMIN))
 +              return -EACCES;
 +
 +      if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
 +          efivar_validate(new_var, new_var->Data, new_var->DataSize) == false) {
 +              printk(KERN_ERR "efivars: Malformed variable content\n");
 +              return -EINVAL;
 +      }
 +
 +      new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL);
 +      if (!new_entry)
 +              return -ENOMEM;
 +
 +      memcpy(&new_entry->var, new_var, sizeof(*new_var));
 +
 +      err = efivar_entry_set(new_entry, new_var->Attributes, new_var->DataSize,
 +                             new_var->Data, &efivar_sysfs_list);
 +      if (err) {
 +              if (err == -EEXIST)
 +                      err = -EINVAL;
 +              goto out;
 +      }
 +
 +      if (efivar_create_sysfs_entry(new_entry)) {
 +              printk(KERN_WARNING "efivars: failed to create sysfs entry.\n");
 +              kfree(new_entry);
 +      }
 +      return count;
 +
 +out:
 +      kfree(new_entry);
 +      return err;
 +}
 +
 +static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
 +                           struct bin_attribute *bin_attr,
 +                           char *buf, loff_t pos, size_t count)
 +{
 +      struct efi_variable *del_var = (struct efi_variable *)buf;
 +      struct efivar_entry *entry;
 +      int err = 0;
 +
 +      if (!capable(CAP_SYS_ADMIN))
 +              return -EACCES;
 +
 +      efivar_entry_iter_begin();
 +      entry = efivar_entry_find(del_var->VariableName, del_var->VendorGuid,
 +                                &efivar_sysfs_list, true);
 +      if (!entry)
 +              err = -EINVAL;
 +      else if (__efivar_entry_delete(entry))
 +              err = -EIO;
 +
 +      efivar_entry_iter_end();
 +
 +      if (err)
 +              return err;
 +
 +      efivar_unregister(entry);
 +
 +      /* It's dead Jim.... */
 +      return count;
 +}
 +
 +/**
 + * efivar_create_sysfs_entry - create a new entry in sysfs
 + * @new_var: efivar entry to create
 + *
 + * Returns 1 on failure, 0 on success
 + */
 +static int
 +efivar_create_sysfs_entry(struct efivar_entry *new_var)
 +{
 +      int i, short_name_size;
 +      char *short_name;
 +      unsigned long variable_name_size;
 +      efi_char16_t *variable_name;
 +
 +      variable_name = new_var->var.VariableName;
 +      variable_name_size = ucs2_strlen(variable_name) * sizeof(efi_char16_t);
 +
 +      /*
 +       * Length of the variable bytes in ASCII, plus the '-' separator,
 +       * plus the GUID, plus trailing NUL
 +       */
 +      short_name_size = variable_name_size / sizeof(efi_char16_t)
 +                              + 1 + EFI_VARIABLE_GUID_LEN + 1;
 +
 +      short_name = kzalloc(short_name_size, GFP_KERNEL);
 +
 +      if (!short_name)
 +              return 1;
 +
 +      /* Convert Unicode to normal chars (assume top bits are 0),
 +         ala UTF-8 */
 +      for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {
 +              short_name[i] = variable_name[i] & 0xFF;
 +      }
 +      /* This is ugly, but necessary to separate one vendor's
 +         private variables from another's.         */
 +
 +      *(short_name + strlen(short_name)) = '-';
 +      efi_guid_unparse(&new_var->var.VendorGuid,
 +                       short_name + strlen(short_name));
 +
 +      new_var->kobj.kset = efivars_kset;
 +
 +      i = kobject_init_and_add(&new_var->kobj, &efivar_ktype,
 +                                 NULL, "%s", short_name);
 +      kfree(short_name);
 +      if (i)
 +              return 1;
 +
 +      kobject_uevent(&new_var->kobj, KOBJ_ADD);
 +      efivar_entry_add(new_var, &efivar_sysfs_list);
 +
 +      return 0;
 +}
 +
 +static int
 +create_efivars_bin_attributes(void)
 +{
 +      struct bin_attribute *attr;
 +      int error;
 +
 +      /* new_var */
 +      attr = kzalloc(sizeof(*attr), GFP_KERNEL);
 +      if (!attr)
 +              return -ENOMEM;
 +
 +      attr->attr.name = "new_var";
 +      attr->attr.mode = 0200;
 +      attr->write = efivar_create;
 +      efivars_new_var = attr;
 +
 +      /* del_var */
 +      attr = kzalloc(sizeof(*attr), GFP_KERNEL);
 +      if (!attr) {
 +              error = -ENOMEM;
 +              goto out_free;
 +      }
 +      attr->attr.name = "del_var";
 +      attr->attr.mode = 0200;
 +      attr->write = efivar_delete;
 +      efivars_del_var = attr;
 +
 +      sysfs_bin_attr_init(efivars_new_var);
 +      sysfs_bin_attr_init(efivars_del_var);
 +
 +      /* Register */
 +      error = sysfs_create_bin_file(&efivars_kset->kobj, efivars_new_var);
 +      if (error) {
 +              printk(KERN_ERR "efivars: unable to create new_var sysfs file"
 +                      " due to error %d\n", error);
 +              goto out_free;
 +      }
 +
 +      error = sysfs_create_bin_file(&efivars_kset->kobj, efivars_del_var);
 +      if (error) {
 +              printk(KERN_ERR "efivars: unable to create del_var sysfs file"
 +                      " due to error %d\n", error);
 +              sysfs_remove_bin_file(&efivars_kset->kobj, efivars_new_var);
 +              goto out_free;
 +      }
 +
 +      return 0;
 +out_free:
 +      kfree(efivars_del_var);
 +      efivars_del_var = NULL;
 +      kfree(efivars_new_var);
 +      efivars_new_var = NULL;
 +      return error;
 +}
 +
 +static int efivar_update_sysfs_entry(efi_char16_t *name, efi_guid_t vendor,
 +                                   unsigned long name_size, void *data)
 +{
 +      struct efivar_entry *entry = data;
 +
 +      if (efivar_entry_find(name, vendor, &efivar_sysfs_list, false))
 +              return 0;
 +
 +      memcpy(entry->var.VariableName, name, name_size);
 +      memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
 +
 +      return 1;
 +}
 +
 +static void efivar_update_sysfs_entries(struct work_struct *work)
 +{
 +      struct efivar_entry *entry;
 +      int err;
 +
 +      entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 +      if (!entry)
 +              return;
 +
 +      /* Add new sysfs entries */
 +      while (1) {
 +              memset(entry, 0, sizeof(*entry));
 +
 +              err = efivar_init(efivar_update_sysfs_entry, entry,
 +                                true, false, &efivar_sysfs_list);
 +              if (!err)
 +                      break;
 +
 +              efivar_create_sysfs_entry(entry);
 +      }
 +
 +      kfree(entry);
 +}
 +
 +static int efivars_sysfs_callback(efi_char16_t *name, efi_guid_t vendor,
 +                                unsigned long name_size, void *data)
 +{
 +      struct efivar_entry *entry;
 +
 +      entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 +      if (!entry)
 +              return -ENOMEM;
 +
 +      memcpy(entry->var.VariableName, name, name_size);
 +      memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
 +
 +      efivar_create_sysfs_entry(entry);
 +
 +      return 0;
 +}
 +
 +static int efivar_sysfs_destroy(struct efivar_entry *entry, void *data)
 +{
 +      efivar_entry_remove(entry);
 +      efivar_unregister(entry);
 +      return 0;
 +}
 +
 +void efivars_sysfs_exit(void)
 +{
 +      /* Remove all entries and destroy */
 +      __efivar_entry_iter(efivar_sysfs_destroy, &efivar_sysfs_list, NULL, NULL);
 +
 +      if (efivars_new_var)
 +              sysfs_remove_bin_file(&efivars_kset->kobj, efivars_new_var);
 +      if (efivars_del_var)
 +              sysfs_remove_bin_file(&efivars_kset->kobj, efivars_del_var);
 +      kfree(efivars_new_var);
 +      kfree(efivars_del_var);
 +      kset_unregister(efivars_kset);
 +}
 +
 +int efivars_sysfs_init(void)
 +{
 +      struct kobject *parent_kobj = efivars_kobject();
 +      int error = 0;
 +
 +      /* No efivars has been registered yet */
 +      if (!parent_kobj)
 +              return 0;
 +
 +      printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
 +             EFIVARS_DATE);
 +
 +      efivars_kset = kset_create_and_add("vars", NULL, parent_kobj);
 +      if (!efivars_kset) {
 +              printk(KERN_ERR "efivars: Subsystem registration failed.\n");
 +              return -ENOMEM;
 +      }
 +
 +      efivar_init(efivars_sysfs_callback, NULL, false,
 +                  true, &efivar_sysfs_list);
 +
 +      error = create_efivars_bin_attributes();
 +      if (error) {
 +              efivars_sysfs_exit();
 +              return error;
 +      }
 +
 +      INIT_WORK(&efivar_work, efivar_update_sysfs_entries);
 +
 +      return 0;
 +}
 +EXPORT_SYMBOL_GPL(efivars_sysfs_init);
 +
 +module_init(efivars_sysfs_init);
 +module_exit(efivars_sysfs_exit);
Simple merge
Simple merge
@@@ -257,19 -257,16 +257,16 @@@ void cx25821_free_mem_upstream_audio(st
  }
  
  static int cx25821_get_audio_data(struct cx25821_dev *dev,
 -                         struct sram_channel *sram_ch)
 +                         const struct sram_channel *sram_ch)
  {
-       struct file *myfile;
+       struct file *file;
        int frame_index_temp = dev->_audioframe_index;
        int i = 0;
-       int line_size = AUDIO_LINE_SIZE;
        int frame_size = AUDIO_DATA_BUF_SZ;
        int frame_offset = frame_size * frame_index_temp;
-       ssize_t vfs_read_retval = 0;
-       char mybuf[line_size];
+       char mybuf[AUDIO_LINE_SIZE];
        loff_t file_offset = dev->_audioframe_count * frame_size;
-       loff_t pos;
-       mm_segment_t old_fs;
+       char *p = NULL;
  
        if (dev->_audiofile_status == END_OF_FILE)
                return 0;
@@@ -352,83 -319,43 +319,43 @@@ static void cx25821_audioups_handler(st
  }
  
  static int cx25821_openfile_audio(struct cx25821_dev *dev,
 -                         struct sram_channel *sram_ch)
 +                         const struct sram_channel *sram_ch)
  {
-       struct file *myfile;
-       int i = 0, j = 0;
-       int line_size = AUDIO_LINE_SIZE;
-       ssize_t vfs_read_retval = 0;
-       char mybuf[line_size];
-       loff_t pos;
-       loff_t offset = (unsigned long)0;
-       mm_segment_t old_fs;
-       myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
-       if (IS_ERR(myfile)) {
-               const int open_errno = -PTR_ERR(myfile);
-               pr_err("%s(): ERROR opening file(%s) with errno = %d!\n",
-                       __func__, dev->_audiofilename, open_errno);
-               return PTR_ERR(myfile);
-       } else {
-               if (!(myfile->f_op)) {
-                       pr_err("%s(): File has no file operations registered!\n",
-                               __func__);
-                       filp_close(myfile, NULL);
-                       return -EIO;
-               }
+       char *p = (void *)dev->_audiodata_buf_virt_addr;
+       struct file *file;
+       loff_t offset;
+       int i, j;
+       file = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
+       if (IS_ERR(file)) {
+               pr_err("%s(): ERROR opening file(%s) with errno = %ld!\n",
+                       __func__, dev->_audiofilename, PTR_ERR(file));
+               return PTR_ERR(file);
+       }
  
-               if (!myfile->f_op->read) {
-                       pr_err("%s(): File has no READ operations registered!\n",
-                               __func__);
-                       filp_close(myfile, NULL);
-                       return -EIO;
-               }
+       for (j = 0, offset = 0; j < NUM_AUDIO_FRAMES; j++) {
+               for (i = 0; i < dev->_audio_lines_count; i++) {
+                       char buf[AUDIO_LINE_SIZE];
+                       int n = kernel_read(file, offset, buf,
+                                               AUDIO_LINE_SIZE);
  
-               pos = myfile->f_pos;
-               old_fs = get_fs();
-               set_fs(KERNEL_DS);
-               for (j = 0; j < NUM_AUDIO_FRAMES; j++) {
-                       for (i = 0; i < dev->_audio_lines_count; i++) {
-                               pos = offset;
-                               vfs_read_retval = vfs_read(myfile, mybuf,
-                                               line_size, &pos);
-                               if (vfs_read_retval > 0 &&
-                                   vfs_read_retval == line_size &&
-                                   dev->_audiodata_buf_virt_addr != NULL) {
-                                       memcpy((void *)(dev->
-                                                       _audiodata_buf_virt_addr
-                                                       + offset / 4), mybuf,
-                                              vfs_read_retval);
-                               }
-                               offset += vfs_read_retval;
-                               if (vfs_read_retval < line_size) {
-                                       pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
-                                               __func__);
-                                       break;
-                               }
+                       if (n < AUDIO_LINE_SIZE) {
+                               pr_info("Done: exit %s() since no more bytes to read from Audio file\n",
+                                       __func__);
+                               dev->_audiofile_status = END_OF_FILE;
+                               fput(file);
+                               return 0;
                        }
  
-                       if (i > 0)
-                               dev->_audioframe_count++;
+                       if (p)
+                               memcpy(p + offset, buf, n);
  
-                       if (vfs_read_retval < line_size)
-                               break;
+                       offset += n;
                }
-               dev->_audiofile_status = (vfs_read_retval == line_size) ?
-                                               IN_PROGRESS : END_OF_FILE;
-               set_fs(old_fs);
-               myfile->f_pos = 0;
-               filp_close(myfile, NULL);
+               dev->_audioframe_count++;
        }
+       dev->_audiofile_status = IN_PROGRESS;
+       fput(file);
        return 0;
  }
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -147,10 -147,9 +147,8 @@@ struct scsi_cmnd
  
  int slave_alloc(struct scsi_device *sdev);
  int slave_configure(struct scsi_device *sdev);
- int proc_info(struct Scsi_Host *host, char *buffer,
-             char **start, off_t offset, int length, int inout);
  int queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
  int command_abort(struct scsi_cmnd *srb);
 -int device_reset(struct scsi_cmnd *srb);
  int bus_reset(struct scsi_cmnd *srb);
  
  #endif /* __RTS51X_SCSI_H */
index 0000000,3117559..b7e570c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,7909 +1,7907 @@@
 -/*    spin_unlock_irqrestore(&bpvm_lock, flags);        
+ /******************************************************************************/
+ /*                                                                            */
+ /* 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/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 <linux/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 major_num = 0;
+ MODULE_AUTHOR("Anna Lukin, annal@silicom.co.il");
+ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION(BP_MOD_DESCR);
+ MODULE_VERSION(BP_MOD_VER);
+ spinlock_t bpvm_lock;
+ #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 bypass_pfs_sd {
+       char dir_name[32];
+       struct proc_dir_entry *bypass_entry;
+ };
+ 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;
+       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;
+       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 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++ != ':') ;
+                       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;
+               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;
+               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;
+       }
+       switch (event) {
+       case NETDEV_CHANGE:{
+                       if (netif_carrier_ok(dev))
+                               return NOTIFY_DONE;
+                       if (((dev_num = get_dev_idx(dev->ifindex)) == -1) ||
+                           (!(pbpctl_dev = &bpctl_dev_arr[dev_num])))
+                               return NOTIFY_DONE;
+                       if ((is_bypass_fn(pbpctl_dev)) == 1)
+                               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,
+ };
+ 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*/
+                               BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+                                               (ctrl_ext | BP10G_MCLK_DATA_OUT
+                                                | BP10G_MDIO_DATA_OUT));
+                       }
+                       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 {
+                               BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+                                               ((ctrl_ext |
+                                                 BP10G_MDIO_DATA_OUT) &
+                                                ~(BP10G_MCLK_DATA_OUT)));
+                       }
+                       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 {
+                               BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+                                               ((ctrl_ext |
+                                                 BP10G_MCLK_DATA_OUT) &
+                                                ~BP10G_MDIO_DATA_OUT));
+                       }
+                       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 {
+                               BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+                                               (ctrl_ext &
+                                                ~(BP10G_MCLK_DATA_OUT |
+                                                  BP10G_MDIO_DATA_OUT)));
+                       }
+                       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);
+       }
+       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 {
+                       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);); */
+               }
+               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 {
+                       BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+                                       (ctrl_ext | BP10G_MCLK_DATA_OUT |
+                                        BP10G_MDIO_DATA_OUT));
+               }
+               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);
+               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)));
+       }
+       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)));
+       }
+       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 {
+               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)));
+       }
+       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 {
+               BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+                               (ctrl_ext | BP10G_MCLK_DATA_OUT |
+                                BP10G_MDIO_DATA_OUT));
+       }
+       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 {
+               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)));
+       }
+       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 {
+               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)));
+       }
+       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 {
+               BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+                               ((ctrl_ext | BP10G_MCLK_DATA_OUT) &
+                                ~BP10G_MDIO_DATA_OUT));
+       }
+       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 {
+               BP10G_WRITE_REG(pbpctl_dev, EODSDP,
+                               (ctrl_ext &
+                                ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
+       }
+       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 *lookup_port(bpctl_dev_t *dev)
+ {
+       bpctl_dev_t *p;
+       int n;
+       for (n = 0, p = bpctl_dev_arr; n < device_num && p->pdev; n++) {
+               if (p->bus == dev->bus
+                   && p->slot == dev->slot
+                   && p->func == (dev->func ^ 1))
+                       return p;
+       }
+       return NULL;
+ }
+ static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev)
+ {
+       if (pbpctl_dev) {
+               if (pbpctl_dev->func == 0 || pbpctl_dev->func == 2)
+                       return lookup_port(pbpctl_dev);
+       }
+       return NULL;
+ }
+ static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev)
+ {
+       if (pbpctl_dev) {
+               if (pbpctl_dev->func == 1 || pbpctl_dev->func == 3)
+                       return lookup_port(pbpctl_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 = 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
+                               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
+                               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);
+       }
+ }
+ /*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;
+ }
+ 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) {
+                       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 ((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 ((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 ((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 (((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 ((BP10G_READ_REG(pbpctl_dev_b, ESDP) &
+                                BP10G_SDP2_DATA) != 0 ? 1 : 0);
+               }
+               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 ((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 ((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));
+                               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;
+ }
+ 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;
+ }
+ 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;
+       } else {
+               if (BP10G_CX4_SERIES(pbpctl_dev->subdevice))
+                       pbpctl_dev->media_type = bp_cx4;
+               else
+                       pbpctl_dev->media_type = bp_fiber;
+       }
+       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 (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
+       }
+ }
+ 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 ((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();
+               }
+               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)
+&nb