linux/drivers/staging/silicom/bpctl_mod.c
<<
>>
Prefs
   1/******************************************************************************/
   2/*                                                                            */
   3/* Bypass Control utility, Copyright (c) 2005-20011 Silicom                   */
   4/*                                                                            */
   5/* This program is free software; you can redistribute it and/or modify       */
   6/* it under the terms of the GNU General Public License as published by       */
   7/* the Free Software Foundation, located in the file LICENSE.                 */
   8/*  Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.          */
   9/*                                                                            */
  10/*                                                                            */
  11/******************************************************************************/
  12
  13#include <linux/kernel.h>       /* We're doing kernel work */
  14#include <linux/module.h>       /* Specifically, a module */
  15#include <linux/fs.h>
  16#include <linux/pci.h>
  17#include <linux/delay.h>
  18#include <linux/netdevice.h>
  19#include <linux/rtnetlink.h>
  20#include <linux/rcupdate.h>
  21#include <linux/etherdevice.h>
  22
  23#include <linux/uaccess.h>      /* for get_user and put_user */
  24#include <linux/sched.h>
  25#include <linux/ethtool.h>
  26#include <linux/proc_fs.h>
  27
  28#include "bp_ioctl.h"
  29#include "bp_mod.h"
  30#include "bypass.h"
  31#include "libbp_sd.h"
  32
  33#define SUCCESS 0
  34#define BP_MOD_VER  "9.0.4"
  35#define BP_MOD_DESCR "Silicom Bypass-SD Control driver"
  36#define BP_SYNC_FLAG 1
  37
  38static int major_num;
  39
  40MODULE_AUTHOR("Anna Lukin, annal@silicom.co.il");
  41MODULE_LICENSE("GPL");
  42MODULE_DESCRIPTION(BP_MOD_DESCR);
  43MODULE_VERSION(BP_MOD_VER);
  44spinlock_t bpvm_lock;
  45
  46#define unlock_bpctl()                                  \
  47        up(&bpctl_sema);
  48
  49/* Media Types */
  50enum bp_media_type {
  51        BP_COPPER = 0,
  52        BP_FIBER,
  53        BP_CX4,
  54        BP_NONE,
  55};
  56
  57struct bypass_pfs_sd {
  58        char dir_name[32];
  59        struct proc_dir_entry *bypass_entry;
  60};
  61
  62typedef struct _bpctl_dev {
  63        char *name;
  64        char *desc;
  65        struct pci_dev *pdev;   /* PCI device */
  66        struct net_device *ndev;        /* net device */
  67        unsigned long mem_map;
  68        uint8_t bus;
  69        uint8_t slot;
  70        uint8_t func;
  71        u_int32_t device;
  72        u_int32_t vendor;
  73        u_int32_t subvendor;
  74        u_int32_t subdevice;
  75        int ifindex;
  76        uint32_t bp_caps;
  77        uint32_t bp_caps_ex;
  78        uint8_t bp_fw_ver;
  79        int bp_ext_ver;
  80        int wdt_status;
  81        unsigned long bypass_wdt_on_time;
  82        uint32_t bypass_timer_interval;
  83        struct timer_list bp_timer;
  84        uint32_t reset_time;
  85        uint8_t bp_status_un;
  86        atomic_t wdt_busy;
  87        enum bp_media_type media_type;
  88        int bp_tpl_flag;
  89        struct timer_list bp_tpl_timer;
  90        spinlock_t bypass_wr_lock;
  91        int bp_10g;
  92        int bp_10gb;
  93        int bp_fiber5;
  94        int bp_10g9;
  95        int bp_i80;
  96        int bp_540;
  97        int (*hard_start_xmit_save) (struct sk_buff *skb,
  98                                     struct net_device *dev);
  99        const struct net_device_ops *old_ops;
 100        struct net_device_ops new_ops;
 101        int bp_self_test_flag;
 102        char *bp_tx_data;
 103        struct bypass_pfs_sd bypass_pfs_set;
 104
 105} bpctl_dev_t;
 106
 107static bpctl_dev_t *bpctl_dev_arr;
 108
 109static struct semaphore bpctl_sema;
 110static int device_num;
 111
 112static int get_dev_idx(int ifindex);
 113static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev);
 114static int disc_status(bpctl_dev_t *pbpctl_dev);
 115static int bypass_status(bpctl_dev_t *pbpctl_dev);
 116static int wdt_timer(bpctl_dev_t *pbpctl_dev, int *time_left);
 117static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev);
 118static void if_scan_init(void);
 119
 120int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block);
 121int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block);
 122int bp_proc_create(void);
 123
 124int is_bypass_fn(bpctl_dev_t *pbpctl_dev);
 125int get_dev_idx_bsf(int bus, int slot, int func);
 126
 127static unsigned long str_to_hex(char *p);
 128static int bp_device_event(struct notifier_block *unused,
 129                           unsigned long event, void *ptr)
 130{
 131        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 132        static bpctl_dev_t *pbpctl_dev, *pbpctl_dev_m;
 133        int dev_num = 0, ret = 0, ret_d = 0, time_left = 0;
 134        /* printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); */
 135        /* return NOTIFY_DONE; */
 136        if (!dev)
 137                return NOTIFY_DONE;
 138        if (event == NETDEV_REGISTER) {
 139                {
 140                        struct ethtool_drvinfo drvinfo;
 141                        char cbuf[32];
 142                        char *buf = NULL;
 143                        char res[10];
 144                        int i = 0, ifindex, idx_dev = 0;
 145                        int bus = 0, slot = 0, func = 0;
 146                        ifindex = dev->ifindex;
 147
 148                        memset(res, 0, 10);
 149                        memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
 150
 151                        if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) {
 152                                memset(&drvinfo, 0, sizeof(drvinfo));
 153                                dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
 154                        } else
 155                                return NOTIFY_DONE;
 156                        if (!drvinfo.bus_info)
 157                                return NOTIFY_DONE;
 158                        if (!strcmp(drvinfo.bus_info, "N/A"))
 159                                return NOTIFY_DONE;
 160                        memcpy(&cbuf, drvinfo.bus_info, 32);
 161                        buf = &cbuf[0];
 162
 163                        while (*buf++ != ':')
 164                                ;
 165                        for (i = 0; i < 10; i++, buf++) {
 166                                if (*buf == ':')
 167                                        break;
 168                                res[i] = *buf;
 169
 170                        }
 171                        buf++;
 172                        bus = str_to_hex(res);
 173                        memset(res, 0, 10);
 174
 175                        for (i = 0; i < 10; i++, buf++) {
 176                                if (*buf == '.')
 177                                        break;
 178                                res[i] = *buf;
 179
 180                        }
 181                        buf++;
 182                        slot = str_to_hex(res);
 183                        func = str_to_hex(buf);
 184                        idx_dev = get_dev_idx_bsf(bus, slot, func);
 185
 186                        if (idx_dev != -1) {
 187
 188                                bpctl_dev_arr[idx_dev].ifindex = ifindex;
 189                                bpctl_dev_arr[idx_dev].ndev = dev;
 190
 191                                bypass_proc_remove_dev_sd(&bpctl_dev_arr
 192                                                          [idx_dev]);
 193                                bypass_proc_create_dev_sd(&bpctl_dev_arr
 194                                                          [idx_dev]);
 195
 196                        }
 197
 198                }
 199                return NOTIFY_DONE;
 200
 201        }
 202        if (event == NETDEV_UNREGISTER) {
 203                int idx_dev = 0;
 204                for (idx_dev = 0;
 205                     ((bpctl_dev_arr[idx_dev].pdev != NULL)
 206                      && (idx_dev < device_num)); idx_dev++) {
 207                        if (bpctl_dev_arr[idx_dev].ndev == dev) {
 208                                bypass_proc_remove_dev_sd(&bpctl_dev_arr
 209                                                          [idx_dev]);
 210                                bpctl_dev_arr[idx_dev].ndev = NULL;
 211
 212                                return NOTIFY_DONE;
 213
 214                        }
 215
 216                }
 217                return NOTIFY_DONE;
 218        }
 219        if (event == NETDEV_CHANGENAME) {
 220                int idx_dev = 0;
 221                for (idx_dev = 0;
 222                     ((bpctl_dev_arr[idx_dev].pdev != NULL)
 223                      && (idx_dev < device_num)); idx_dev++) {
 224                        if (bpctl_dev_arr[idx_dev].ndev == dev) {
 225                                bypass_proc_remove_dev_sd(&bpctl_dev_arr
 226                                                          [idx_dev]);
 227                                bypass_proc_create_dev_sd(&bpctl_dev_arr
 228                                                          [idx_dev]);
 229
 230                                return NOTIFY_DONE;
 231
 232                        }
 233
 234                }
 235                return NOTIFY_DONE;
 236
 237        }
 238
 239        switch (event) {
 240
 241        case NETDEV_CHANGE:{
 242                        if (netif_carrier_ok(dev))
 243                                return NOTIFY_DONE;
 244
 245                        if (((dev_num = get_dev_idx(dev->ifindex)) == -1) ||
 246                            (!(pbpctl_dev = &bpctl_dev_arr[dev_num])))
 247                                return NOTIFY_DONE;
 248
 249                        if ((is_bypass_fn(pbpctl_dev)) == 1)
 250                                pbpctl_dev_m = pbpctl_dev;
 251                        else
 252                                pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
 253                        if (!pbpctl_dev_m)
 254                                return NOTIFY_DONE;
 255                        ret = bypass_status(pbpctl_dev_m);
 256                        if (ret == 1)
 257                                printk("bpmod: %s is in the Bypass mode now",
 258                                       dev->name);
 259                        ret_d = disc_status(pbpctl_dev_m);
 260                        if (ret_d == 1)
 261                                printk
 262                                    ("bpmod: %s is in the Disconnect mode now",
 263                                     dev->name);
 264                        if (ret || ret_d) {
 265                                wdt_timer(pbpctl_dev_m, &time_left);
 266                                if (time_left == -1)
 267                                        printk("; WDT has expired");
 268                                printk(".\n");
 269
 270                        }
 271                        return NOTIFY_DONE;
 272
 273                }
 274
 275        default:
 276                return NOTIFY_DONE;
 277
 278        }
 279        return NOTIFY_DONE;
 280
 281}
 282
 283static struct notifier_block bp_notifier_block = {
 284        .notifier_call = bp_device_event,
 285};
 286
 287int is_bypass_fn(bpctl_dev_t *pbpctl_dev);
 288int wdt_time_left(bpctl_dev_t *pbpctl_dev);
 289
 290static void write_pulse(bpctl_dev_t *pbpctl_dev,
 291                        unsigned int ctrl_ext,
 292                        unsigned char value, unsigned char len)
 293{
 294        unsigned char ctrl_val = 0;
 295        unsigned int i = len;
 296        unsigned int ctrl = 0;
 297        bpctl_dev_t *pbpctl_dev_c = NULL;
 298
 299        if (pbpctl_dev->bp_i80)
 300                ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
 301        if (pbpctl_dev->bp_540)
 302                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
 303
 304        if (pbpctl_dev->bp_10g9) {
 305                pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
 306                if (!pbpctl_dev_c)
 307                        return;
 308                ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
 309        }
 310
 311        while (i--) {
 312                ctrl_val = (value >> i) & 0x1;
 313                if (ctrl_val) {
 314                        if (pbpctl_dev->bp_10g9) {
 315
 316                                /* To start management : MCLK 1, MDIO 1, output */
 317                                /* DATA 1 CLK 1 */
 318                                /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */
 319                                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
 320                                                ctrl_ext |
 321                                                BP10G_MDIO_DATA_OUT9);
 322                                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
 323                                                (ctrl | BP10G_MCLK_DATA_OUT9 |
 324                                                 BP10G_MCLK_DIR_OUT9));
 325
 326                        } else if (pbpctl_dev->bp_fiber5) {
 327                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext |
 328                                                                      BPCTLI_CTRL_EXT_MCLK_DIR5
 329                                                                      |
 330                                                                      BPCTLI_CTRL_EXT_MDIO_DIR5
 331                                                                      |
 332                                                                      BPCTLI_CTRL_EXT_MDIO_DATA5
 333                                                                      |
 334                                                                      BPCTLI_CTRL_EXT_MCLK_DATA5));
 335
 336                        } else if (pbpctl_dev->bp_i80) {
 337                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext |
 338                                                                      BPCTLI_CTRL_EXT_MDIO_DIR80
 339                                                                      |
 340                                                                      BPCTLI_CTRL_EXT_MDIO_DATA80));
 341
 342                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, (ctrl |
 343                                                                          BPCTLI_CTRL_EXT_MCLK_DIR80
 344                                                                          |
 345                                                                          BPCTLI_CTRL_EXT_MCLK_DATA80));
 346
 347                        } else if (pbpctl_dev->bp_540) {
 348                                BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl |
 349                                                                   BP540_MDIO_DIR
 350                                                                   |
 351                                                                   BP540_MDIO_DATA
 352                                                                   |
 353                                                                   BP540_MCLK_DIR
 354                                                                   |
 355                                                                   BP540_MCLK_DATA));
 356
 357                        } else if (pbpctl_dev->bp_10gb) {
 358                                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
 359                                                 (ctrl_ext | BP10GB_MDIO_SET |
 360                                                  BP10GB_MCLK_SET) &
 361                                                 ~(BP10GB_MCLK_DIR |
 362                                                   BP10GB_MDIO_DIR |
 363                                                   BP10GB_MDIO_CLR |
 364                                                   BP10GB_MCLK_CLR));
 365
 366                        } else if (!pbpctl_dev->bp_10g)
 367                                /* To start management : MCLK 1, MDIO 1, output */
 368                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 369                                                   (ctrl_ext |
 370                                                    BPCTLI_CTRL_EXT_MCLK_DIR |
 371                                                    BPCTLI_CTRL_EXT_MDIO_DIR |
 372                                                    BPCTLI_CTRL_EXT_MDIO_DATA |
 373                                                    BPCTLI_CTRL_EXT_MCLK_DATA));
 374                        else {
 375
 376                                /* To start management : MCLK 1, MDIO 1, output*/
 377                                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
 378                                                (ctrl_ext | BP10G_MCLK_DATA_OUT
 379                                                 | BP10G_MDIO_DATA_OUT));
 380
 381                        }
 382
 383                        usec_delay(PULSE_TIME);
 384                        if (pbpctl_dev->bp_10g9) {
 385
 386                                /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MDIO_DATA_OUT9)&~(BP10G_MCLK_DATA_OUT9))); */
 387                                /* DATA 1 CLK 0 */
 388                                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
 389                                                ctrl_ext |
 390                                                BP10G_MDIO_DATA_OUT9);
 391                                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
 392                                                (ctrl | BP10G_MCLK_DIR_OUT9) &
 393                                                ~BP10G_MCLK_DATA_OUT9);
 394
 395                        } else if (pbpctl_dev->bp_fiber5) {
 396                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
 397                                                   ((ctrl_ext |
 398                                                     BPCTLI_CTRL_EXT_MCLK_DIR5 |
 399                                                     BPCTLI_CTRL_EXT_MDIO_DIR5 |
 400                                                     BPCTLI_CTRL_EXT_MDIO_DATA5)
 401                                                    &
 402                                                    ~
 403                                                    (BPCTLI_CTRL_EXT_MCLK_DATA5)));
 404
 405                        } else if (pbpctl_dev->bp_i80) {
 406                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext |
 407                                                                      BPCTLI_CTRL_EXT_MDIO_DIR80
 408                                                                      |
 409                                                                      BPCTLI_CTRL_EXT_MDIO_DATA80));
 410                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 411                                                   ((ctrl |
 412                                                     BPCTLI_CTRL_EXT_MCLK_DIR80)
 413                                                    &
 414                                                    ~
 415                                                    (BPCTLI_CTRL_EXT_MCLK_DATA80)));
 416
 417                        } else if (pbpctl_dev->bp_540) {
 418                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
 419                                                (ctrl | BP540_MDIO_DIR |
 420                                                 BP540_MDIO_DATA |
 421                                                 BP540_MCLK_DIR) &
 422                                                ~(BP540_MCLK_DATA));
 423
 424                        } else if (pbpctl_dev->bp_10gb) {
 425
 426                                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
 427                                                 (ctrl_ext | BP10GB_MDIO_SET |
 428                                                  BP10GB_MCLK_CLR) &
 429                                                 ~(BP10GB_MCLK_DIR |
 430                                                   BP10GB_MDIO_DIR |
 431                                                   BP10GB_MDIO_CLR |
 432                                                   BP10GB_MCLK_SET));
 433
 434                        } else if (!pbpctl_dev->bp_10g)
 435
 436                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 437                                                   ((ctrl_ext |
 438                                                     BPCTLI_CTRL_EXT_MCLK_DIR |
 439                                                     BPCTLI_CTRL_EXT_MDIO_DIR |
 440                                                     BPCTLI_CTRL_EXT_MDIO_DATA)
 441                                                    &
 442                                                    ~
 443                                                    (BPCTLI_CTRL_EXT_MCLK_DATA)));
 444                        else {
 445
 446                                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
 447                                                ((ctrl_ext |
 448                                                  BP10G_MDIO_DATA_OUT) &
 449                                                 ~(BP10G_MCLK_DATA_OUT)));
 450                        }
 451
 452                        usec_delay(PULSE_TIME);
 453
 454                } else {
 455                        if (pbpctl_dev->bp_10g9) {
 456                                /* DATA 0 CLK 1 */
 457                                /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MCLK_DATA_OUT9)&~BP10G_MDIO_DATA_OUT9)); */
 458                                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
 459                                                (ctrl_ext &
 460                                                 ~BP10G_MDIO_DATA_OUT9));
 461                                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
 462                                                (ctrl | BP10G_MCLK_DATA_OUT9 |
 463                                                 BP10G_MCLK_DIR_OUT9));
 464
 465                        } else if (pbpctl_dev->bp_fiber5) {
 466                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
 467                                                   ((ctrl_ext |
 468                                                     BPCTLI_CTRL_EXT_MCLK_DIR5 |
 469                                                     BPCTLI_CTRL_EXT_MDIO_DIR5 |
 470                                                     BPCTLI_CTRL_EXT_MCLK_DATA5)
 471                                                    &
 472                                                    ~
 473                                                    (BPCTLI_CTRL_EXT_MDIO_DATA5)));
 474
 475                        } else if (pbpctl_dev->bp_i80) {
 476                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
 477                                                   ((ctrl_ext |
 478                                                     BPCTLI_CTRL_EXT_MDIO_DIR80)
 479                                                    &
 480                                                    ~
 481                                                    (BPCTLI_CTRL_EXT_MDIO_DATA80)));
 482                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 483                                                   (ctrl |
 484                                                    BPCTLI_CTRL_EXT_MCLK_DIR80 |
 485                                                    BPCTLI_CTRL_EXT_MCLK_DATA80));
 486
 487                        } else if (pbpctl_dev->bp_540) {
 488                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
 489                                                ((ctrl | BP540_MCLK_DIR |
 490                                                  BP540_MCLK_DATA |
 491                                                  BP540_MDIO_DIR) &
 492                                                 ~(BP540_MDIO_DATA)));
 493
 494                        } else if (pbpctl_dev->bp_10gb) {
 495                                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
 496                                                 (ctrl_ext | BP10GB_MDIO_CLR |
 497                                                  BP10GB_MCLK_SET) &
 498                                                 ~(BP10GB_MCLK_DIR |
 499                                                   BP10GB_MDIO_DIR |
 500                                                   BP10GB_MDIO_SET |
 501                                                   BP10GB_MCLK_CLR));
 502
 503                        } else if (!pbpctl_dev->bp_10g)
 504
 505                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 506                                                   ((ctrl_ext |
 507                                                     BPCTLI_CTRL_EXT_MCLK_DIR |
 508                                                     BPCTLI_CTRL_EXT_MDIO_DIR |
 509                                                     BPCTLI_CTRL_EXT_MCLK_DATA)
 510                                                    &
 511                                                    ~
 512                                                    (BPCTLI_CTRL_EXT_MDIO_DATA)));
 513                        else {
 514
 515                                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
 516                                                ((ctrl_ext |
 517                                                  BP10G_MCLK_DATA_OUT) &
 518                                                 ~BP10G_MDIO_DATA_OUT));
 519
 520                        }
 521                        usec_delay(PULSE_TIME);
 522                        if (pbpctl_dev->bp_10g9) {
 523                                /* DATA 0 CLK 0 */
 524                                /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
 525                                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
 526                                                (ctrl_ext &
 527                                                 ~BP10G_MDIO_DATA_OUT9));
 528                                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
 529                                                ((ctrl | BP10G_MCLK_DIR_OUT9) &
 530                                                 ~(BP10G_MCLK_DATA_OUT9)));
 531
 532                        } else if (pbpctl_dev->bp_fiber5) {
 533                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
 534                                                   ((ctrl_ext |
 535                                                     BPCTLI_CTRL_EXT_MCLK_DIR5 |
 536                                                     BPCTLI_CTRL_EXT_MDIO_DIR5)
 537                                                    &
 538                                                    ~(BPCTLI_CTRL_EXT_MCLK_DATA5
 539                                                      |
 540                                                      BPCTLI_CTRL_EXT_MDIO_DATA5)));
 541
 542                        } else if (pbpctl_dev->bp_i80) {
 543                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
 544                                                   ((ctrl_ext |
 545                                                     BPCTLI_CTRL_EXT_MDIO_DIR80)
 546                                                    &
 547                                                    ~BPCTLI_CTRL_EXT_MDIO_DATA80));
 548                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 549                                                   ((ctrl |
 550                                                     BPCTLI_CTRL_EXT_MCLK_DIR80)
 551                                                    &
 552                                                    ~
 553                                                    (BPCTLI_CTRL_EXT_MCLK_DATA80)));
 554
 555                        } else if (pbpctl_dev->bp_540) {
 556                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
 557                                                ((ctrl | BP540_MCLK_DIR |
 558                                                  BP540_MDIO_DIR) &
 559                                                 ~(BP540_MDIO_DATA |
 560                                                   BP540_MCLK_DATA)));
 561                        } else if (pbpctl_dev->bp_10gb) {
 562
 563                                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
 564                                                 (ctrl_ext | BP10GB_MDIO_CLR |
 565                                                  BP10GB_MCLK_CLR) &
 566                                                 ~(BP10GB_MCLK_DIR |
 567                                                   BP10GB_MDIO_DIR |
 568                                                   BP10GB_MDIO_SET |
 569                                                   BP10GB_MCLK_SET));
 570
 571                        } else if (!pbpctl_dev->bp_10g)
 572                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 573                                                   ((ctrl_ext |
 574                                                     BPCTLI_CTRL_EXT_MCLK_DIR |
 575                                                     BPCTLI_CTRL_EXT_MDIO_DIR) &
 576                                                    ~(BPCTLI_CTRL_EXT_MCLK_DATA
 577                                                      |
 578                                                      BPCTLI_CTRL_EXT_MDIO_DATA)));
 579                        else {
 580
 581                                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
 582                                                (ctrl_ext &
 583                                                 ~(BP10G_MCLK_DATA_OUT |
 584                                                   BP10G_MDIO_DATA_OUT)));
 585                        }
 586
 587                        usec_delay(PULSE_TIME);
 588                }
 589
 590        }
 591}
 592
 593static int read_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext,
 594                      unsigned char len)
 595{
 596        unsigned char ctrl_val = 0;
 597        unsigned int i = len;
 598        unsigned int ctrl = 0;
 599        bpctl_dev_t *pbpctl_dev_c = NULL;
 600
 601        if (pbpctl_dev->bp_i80)
 602                ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
 603        if (pbpctl_dev->bp_540)
 604                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
 605        if (pbpctl_dev->bp_10g9) {
 606                pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
 607                if (!pbpctl_dev_c)
 608                        return -1;
 609                ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
 610        }
 611
 612
 613        while (i--) {
 614                if (pbpctl_dev->bp_10g9) {
 615                        /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MDIO_DATA_OUT9)&~BP10G_MCLK_DATA_OUT9)); */
 616                        /* DATA ? CLK 0 */
 617                        BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
 618                                        ((ctrl | BP10G_MCLK_DIR_OUT9) &
 619                                         ~(BP10G_MCLK_DATA_OUT9)));
 620
 621                } else if (pbpctl_dev->bp_fiber5) {
 622                        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
 623                                                               BPCTLI_CTRL_EXT_MCLK_DIR5)
 624                                                              &
 625                                                              ~
 626                                                              (BPCTLI_CTRL_EXT_MDIO_DIR5
 627                                                               |
 628                                                               BPCTLI_CTRL_EXT_MCLK_DATA5)));
 629
 630                } else if (pbpctl_dev->bp_i80) {
 631                        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
 632                                           (ctrl_ext &
 633                                            ~BPCTLI_CTRL_EXT_MDIO_DIR80));
 634                        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 635                                           ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80)
 636                                            & ~(BPCTLI_CTRL_EXT_MCLK_DATA80)));
 637
 638                } else if (pbpctl_dev->bp_540) {
 639                        BP10G_WRITE_REG(pbpctl_dev, ESDP,
 640                                        ((ctrl | BP540_MCLK_DIR) &
 641                                         ~(BP540_MDIO_DIR | BP540_MCLK_DATA)));
 642
 643                } else if (pbpctl_dev->bp_10gb) {
 644
 645                        BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
 646                                         (ctrl_ext | BP10GB_MDIO_DIR |
 647                                          BP10GB_MCLK_CLR) & ~(BP10GB_MCLK_DIR |
 648                                                               BP10GB_MDIO_CLR |
 649                                                               BP10GB_MDIO_SET |
 650                                                               BP10GB_MCLK_SET));
 651
 652                } else if (!pbpctl_dev->bp_10g)
 653                        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
 654                                                                   BPCTLI_CTRL_EXT_MCLK_DIR)
 655                                                                  &
 656                                                                  ~
 657                                                                  (BPCTLI_CTRL_EXT_MDIO_DIR
 658                                                                   |
 659                                                                   BPCTLI_CTRL_EXT_MCLK_DATA)));
 660                else {
 661
 662                        BP10G_WRITE_REG(pbpctl_dev, EODSDP, ((ctrl_ext | BP10G_MDIO_DATA_OUT) & ~BP10G_MCLK_DATA_OUT)); /* ? */
 663                        /*    printk("0x28=0x%x\n",BP10G_READ_REG(pbpctl_dev,EODSDP);); */
 664
 665                }
 666
 667                usec_delay(PULSE_TIME);
 668                if (pbpctl_dev->bp_10g9) {
 669                        /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */
 670                        /* DATA ? CLK 1 */
 671                        BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
 672                                        (ctrl | BP10G_MCLK_DATA_OUT9 |
 673                                         BP10G_MCLK_DIR_OUT9));
 674
 675                } else if (pbpctl_dev->bp_fiber5) {
 676                        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
 677                                                               BPCTLI_CTRL_EXT_MCLK_DIR5
 678                                                               |
 679                                                               BPCTLI_CTRL_EXT_MCLK_DATA5)
 680                                                              &
 681                                                              ~
 682                                                              (BPCTLI_CTRL_EXT_MDIO_DIR5)));
 683
 684                } else if (pbpctl_dev->bp_i80) {
 685                        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
 686                                           (ctrl_ext &
 687                                            ~(BPCTLI_CTRL_EXT_MDIO_DIR80)));
 688                        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 689                                           (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 |
 690                                            BPCTLI_CTRL_EXT_MCLK_DATA80));
 691
 692                } else if (pbpctl_dev->bp_540) {
 693                        BP10G_WRITE_REG(pbpctl_dev, ESDP,
 694                                        ((ctrl | BP540_MCLK_DIR |
 695                                          BP540_MCLK_DATA) &
 696                                         ~(BP540_MDIO_DIR)));
 697
 698                } else if (pbpctl_dev->bp_10gb) {
 699                        BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
 700                                         (ctrl_ext | BP10GB_MDIO_DIR |
 701                                          BP10GB_MCLK_SET) & ~(BP10GB_MCLK_DIR |
 702                                                               BP10GB_MDIO_CLR |
 703                                                               BP10GB_MDIO_SET |
 704                                                               BP10GB_MCLK_CLR));
 705
 706                } else if (!pbpctl_dev->bp_10g)
 707                        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
 708                                                                   BPCTLI_CTRL_EXT_MCLK_DIR
 709                                                                   |
 710                                                                   BPCTLI_CTRL_EXT_MCLK_DATA)
 711                                                                  &
 712                                                                  ~
 713                                                                  (BPCTLI_CTRL_EXT_MDIO_DIR)));
 714                else {
 715
 716                        BP10G_WRITE_REG(pbpctl_dev, EODSDP,
 717                                        (ctrl_ext | BP10G_MCLK_DATA_OUT |
 718                                         BP10G_MDIO_DATA_OUT));
 719
 720                }
 721
 722                if (pbpctl_dev->bp_10g9)
 723                        ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
 724                else if ((pbpctl_dev->bp_fiber5) || (pbpctl_dev->bp_i80))
 725                        ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
 726                else if (pbpctl_dev->bp_540)
 727                        ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP);
 728                else if (pbpctl_dev->bp_10gb)
 729                        ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
 730                else if (!pbpctl_dev->bp_10g)
 731                        ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
 732                else
 733                        ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
 734
 735                usec_delay(PULSE_TIME);
 736                if (pbpctl_dev->bp_10g9) {
 737                        if (ctrl_ext & BP10G_MDIO_DATA_IN9)
 738                                ctrl_val |= 1 << i;
 739
 740                } else if (pbpctl_dev->bp_fiber5) {
 741                        if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA5)
 742                                ctrl_val |= 1 << i;
 743                } else if (pbpctl_dev->bp_i80) {
 744                        if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA80)
 745                                ctrl_val |= 1 << i;
 746                } else if (pbpctl_dev->bp_540) {
 747                        if (ctrl_ext & BP540_MDIO_DATA)
 748                                ctrl_val |= 1 << i;
 749                } else if (pbpctl_dev->bp_10gb) {
 750                        if (ctrl_ext & BP10GB_MDIO_DATA)
 751                                ctrl_val |= 1 << i;
 752
 753                } else if (!pbpctl_dev->bp_10g) {
 754
 755                        if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA)
 756                                ctrl_val |= 1 << i;
 757                } else {
 758
 759                        if (ctrl_ext & BP10G_MDIO_DATA_IN)
 760                                ctrl_val |= 1 << i;
 761                }
 762
 763        }
 764
 765        return ctrl_val;
 766}
 767
 768static void write_reg(bpctl_dev_t *pbpctl_dev, unsigned char value,
 769                      unsigned char addr)
 770{
 771        uint32_t ctrl_ext = 0, ctrl = 0;
 772        bpctl_dev_t *pbpctl_dev_c = NULL;
 773        unsigned long flags;
 774        if (pbpctl_dev->bp_10g9) {
 775                pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
 776                if (!pbpctl_dev_c)
 777                        return;
 778        }
 779        if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) &&
 780            (pbpctl_dev->bp_ext_ver < PXG4BPFI_VER))
 781                wdt_time_left(pbpctl_dev);
 782
 783#ifdef BP_SYNC_FLAG
 784        spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags);
 785#else
 786        atomic_set(&pbpctl_dev->wdt_busy, 1);
 787#endif
 788        if (pbpctl_dev->bp_10g9) {
 789
 790                ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
 791                ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
 792                /* DATA 0 CLK 0 */
 793                /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
 794                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
 795                                (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
 796                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
 797                                ((ctrl | BP10G_MCLK_DIR_OUT9) &
 798                                 ~(BP10G_MCLK_DATA_OUT9)));
 799
 800        } else if (pbpctl_dev->bp_fiber5) {
 801                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
 802                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
 803                                                       BPCTLI_CTRL_EXT_MCLK_DIR5
 804                                                       |
 805                                                       BPCTLI_CTRL_EXT_MDIO_DIR5)
 806                                                      &
 807                                                      ~
 808                                                      (BPCTLI_CTRL_EXT_MDIO_DATA5
 809                                                       |
 810                                                       BPCTLI_CTRL_EXT_MCLK_DATA5)));
 811        } else if (pbpctl_dev->bp_i80) {
 812                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
 813                ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
 814                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
 815                                                       BPCTLI_CTRL_EXT_MDIO_DIR80)
 816                                                      &
 817                                                      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
 818                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 819                                   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
 820                                    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
 821
 822        } else if (pbpctl_dev->bp_540) {
 823                ctrl = ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP);
 824                BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |
 825                                                    BP540_MDIO_DIR |
 826                                                    BP540_MCLK_DIR) &
 827                                                   ~(BP540_MDIO_DATA |
 828                                                     BP540_MCLK_DATA)));
 829
 830        } else if (pbpctl_dev->bp_10gb) {
 831                ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
 832
 833                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
 834                                 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
 835                                 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
 836                                     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
 837
 838        } else if (!pbpctl_dev->bp_10g) {
 839
 840                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
 841                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
 842                                                           BPCTLI_CTRL_EXT_MCLK_DIR
 843                                                           |
 844                                                           BPCTLI_CTRL_EXT_MDIO_DIR)
 845                                                          &
 846                                                          ~
 847                                                          (BPCTLI_CTRL_EXT_MDIO_DATA
 848                                                           |
 849                                                           BPCTLI_CTRL_EXT_MCLK_DATA)));
 850        } else {
 851                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
 852                ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
 853                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
 854                                (ctrl_ext &
 855                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
 856        }
 857        usec_delay(CMND_INTERVAL);
 858
 859        /*send sync cmd */
 860        write_pulse(pbpctl_dev, ctrl_ext, SYNC_CMD_VAL, SYNC_CMD_LEN);
 861        /*send wr cmd */
 862        write_pulse(pbpctl_dev, ctrl_ext, WR_CMD_VAL, WR_CMD_LEN);
 863        write_pulse(pbpctl_dev, ctrl_ext, addr, ADDR_CMD_LEN);
 864
 865        /*write data */
 866        write_pulse(pbpctl_dev, ctrl_ext, value, WR_DATA_LEN);
 867        if (pbpctl_dev->bp_10g9) {
 868                /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
 869                /* DATA 0 CLK 0 */
 870                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
 871                                (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
 872                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
 873                                ((ctrl | BP10G_MCLK_DIR_OUT9) &
 874                                 ~(BP10G_MCLK_DATA_OUT9)));
 875
 876        } else if (pbpctl_dev->bp_fiber5) {
 877                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
 878                                                       BPCTLI_CTRL_EXT_MCLK_DIR5
 879                                                       |
 880                                                       BPCTLI_CTRL_EXT_MDIO_DIR5)
 881                                                      &
 882                                                      ~
 883                                                      (BPCTLI_CTRL_EXT_MDIO_DATA5
 884                                                       |
 885                                                       BPCTLI_CTRL_EXT_MCLK_DATA5)));
 886        } else if (pbpctl_dev->bp_i80) {
 887                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
 888                                                       BPCTLI_CTRL_EXT_MDIO_DIR80)
 889                                                      &
 890                                                      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
 891                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 892                                   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
 893                                    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
 894        } else if (pbpctl_dev->bp_540) {
 895                BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |
 896                                                    BP540_MDIO_DIR |
 897                                                    BP540_MCLK_DIR) &
 898                                                   ~(BP540_MDIO_DATA |
 899                                                     BP540_MCLK_DATA)));
 900        } else if (pbpctl_dev->bp_10gb) {
 901                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
 902                                 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
 903                                 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
 904                                     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
 905
 906        } else if (!pbpctl_dev->bp_10g)
 907
 908                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
 909                                                           BPCTLI_CTRL_EXT_MCLK_DIR
 910                                                           |
 911                                                           BPCTLI_CTRL_EXT_MDIO_DIR)
 912                                                          &
 913                                                          ~
 914                                                          (BPCTLI_CTRL_EXT_MDIO_DATA
 915                                                           |
 916                                                           BPCTLI_CTRL_EXT_MCLK_DATA)));
 917        else {
 918                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
 919                                (ctrl_ext &
 920                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
 921
 922        }
 923
 924        usec_delay(CMND_INTERVAL * 4);
 925
 926        if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) &&
 927            (pbpctl_dev->bp_ext_ver < PXG4BPFI_VER) && (addr == CMND_REG_ADDR))
 928                pbpctl_dev->bypass_wdt_on_time = jiffies;
 929#ifdef BP_SYNC_FLAG
 930        spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
 931#else
 932        atomic_set(&pbpctl_dev->wdt_busy, 0);
 933#endif
 934
 935}
 936
 937static void write_data(bpctl_dev_t *pbpctl_dev, unsigned char value)
 938{
 939        write_reg(pbpctl_dev, value, CMND_REG_ADDR);
 940}
 941
 942static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr)
 943{
 944        uint32_t ctrl_ext = 0, ctrl = 0, ctrl_value = 0;
 945        bpctl_dev_t *pbpctl_dev_c = NULL;
 946
 947#ifdef BP_SYNC_FLAG
 948        unsigned long flags;
 949        spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags);
 950#else
 951        atomic_set(&pbpctl_dev->wdt_busy, 1);
 952#endif
 953        if (pbpctl_dev->bp_10g9) {
 954                pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
 955                if (!pbpctl_dev_c)
 956                        return -1;
 957        }
 958
 959        if (pbpctl_dev->bp_10g9) {
 960                ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
 961                ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
 962
 963                /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
 964                /* DATA 0 CLK 0 */
 965                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
 966                                (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
 967                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
 968                                ((ctrl | BP10G_MCLK_DIR_OUT9) &
 969                                 ~(BP10G_MCLK_DATA_OUT9)));
 970
 971        } else if (pbpctl_dev->bp_fiber5) {
 972                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
 973
 974                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
 975                                                       BPCTLI_CTRL_EXT_MCLK_DIR5
 976                                                       |
 977                                                       BPCTLI_CTRL_EXT_MDIO_DIR5)
 978                                                      &
 979                                                      ~
 980                                                      (BPCTLI_CTRL_EXT_MDIO_DATA5
 981                                                       |
 982                                                       BPCTLI_CTRL_EXT_MCLK_DATA5)));
 983        } else if (pbpctl_dev->bp_i80) {
 984                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
 985                ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
 986
 987                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
 988                                                       BPCTLI_CTRL_EXT_MDIO_DIR80)
 989                                                      &
 990                                                      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
 991                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
 992                                   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
 993                                    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
 994        } else if (pbpctl_dev->bp_540) {
 995                ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP);
 996                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
 997
 998                BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
 999                                                    BP540_MDIO_DIR) &
1000                                                   ~(BP540_MDIO_DATA |
1001                                                     BP540_MCLK_DATA)));
1002        } else if (pbpctl_dev->bp_10gb) {
1003                ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
1004
1005                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
1006                                 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
1007                                 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
1008                                     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
1009#if 0
1010
1011                /*BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, (ctrl_ext | BP10GB_MCLK_DIR | BP10GB_MDIO_DIR|
1012                   BP10GB_MCLK_CLR|BP10GB_MDIO_CLR));
1013                   ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
1014                   printk("1reg=%x\n", ctrl_ext); */
1015
1016                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, ((ctrl_ext |
1017                                                              BP10GB_MCLK_SET |
1018                                                              BP10GB_MDIO_CLR))
1019                                 & ~(BP10GB_MCLK_CLR | BP10GB_MDIO_SET |
1020                                     BP10GB_MCLK_DIR | BP10GB_MDIO_DIR));
1021
1022                /*   bnx2x_set_spio(pbpctl_dev, 5, MISC_REGISTERS_SPIO_OUTPUT_LOW);
1023                   bnx2x_set_spio(pbpctl_dev, 4, MISC_REGISTERS_SPIO_OUTPUT_LOW);
1024                   bnx2x_set_spio(pbpctl_dev, 4, MISC_REGISTERS_SPIO_INPUT_HI_Z); */
1025
1026                ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
1027
1028                printk("2reg=%x\n", ctrl_ext);
1029
1030#ifdef BP_SYNC_FLAG
1031                spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
1032#else
1033                atomic_set(&pbpctl_dev->wdt_busy, 0);
1034#endif
1035
1036                return 0;
1037
1038#endif
1039
1040        } else if (!pbpctl_dev->bp_10g) {
1041
1042                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1043
1044                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1045                                                           BPCTLI_CTRL_EXT_MCLK_DIR
1046                                                           |
1047                                                           BPCTLI_CTRL_EXT_MDIO_DIR)
1048                                                          &
1049                                                          ~
1050                                                          (BPCTLI_CTRL_EXT_MDIO_DATA
1051                                                           |
1052                                                           BPCTLI_CTRL_EXT_MCLK_DATA)));
1053        } else {
1054
1055                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
1056                ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
1057                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
1058                                (ctrl_ext &
1059                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
1060
1061        }
1062
1063        usec_delay(CMND_INTERVAL);
1064
1065        /*send sync cmd */
1066        write_pulse(pbpctl_dev, ctrl_ext, SYNC_CMD_VAL, SYNC_CMD_LEN);
1067        /*send rd cmd */
1068        write_pulse(pbpctl_dev, ctrl_ext, RD_CMD_VAL, RD_CMD_LEN);
1069        /*send addr */
1070        write_pulse(pbpctl_dev, ctrl_ext, addr, ADDR_CMD_LEN);
1071        /*read data */
1072        /* zero */
1073        if (pbpctl_dev->bp_10g9) {
1074                /* DATA 0 CLK 1 */
1075                /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */
1076                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
1077                                (ctrl_ext | BP10G_MDIO_DATA_OUT9));
1078                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
1079                                (ctrl | BP10G_MCLK_DATA_OUT9 |
1080                                 BP10G_MCLK_DIR_OUT9));
1081
1082        } else if (pbpctl_dev->bp_fiber5) {
1083                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
1084                                                       BPCTLI_CTRL_EXT_MCLK_DIR5
1085                                                       |
1086                                                       BPCTLI_CTRL_EXT_MCLK_DATA5)
1087                                                      &
1088                                                      ~
1089                                                      (BPCTLI_CTRL_EXT_MDIO_DIR5
1090                                                       |
1091                                                       BPCTLI_CTRL_EXT_MDIO_DATA5)));
1092
1093        } else if (pbpctl_dev->bp_i80) {
1094                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
1095                                   (ctrl_ext &
1096                                    ~(BPCTLI_CTRL_EXT_MDIO_DATA80 |
1097                                      BPCTLI_CTRL_EXT_MDIO_DIR80)));
1098                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
1099                                   (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 |
1100                                    BPCTLI_CTRL_EXT_MCLK_DATA80));
1101
1102        } else if (pbpctl_dev->bp_540) {
1103                BP10G_WRITE_REG(pbpctl_dev, ESDP,
1104                                (((ctrl | BP540_MDIO_DIR | BP540_MCLK_DIR |
1105                                   BP540_MCLK_DATA) & ~BP540_MDIO_DATA)));
1106
1107        } else if (pbpctl_dev->bp_10gb) {
1108
1109                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
1110                                 (ctrl_ext | BP10GB_MDIO_DIR | BP10GB_MCLK_SET)
1111                                 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_SET |
1112                                     BP10GB_MDIO_CLR | BP10GB_MCLK_CLR));
1113
1114        } else if (!pbpctl_dev->bp_10g)
1115                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1116                                                           BPCTLI_CTRL_EXT_MCLK_DIR
1117                                                           |
1118                                                           BPCTLI_CTRL_EXT_MCLK_DATA)
1119                                                          &
1120                                                          ~
1121                                                          (BPCTLI_CTRL_EXT_MDIO_DIR
1122                                                           |
1123                                                           BPCTLI_CTRL_EXT_MDIO_DATA)));
1124        else {
1125
1126                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
1127                                (ctrl_ext | BP10G_MCLK_DATA_OUT |
1128                                 BP10G_MDIO_DATA_OUT));
1129
1130
1131        }
1132        usec_delay(PULSE_TIME);
1133
1134        ctrl_value = read_pulse(pbpctl_dev, ctrl_ext, RD_DATA_LEN);
1135
1136        if (pbpctl_dev->bp_10g9) {
1137                ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
1138                ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
1139
1140                /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
1141                /* DATA 0 CLK 0 */
1142                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
1143                                (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
1144                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
1145                                ((ctrl | BP10G_MCLK_DIR_OUT9) &
1146                                 ~(BP10G_MCLK_DATA_OUT9)));
1147
1148        } else if (pbpctl_dev->bp_fiber5) {
1149                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
1150                                                       BPCTLI_CTRL_EXT_MCLK_DIR5
1151                                                       |
1152                                                       BPCTLI_CTRL_EXT_MDIO_DIR5)
1153                                                      &
1154                                                      ~
1155                                                      (BPCTLI_CTRL_EXT_MDIO_DATA5
1156                                                       |
1157                                                       BPCTLI_CTRL_EXT_MCLK_DATA5)));
1158        } else if (pbpctl_dev->bp_i80) {
1159                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
1160                                                       BPCTLI_CTRL_EXT_MDIO_DIR80)
1161                                                      &
1162                                                      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
1163                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
1164                                   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
1165                                    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
1166
1167        } else if (pbpctl_dev->bp_540) {
1168                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
1169                BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
1170                                                    BP540_MDIO_DIR) &
1171                                                   ~(BP540_MDIO_DATA |
1172                                                     BP540_MCLK_DATA)));
1173
1174        } else if (pbpctl_dev->bp_10gb) {
1175                ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
1176                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
1177                                 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
1178                                 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
1179                                     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
1180
1181        } else if (!pbpctl_dev->bp_10g) {
1182                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1183                                                           BPCTLI_CTRL_EXT_MCLK_DIR
1184                                                           |
1185                                                           BPCTLI_CTRL_EXT_MDIO_DIR)
1186                                                          &
1187                                                          ~
1188                                                          (BPCTLI_CTRL_EXT_MDIO_DATA
1189                                                           |
1190                                                           BPCTLI_CTRL_EXT_MCLK_DATA)));
1191        } else {
1192
1193                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
1194                ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
1195                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
1196                                (ctrl_ext &
1197                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
1198
1199        }
1200
1201        usec_delay(CMND_INTERVAL * 4);
1202#ifdef BP_SYNC_FLAG
1203        spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
1204#else
1205        atomic_set(&pbpctl_dev->wdt_busy, 0);
1206#endif
1207
1208        return ctrl_value;
1209}
1210
1211static int wdt_pulse(bpctl_dev_t *pbpctl_dev)
1212{
1213        uint32_t ctrl_ext = 0, ctrl = 0;
1214        bpctl_dev_t *pbpctl_dev_c = NULL;
1215
1216#ifdef BP_SYNC_FLAG
1217        unsigned long flags;
1218
1219        spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags);
1220#else
1221
1222        if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)
1223                return -1;
1224#endif
1225        if (pbpctl_dev->bp_10g9) {
1226                pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
1227                if (!pbpctl_dev_c)
1228                        return -1;
1229        }
1230
1231        if (pbpctl_dev->bp_10g9) {
1232                ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL);
1233                ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
1234
1235                /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
1236                /* DATA 0 CLK 0 */
1237                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
1238                                (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
1239                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
1240                                ((ctrl | BP10G_MCLK_DIR_OUT9) &
1241                                 ~(BP10G_MCLK_DATA_OUT9)));
1242
1243        } else if (pbpctl_dev->bp_fiber5) {
1244                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
1245                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
1246                                                       BPCTLI_CTRL_EXT_MCLK_DIR5
1247                                                       |
1248                                                       BPCTLI_CTRL_EXT_MDIO_DIR5)
1249                                                      &
1250                                                      ~
1251                                                      (BPCTLI_CTRL_EXT_MDIO_DATA5
1252                                                       |
1253                                                       BPCTLI_CTRL_EXT_MCLK_DATA5)));
1254        } else if (pbpctl_dev->bp_i80) {
1255                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
1256                ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1257                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
1258                                                       BPCTLI_CTRL_EXT_MDIO_DIR80)
1259                                                      &
1260                                                      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
1261                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
1262                                   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
1263                                    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
1264        } else if (pbpctl_dev->bp_540) {
1265                ctrl_ext = ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
1266                BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
1267                                                    BP540_MDIO_DIR) &
1268                                                   ~(BP540_MDIO_DATA |
1269                                                     BP540_MCLK_DATA)));
1270        } else if (pbpctl_dev->bp_10gb) {
1271                ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
1272                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
1273                                 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
1274                                 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
1275                                     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
1276
1277        } else if (!pbpctl_dev->bp_10g) {
1278
1279                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1280                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1281                                                           BPCTLI_CTRL_EXT_MCLK_DIR
1282                                                           |
1283                                                           BPCTLI_CTRL_EXT_MDIO_DIR)
1284                                                          &
1285                                                          ~
1286                                                          (BPCTLI_CTRL_EXT_MDIO_DATA
1287                                                           |
1288                                                           BPCTLI_CTRL_EXT_MCLK_DATA)));
1289        } else {
1290
1291                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
1292                ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
1293                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
1294                                (ctrl_ext &
1295                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
1296
1297        }
1298        if (pbpctl_dev->bp_10g9) {
1299                /*   BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MCLK_DATA_OUT9)&~BP10G_MDIO_DATA_OUT9)); */
1300                /* DATA 0 CLK 1 */
1301                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
1302                                (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
1303                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
1304                                (ctrl | BP10G_MCLK_DATA_OUT9 |
1305                                 BP10G_MCLK_DIR_OUT9));
1306
1307        } else if (pbpctl_dev->bp_fiber5) {
1308                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
1309                                                       BPCTLI_CTRL_EXT_MCLK_DIR5
1310                                                       |
1311                                                       BPCTLI_CTRL_EXT_MDIO_DIR5
1312                                                       |
1313                                                       BPCTLI_CTRL_EXT_MCLK_DATA5)
1314                                                      &
1315                                                      ~
1316                                                      (BPCTLI_CTRL_EXT_MDIO_DATA5)));
1317        } else if (pbpctl_dev->bp_i80) {
1318                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
1319                                                       BPCTLI_CTRL_EXT_MDIO_DIR80)
1320                                                      &
1321                                                      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
1322                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
1323                                   (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 |
1324                                    BPCTLI_CTRL_EXT_MCLK_DATA80));
1325
1326        } else if (pbpctl_dev->bp_540) {
1327                BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |
1328                                                    BP540_MDIO_DIR |
1329                                                    BP540_MCLK_DIR |
1330                                                    BP540_MCLK_DATA) &
1331                                                   ~BP540_MDIO_DATA));
1332
1333        } else if (pbpctl_dev->bp_10gb) {
1334                ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
1335
1336                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
1337                                 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_SET)
1338                                 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
1339                                     BP10GB_MDIO_SET | BP10GB_MCLK_CLR));
1340
1341        } else if (!pbpctl_dev->bp_10g)
1342                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1343                                                           BPCTLI_CTRL_EXT_MCLK_DIR
1344                                                           |
1345                                                           BPCTLI_CTRL_EXT_MDIO_DIR
1346                                                           |
1347                                                           BPCTLI_CTRL_EXT_MCLK_DATA)
1348                                                          &
1349                                                          ~
1350                                                          (BPCTLI_CTRL_EXT_MDIO_DATA)));
1351        else {
1352
1353                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
1354                                ((ctrl_ext | BP10G_MCLK_DATA_OUT) &
1355                                 ~BP10G_MDIO_DATA_OUT));
1356
1357        }
1358
1359        usec_delay(WDT_INTERVAL);
1360        if (pbpctl_dev->bp_10g9) {
1361                /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */
1362                /* DATA 0 CLK 0 */
1363                BP10G_WRITE_REG(pbpctl_dev, I2CCTL,
1364                                (ctrl_ext & ~BP10G_MDIO_DATA_OUT9));
1365                BP10G_WRITE_REG(pbpctl_dev_c, ESDP,
1366                                ((ctrl | BP10G_MCLK_DIR_OUT9) &
1367                                 ~(BP10G_MCLK_DATA_OUT9)));
1368
1369        } else if (pbpctl_dev->bp_fiber5) {
1370                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
1371                                                       BPCTLI_CTRL_EXT_MCLK_DIR5
1372                                                       |
1373                                                       BPCTLI_CTRL_EXT_MDIO_DIR5)
1374                                                      &
1375                                                      ~
1376                                                      (BPCTLI_CTRL_EXT_MCLK_DATA5
1377                                                       |
1378                                                       BPCTLI_CTRL_EXT_MDIO_DATA5)));
1379        } else if (pbpctl_dev->bp_i80) {
1380                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext |
1381                                                       BPCTLI_CTRL_EXT_MDIO_DIR80)
1382                                                      &
1383                                                      ~BPCTLI_CTRL_EXT_MDIO_DATA80));
1384                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
1385                                   ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) &
1386                                    ~BPCTLI_CTRL_EXT_MCLK_DATA80));
1387
1388        } else if (pbpctl_dev->bp_540) {
1389                BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR |
1390                                                    BP540_MDIO_DIR) &
1391                                                   ~(BP540_MDIO_DATA |
1392                                                     BP540_MCLK_DATA)));
1393
1394        } else if (pbpctl_dev->bp_10gb) {
1395                ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
1396                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO,
1397                                 (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)
1398                                 & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR |
1399                                     BP10GB_MDIO_SET | BP10GB_MCLK_SET));
1400
1401        } else if (!pbpctl_dev->bp_10g)
1402                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1403                                                           BPCTLI_CTRL_EXT_MCLK_DIR
1404                                                           |
1405                                                           BPCTLI_CTRL_EXT_MDIO_DIR)
1406                                                          &
1407                                                          ~
1408                                                          (BPCTLI_CTRL_EXT_MCLK_DATA
1409                                                           |
1410                                                           BPCTLI_CTRL_EXT_MDIO_DATA)));
1411        else {
1412
1413                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
1414                                (ctrl_ext &
1415                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
1416        }
1417        if ((pbpctl_dev->wdt_status == WDT_STATUS_EN))
1418                /*&& (pbpctl_dev->bp_ext_ver<PXG4BPFI_VER) */
1419                pbpctl_dev->bypass_wdt_on_time = jiffies;
1420#ifdef BP_SYNC_FLAG
1421        spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
1422#endif
1423        usec_delay(CMND_INTERVAL * 4);
1424        return 0;
1425}
1426
1427static void data_pulse(bpctl_dev_t *pbpctl_dev, unsigned char value)
1428{
1429
1430        uint32_t ctrl_ext = 0;
1431#ifdef BP_SYNC_FLAG
1432        unsigned long flags;
1433#endif
1434        wdt_time_left(pbpctl_dev);
1435#ifdef BP_SYNC_FLAG
1436        spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags);
1437#else
1438        atomic_set(&pbpctl_dev->wdt_busy, 1);
1439#endif
1440
1441        ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1442        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1443                                                   BPCTLI_CTRL_EXT_SDP6_DIR |
1444                                                   BPCTLI_CTRL_EXT_SDP7_DIR) &
1445                                                  ~(BPCTLI_CTRL_EXT_SDP6_DATA |
1446                                                    BPCTLI_CTRL_EXT_SDP7_DATA)));
1447
1448        usec_delay(INIT_CMND_INTERVAL);
1449        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1450                                                   BPCTLI_CTRL_EXT_SDP6_DIR |
1451                                                   BPCTLI_CTRL_EXT_SDP7_DIR |
1452                                                   BPCTLI_CTRL_EXT_SDP6_DATA) &
1453                                                  ~
1454                                                  (BPCTLI_CTRL_EXT_SDP7_DATA)));
1455        usec_delay(INIT_CMND_INTERVAL);
1456
1457        while (value) {
1458                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |
1459                                   BPCTLI_CTRL_EXT_SDP6_DIR |
1460                                   BPCTLI_CTRL_EXT_SDP7_DIR |
1461                                   BPCTLI_CTRL_EXT_SDP6_DATA |
1462                                   BPCTLI_CTRL_EXT_SDP7_DATA);
1463                usec_delay(PULSE_INTERVAL);
1464                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1465                                                           BPCTLI_CTRL_EXT_SDP6_DIR
1466                                                           |
1467                                                           BPCTLI_CTRL_EXT_SDP7_DIR
1468                                                           |
1469                                                           BPCTLI_CTRL_EXT_SDP6_DATA)
1470                                                          &
1471                                                          ~BPCTLI_CTRL_EXT_SDP7_DATA));
1472                usec_delay(PULSE_INTERVAL);
1473                value--;
1474
1475        }
1476        usec_delay(INIT_CMND_INTERVAL - PULSE_INTERVAL);
1477        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1478                                                   BPCTLI_CTRL_EXT_SDP6_DIR |
1479                                                   BPCTLI_CTRL_EXT_SDP7_DIR) &
1480                                                  ~(BPCTLI_CTRL_EXT_SDP6_DATA |
1481                                                    BPCTLI_CTRL_EXT_SDP7_DATA)));
1482        usec_delay(WDT_TIME_CNT);
1483        if (pbpctl_dev->wdt_status == WDT_STATUS_EN)
1484                pbpctl_dev->bypass_wdt_on_time = jiffies;
1485#ifdef BP_SYNC_FLAG
1486        spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
1487#else
1488        atomic_set(&pbpctl_dev->wdt_busy, 0);
1489#endif
1490
1491}
1492
1493static int send_wdt_pulse(bpctl_dev_t *pbpctl_dev)
1494{
1495        uint32_t ctrl_ext = 0;
1496
1497#ifdef BP_SYNC_FLAG
1498        unsigned long flags;
1499
1500        spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags);
1501#else
1502
1503        if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)
1504                return -1;
1505#endif
1506        wdt_time_left(pbpctl_dev);
1507        ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1508
1509        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |     /* 1 */
1510                           BPCTLI_CTRL_EXT_SDP7_DIR |
1511                           BPCTLI_CTRL_EXT_SDP7_DATA);
1512        usec_delay(PULSE_INTERVAL);
1513        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |   /* 0 */
1514                                                   BPCTLI_CTRL_EXT_SDP7_DIR) &
1515                                                  ~BPCTLI_CTRL_EXT_SDP7_DATA));
1516
1517        usec_delay(PULSE_INTERVAL);
1518        if (pbpctl_dev->wdt_status == WDT_STATUS_EN)
1519                pbpctl_dev->bypass_wdt_on_time = jiffies;
1520#ifdef BP_SYNC_FLAG
1521        spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
1522#endif
1523
1524        return 0;
1525}
1526
1527void send_bypass_clear_pulse(bpctl_dev_t *pbpctl_dev, unsigned int value)
1528{
1529        uint32_t ctrl_ext = 0;
1530
1531        ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1532        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |   /* 0 */
1533                                                   BPCTLI_CTRL_EXT_SDP6_DIR) &
1534                                                  ~BPCTLI_CTRL_EXT_SDP6_DATA));
1535
1536        usec_delay(PULSE_INTERVAL);
1537        while (value) {
1538                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |     /* 1 */
1539                                   BPCTLI_CTRL_EXT_SDP6_DIR |
1540                                   BPCTLI_CTRL_EXT_SDP6_DATA);
1541                usec_delay(PULSE_INTERVAL);
1542                value--;
1543        }
1544        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |   /* 0 */
1545                                                   BPCTLI_CTRL_EXT_SDP6_DIR) &
1546                                                  ~BPCTLI_CTRL_EXT_SDP6_DATA));
1547        usec_delay(PULSE_INTERVAL);
1548}
1549
1550/*  #endif  OLD_FW */
1551#ifdef BYPASS_DEBUG
1552
1553int pulse_set_fn(bpctl_dev_t *pbpctl_dev, unsigned int counter)
1554{
1555        uint32_t ctrl_ext = 0;
1556
1557        if (!pbpctl_dev)
1558                return -1;
1559
1560        ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1561        write_pulse_1(pbpctl_dev, ctrl_ext, counter, counter);
1562
1563        pbpctl_dev->bypass_wdt_status = 0;
1564        if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
1565                write_pulse_1(pbpctl_dev, ctrl_ext, counter, counter);
1566        } else {
1567                wdt_time_left(pbpctl_dev);
1568                if (pbpctl_dev->wdt_status == WDT_STATUS_EN) {
1569                        pbpctl_dev->wdt_status = 0;
1570                        data_pulse(pbpctl_dev, counter);
1571                        pbpctl_dev->wdt_status = WDT_STATUS_EN;
1572                        pbpctl_dev->bypass_wdt_on_time = jiffies;
1573
1574                } else
1575                        data_pulse(pbpctl_dev, counter);
1576        }
1577
1578        return 0;
1579}
1580
1581int zero_set_fn(bpctl_dev_t *pbpctl_dev)
1582{
1583        uint32_t ctrl_ext = 0, ctrl_value = 0;
1584        if (!pbpctl_dev)
1585                return -1;
1586
1587        if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
1588                printk("zero_set");
1589
1590                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1591
1592                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1593                                                           BPCTLI_CTRL_EXT_MCLK_DIR)
1594                                                          &
1595                                                          ~
1596                                                          (BPCTLI_CTRL_EXT_MCLK_DATA
1597                                                           |
1598                                                           BPCTLI_CTRL_EXT_MDIO_DIR
1599                                                           |
1600                                                           BPCTLI_CTRL_EXT_MDIO_DATA)));
1601
1602        }
1603        return ctrl_value;
1604}
1605
1606int pulse_get2_fn(bpctl_dev_t *pbpctl_dev)
1607{
1608        uint32_t ctrl_ext = 0, ctrl_value = 0;
1609        if (!pbpctl_dev)
1610                return -1;
1611
1612        if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
1613                printk("pulse_get_fn\n");
1614                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1615                ctrl_value = read_pulse_2(pbpctl_dev, ctrl_ext);
1616                printk("read:%d\n", ctrl_value);
1617        }
1618        return ctrl_value;
1619}
1620
1621int pulse_get1_fn(bpctl_dev_t *pbpctl_dev)
1622{
1623        uint32_t ctrl_ext = 0, ctrl_value = 0;
1624        if (!pbpctl_dev)
1625                return -1;
1626
1627        if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
1628
1629                printk("pulse_get_fn\n");
1630
1631                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1632                ctrl_value = read_pulse_1(pbpctl_dev, ctrl_ext);
1633                printk("read:%d\n", ctrl_value);
1634        }
1635        return ctrl_value;
1636}
1637
1638int gpio6_set_fn(bpctl_dev_t *pbpctl_dev)
1639{
1640        uint32_t ctrl_ext = 0;
1641
1642        ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1643        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |
1644                           BPCTLI_CTRL_EXT_SDP6_DIR |
1645                           BPCTLI_CTRL_EXT_SDP6_DATA);
1646        return 0;
1647}
1648
1649int gpio7_set_fn(bpctl_dev_t *pbpctl_dev)
1650{
1651        uint32_t ctrl_ext = 0;
1652
1653        ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1654        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext |
1655                           BPCTLI_CTRL_EXT_SDP7_DIR |
1656                           BPCTLI_CTRL_EXT_SDP7_DATA);
1657        return 0;
1658}
1659
1660int gpio7_clear_fn(bpctl_dev_t *pbpctl_dev)
1661{
1662        uint32_t ctrl_ext = 0;
1663
1664        ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1665        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1666                                                   BPCTLI_CTRL_EXT_SDP7_DIR) &
1667                                                  ~BPCTLI_CTRL_EXT_SDP7_DATA));
1668        return 0;
1669}
1670
1671int gpio6_clear_fn(bpctl_dev_t *pbpctl_dev)
1672{
1673        uint32_t ctrl_ext = 0;
1674
1675        ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
1676        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext |
1677                                                   BPCTLI_CTRL_EXT_SDP6_DIR) &
1678                                                  ~BPCTLI_CTRL_EXT_SDP6_DATA));
1679        return 0;
1680}
1681#endif                          /*BYPASS_DEBUG */
1682
1683static bpctl_dev_t *lookup_port(bpctl_dev_t *dev)
1684{
1685        bpctl_dev_t *p;
1686        int n;
1687        for (n = 0, p = bpctl_dev_arr; n < device_num && p->pdev; n++) {
1688                if (p->bus == dev->bus
1689                    && p->slot == dev->slot
1690                    && p->func == (dev->func ^ 1))
1691                        return p;
1692        }
1693        return NULL;
1694}
1695
1696static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev)
1697{
1698        if (pbpctl_dev) {
1699                if (pbpctl_dev->func == 0 || pbpctl_dev->func == 2)
1700                        return lookup_port(pbpctl_dev);
1701        }
1702        return NULL;
1703}
1704
1705static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev)
1706{
1707        if (pbpctl_dev) {
1708                if (pbpctl_dev->func == 1 || pbpctl_dev->func == 3)
1709                        return lookup_port(pbpctl_dev);
1710        }
1711        return NULL;
1712}
1713
1714/**************************************/
1715/**************INTEL API***************/
1716/**************************************/
1717
1718static void write_data_port_int(bpctl_dev_t *pbpctl_dev,
1719                                unsigned char ctrl_value)
1720{
1721        uint32_t value;
1722
1723        value = BPCTL_READ_REG(pbpctl_dev, CTRL);
1724/* Make SDP0 Pin Directonality to Output */
1725        value |= BPCTLI_CTRL_SDP0_DIR;
1726        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value);
1727
1728        value &= ~BPCTLI_CTRL_SDP0_DATA;
1729        value |= ((ctrl_value & 0x1) << BPCTLI_CTRL_SDP0_SHIFT);
1730        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value);
1731
1732        value = (BPCTL_READ_REG(pbpctl_dev, CTRL_EXT));
1733/* Make SDP2 Pin Directonality to Output */
1734        value |= BPCTLI_CTRL_EXT_SDP6_DIR;
1735        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, value);
1736
1737        value &= ~BPCTLI_CTRL_EXT_SDP6_DATA;
1738        value |= (((ctrl_value & 0x2) >> 1) << BPCTLI_CTRL_EXT_SDP6_SHIFT);
1739        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, value);
1740
1741}
1742
1743static int write_data_int(bpctl_dev_t *pbpctl_dev, unsigned char value)
1744{
1745        bpctl_dev_t *pbpctl_dev_b = NULL;
1746
1747        pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
1748        if (!pbpctl_dev_b)
1749                return -1;
1750        atomic_set(&pbpctl_dev->wdt_busy, 1);
1751        write_data_port_int(pbpctl_dev, value & 0x3);
1752        write_data_port_int(pbpctl_dev_b, ((value & 0xc) >> 2));
1753        atomic_set(&pbpctl_dev->wdt_busy, 0);
1754
1755        return 0;
1756}
1757
1758static int wdt_pulse_int(bpctl_dev_t *pbpctl_dev)
1759{
1760
1761        if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)
1762                return -1;
1763
1764        if ((write_data_int(pbpctl_dev, RESET_WDT_INT)) < 0)
1765                return -1;
1766        msec_delay_bp(CMND_INTERVAL_INT);
1767        if ((write_data_int(pbpctl_dev, CMND_OFF_INT)) < 0)
1768                return -1;
1769        msec_delay_bp(CMND_INTERVAL_INT);
1770
1771        if (pbpctl_dev->wdt_status == WDT_STATUS_EN)
1772                pbpctl_dev->bypass_wdt_on_time = jiffies;
1773
1774        return 0;
1775}
1776
1777/*************************************/
1778/************* COMMANDS **************/
1779/*************************************/
1780
1781/* CMND_ON  0x4 (100)*/
1782int cmnd_on(bpctl_dev_t *pbpctl_dev)
1783{
1784        int ret = BP_NOT_CAP;
1785
1786        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
1787                if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
1788                        return 0;
1789                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
1790                        write_data(pbpctl_dev, CMND_ON);
1791                else
1792                        data_pulse(pbpctl_dev, CMND_ON);
1793                ret = 0;
1794        }
1795        return ret;
1796}
1797
1798/* CMND_OFF  0x2 (10)*/
1799int cmnd_off(bpctl_dev_t *pbpctl_dev)
1800{
1801        int ret = BP_NOT_CAP;
1802
1803        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
1804                if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
1805                        write_data_int(pbpctl_dev, CMND_OFF_INT);
1806                        msec_delay_bp(CMND_INTERVAL_INT);
1807                } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
1808                        write_data(pbpctl_dev, CMND_OFF);
1809                else
1810                        data_pulse(pbpctl_dev, CMND_OFF);
1811                ret = 0;
1812        };
1813        return ret;
1814}
1815
1816/* BYPASS_ON (0xa)*/
1817int bypass_on(bpctl_dev_t *pbpctl_dev)
1818{
1819        int ret = BP_NOT_CAP;
1820
1821        if (pbpctl_dev->bp_caps & BP_CAP) {
1822                if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
1823                        write_data_int(pbpctl_dev, BYPASS_ON_INT);
1824                        msec_delay_bp(BYPASS_DELAY_INT);
1825                        pbpctl_dev->bp_status_un = 0;
1826                } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
1827                        write_data(pbpctl_dev, BYPASS_ON);
1828                        if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
1829                                msec_delay_bp(LATCH_DELAY);
1830                } else
1831                        data_pulse(pbpctl_dev, BYPASS_ON);
1832                ret = 0;
1833        };
1834        return ret;
1835}
1836
1837/* BYPASS_OFF (0x8 111)*/
1838int bypass_off(bpctl_dev_t *pbpctl_dev)
1839{
1840        int ret = BP_NOT_CAP;
1841
1842        if (pbpctl_dev->bp_caps & BP_CAP) {
1843                if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
1844                        write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
1845                        msec_delay_bp(BYPASS_DELAY_INT);
1846                        write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT);
1847                        msec_delay_bp(BYPASS_DELAY_INT);
1848                        pbpctl_dev->bp_status_un = 0;
1849                } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
1850                        write_data(pbpctl_dev, BYPASS_OFF);
1851                        if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
1852                                msec_delay_bp(LATCH_DELAY);
1853                } else
1854                        data_pulse(pbpctl_dev, BYPASS_OFF);
1855                ret = 0;
1856        }
1857        return ret;
1858}
1859
1860/* TAP_OFF (0x9)*/
1861int tap_off(bpctl_dev_t *pbpctl_dev)
1862{
1863        int ret = BP_NOT_CAP;
1864        if ((pbpctl_dev->bp_caps & TAP_CAP)
1865            && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) {
1866                write_data(pbpctl_dev, TAP_OFF);
1867                msec_delay_bp(LATCH_DELAY);
1868                ret = 0;
1869        };
1870        return ret;
1871}
1872
1873/* TAP_ON (0xb)*/
1874int tap_on(bpctl_dev_t *pbpctl_dev)
1875{
1876        int ret = BP_NOT_CAP;
1877        if ((pbpctl_dev->bp_caps & TAP_CAP)
1878            && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) {
1879                write_data(pbpctl_dev, TAP_ON);
1880                msec_delay_bp(LATCH_DELAY);
1881                ret = 0;
1882        };
1883        return ret;
1884}
1885
1886/* DISC_OFF (0x9)*/
1887int disc_off(bpctl_dev_t *pbpctl_dev)
1888{
1889        int ret = 0;
1890        if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) {
1891                write_data(pbpctl_dev, DISC_OFF);
1892                msec_delay_bp(LATCH_DELAY);
1893        } else
1894                ret = BP_NOT_CAP;
1895        return ret;
1896}
1897
1898/* DISC_ON (0xb)*/
1899int disc_on(bpctl_dev_t *pbpctl_dev)
1900{
1901        int ret = 0;
1902        if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) {
1903                write_data(pbpctl_dev, /*DISC_ON */ 0x85);
1904                msec_delay_bp(LATCH_DELAY);
1905        } else
1906                ret = BP_NOT_CAP;
1907        return ret;
1908}
1909
1910/* DISC_PORT_ON */
1911int disc_port_on(bpctl_dev_t *pbpctl_dev)
1912{
1913        int ret = 0;
1914        bpctl_dev_t *pbpctl_dev_m;
1915
1916        if ((is_bypass_fn(pbpctl_dev)) == 1)
1917                pbpctl_dev_m = pbpctl_dev;
1918        else
1919                pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
1920        if (pbpctl_dev_m == NULL)
1921                return BP_NOT_CAP;
1922
1923        if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
1924                if (is_bypass_fn(pbpctl_dev) == 1)
1925                        write_data(pbpctl_dev_m, TX_DISA);
1926                else
1927                        write_data(pbpctl_dev_m, TX_DISB);
1928
1929                msec_delay_bp(LATCH_DELAY);
1930
1931        }
1932        return ret;
1933}
1934
1935/* DISC_PORT_OFF */
1936int disc_port_off(bpctl_dev_t *pbpctl_dev)
1937{
1938        int ret = 0;
1939        bpctl_dev_t *pbpctl_dev_m;
1940
1941        if ((is_bypass_fn(pbpctl_dev)) == 1)
1942                pbpctl_dev_m = pbpctl_dev;
1943        else
1944                pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
1945        if (pbpctl_dev_m == NULL)
1946                return BP_NOT_CAP;
1947
1948        if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
1949                if (is_bypass_fn(pbpctl_dev) == 1)
1950                        write_data(pbpctl_dev_m, TX_ENA);
1951                else
1952                        write_data(pbpctl_dev_m, TX_ENB);
1953
1954                msec_delay_bp(LATCH_DELAY);
1955
1956        }
1957        return ret;
1958}
1959
1960/*TWO_PORT_LINK_HW_EN (0xe)*/
1961int tpl_hw_on(bpctl_dev_t *pbpctl_dev)
1962{
1963        int ret = 0, ctrl = 0;
1964        bpctl_dev_t *pbpctl_dev_b = NULL;
1965
1966        pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
1967        if (!pbpctl_dev_b)
1968                return BP_NOT_CAP;
1969
1970        if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) {
1971                cmnd_on(pbpctl_dev);
1972                write_data(pbpctl_dev, TPL2_ON);
1973                msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
1974                cmnd_off(pbpctl_dev);
1975                return ret;
1976        }
1977
1978        if (TPL_IF_SERIES(pbpctl_dev->subdevice)) {
1979                ctrl = BPCTL_READ_REG(pbpctl_dev_b, CTRL);
1980                BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL,
1981                                   ((ctrl | BPCTLI_CTRL_SWDPIO0) &
1982                                    ~BPCTLI_CTRL_SWDPIN0));
1983        } else
1984                ret = BP_NOT_CAP;
1985        return ret;
1986}
1987
1988/*TWO_PORT_LINK_HW_DIS (0xc)*/
1989int tpl_hw_off(bpctl_dev_t *pbpctl_dev)
1990{
1991        int ret = 0, ctrl = 0;
1992        bpctl_dev_t *pbpctl_dev_b = NULL;
1993
1994        pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
1995        if (!pbpctl_dev_b)
1996                return BP_NOT_CAP;
1997        if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) {
1998                cmnd_on(pbpctl_dev);
1999                write_data(pbpctl_dev, TPL2_OFF);
2000                msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
2001                cmnd_off(pbpctl_dev);
2002                return ret;
2003        }
2004        if (TPL_IF_SERIES(pbpctl_dev->subdevice)) {
2005                ctrl = BPCTL_READ_REG(pbpctl_dev_b, CTRL);
2006                BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL,
2007                                   (ctrl | BPCTLI_CTRL_SWDPIO0 |
2008                                    BPCTLI_CTRL_SWDPIN0));
2009        } else
2010                ret = BP_NOT_CAP;
2011        return ret;
2012}
2013
2014/* WDT_OFF (0x6 110)*/
2015int wdt_off(bpctl_dev_t *pbpctl_dev)
2016{
2017        int ret = BP_NOT_CAP;
2018
2019        if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
2020                if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
2021                        bypass_off(pbpctl_dev);
2022                else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
2023                        write_data(pbpctl_dev, WDT_OFF);
2024                else
2025                        data_pulse(pbpctl_dev, WDT_OFF);
2026                pbpctl_dev->wdt_status = WDT_STATUS_DIS;
2027                ret = 0;
2028        };
2029        return ret;
2030}
2031
2032/* WDT_ON (0x10)*/
2033
2034/***Global***/
2035static unsigned int
2036    wdt_val_array[] = { 1000, 1500, 2000, 3000, 4000, 8000, 16000, 32000, 0 };
2037
2038int wdt_on(bpctl_dev_t *pbpctl_dev, unsigned int timeout)
2039{
2040
2041        if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
2042                unsigned int pulse = 0, temp_value = 0, temp_cnt = 0;
2043                pbpctl_dev->wdt_status = 0;
2044
2045                if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
2046                        for (; wdt_val_array[temp_cnt]; temp_cnt++)
2047                                if (timeout <= wdt_val_array[temp_cnt])
2048                                        break;
2049
2050                        if (!wdt_val_array[temp_cnt])
2051                                temp_cnt--;
2052
2053                        timeout = wdt_val_array[temp_cnt];
2054                        temp_cnt += 0x7;
2055
2056                        write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
2057                        msec_delay_bp(BYPASS_DELAY_INT);
2058                        pbpctl_dev->bp_status_un = 0;
2059                        write_data_int(pbpctl_dev, temp_cnt);
2060                        pbpctl_dev->bypass_wdt_on_time = jiffies;
2061                        msec_delay_bp(CMND_INTERVAL_INT);
2062                        pbpctl_dev->bypass_timer_interval = timeout;
2063                } else {
2064                        timeout =
2065                            (timeout <
2066                             TIMEOUT_UNIT ? TIMEOUT_UNIT : (timeout >
2067                                                            WDT_TIMEOUT_MAX ?
2068                                                            WDT_TIMEOUT_MAX :
2069                                                            timeout));
2070                        temp_value = timeout / 100;
2071                        while ((temp_value >>= 1))
2072                                temp_cnt++;
2073                        if (timeout > ((1 << temp_cnt) * 100))
2074                                temp_cnt++;
2075                        pbpctl_dev->bypass_wdt_on_time = jiffies;
2076                        pulse = (WDT_ON | temp_cnt);
2077                        if (pbpctl_dev->bp_ext_ver == OLD_IF_VER)
2078                                data_pulse(pbpctl_dev, pulse);
2079                        else
2080                                write_data(pbpctl_dev, pulse);
2081                        pbpctl_dev->bypass_timer_interval =
2082                            (1 << temp_cnt) * 100;
2083                }
2084                pbpctl_dev->wdt_status = WDT_STATUS_EN;
2085                return 0;
2086        }
2087        return BP_NOT_CAP;
2088}
2089
2090void bp75_put_hw_semaphore_generic(bpctl_dev_t *pbpctl_dev)
2091{
2092        u32 swsm;
2093
2094        swsm = BPCTL_READ_REG(pbpctl_dev, SWSM);
2095
2096        swsm &= ~(BPCTLI_SWSM_SMBI | BPCTLI_SWSM_SWESMBI);
2097
2098        BPCTL_WRITE_REG(pbpctl_dev, SWSM, swsm);
2099}
2100
2101s32 bp75_get_hw_semaphore_generic(bpctl_dev_t *pbpctl_dev)
2102{
2103        u32 swsm;
2104        s32 ret_val = 0;
2105        s32 timeout = 8192 + 1;
2106        s32 i = 0;
2107
2108        /* Get the SW semaphore */
2109        while (i < timeout) {
2110                swsm = BPCTL_READ_REG(pbpctl_dev, SWSM);
2111                if (!(swsm & BPCTLI_SWSM_SMBI))
2112                        break;
2113
2114                usec_delay(50);
2115                i++;
2116        }
2117
2118        if (i == timeout) {
2119                printk
2120                    ("bpctl_mod: Driver can't access device - SMBI bit is set.\n");
2121                ret_val = -1;
2122                goto out;
2123        }
2124
2125        /* Get the FW semaphore. */
2126        for (i = 0; i < timeout; i++) {
2127                swsm = BPCTL_READ_REG(pbpctl_dev, SWSM);
2128                BPCTL_WRITE_REG(pbpctl_dev, SWSM, swsm | BPCTLI_SWSM_SWESMBI);
2129
2130                /* Semaphore acquired if bit latched */
2131                if (BPCTL_READ_REG(pbpctl_dev, SWSM) & BPCTLI_SWSM_SWESMBI)
2132                        break;
2133
2134                usec_delay(50);
2135        }
2136
2137        if (i == timeout) {
2138                /* Release semaphores */
2139                bp75_put_hw_semaphore_generic(pbpctl_dev);
2140                printk("bpctl_mod: Driver can't access the NVM\n");
2141                ret_val = -1;
2142                goto out;
2143        }
2144
2145 out:
2146        return ret_val;
2147}
2148
2149static void bp75_release_phy(bpctl_dev_t *pbpctl_dev)
2150{
2151        u16 mask = BPCTLI_SWFW_PHY0_SM;
2152        u32 swfw_sync;
2153        s32 ret_val;
2154
2155        if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3))
2156                mask = BPCTLI_SWFW_PHY1_SM;
2157
2158        do
2159                ret_val = bp75_get_hw_semaphore_generic(pbpctl_dev);
2160        while (ret_val != 0);
2161
2162        swfw_sync = BPCTL_READ_REG(pbpctl_dev, SW_FW_SYNC);
2163        swfw_sync &= ~mask;
2164        BPCTL_WRITE_REG(pbpctl_dev, SW_FW_SYNC, swfw_sync);
2165
2166        bp75_put_hw_semaphore_generic(pbpctl_dev);
2167}
2168
2169static s32 bp75_acquire_phy(bpctl_dev_t *pbpctl_dev)
2170{
2171        u16 mask = BPCTLI_SWFW_PHY0_SM;
2172        u32 swfw_sync;
2173        u32 swmask;
2174        u32 fwmask;
2175        s32 ret_val = 0;
2176        s32 i = 0, timeout = 200;
2177
2178        if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3))
2179                mask = BPCTLI_SWFW_PHY1_SM;
2180
2181        swmask = mask;
2182        fwmask = mask << 16;
2183
2184        while (i < timeout) {
2185                if (bp75_get_hw_semaphore_generic(pbpctl_dev)) {
2186                        ret_val = -1;
2187                        goto out;
2188                }
2189
2190                swfw_sync = BPCTL_READ_REG(pbpctl_dev, SW_FW_SYNC);
2191                if (!(swfw_sync & (fwmask | swmask)))
2192                        break;
2193
2194                bp75_put_hw_semaphore_generic(pbpctl_dev);
2195                mdelay(5);
2196                i++;
2197        }
2198
2199        if (i == timeout) {
2200                printk
2201                    ("bpctl_mod: Driver can't access resource, SW_FW_SYNC timeout.\n");
2202                ret_val = -1;
2203                goto out;
2204        }
2205
2206        swfw_sync |= swmask;
2207        BPCTL_WRITE_REG(pbpctl_dev, SW_FW_SYNC, swfw_sync);
2208
2209        bp75_put_hw_semaphore_generic(pbpctl_dev);
2210
2211 out:
2212        return ret_val;
2213}
2214
2215s32 bp75_read_phy_reg_mdic(bpctl_dev_t *pbpctl_dev, u32 offset, u16 *data)
2216{
2217        u32 i, mdic = 0;
2218        s32 ret_val = 0;
2219        u32 phy_addr = 1;
2220
2221        mdic = ((offset << BPCTLI_MDIC_REG_SHIFT) |
2222                (phy_addr << BPCTLI_MDIC_PHY_SHIFT) | (BPCTLI_MDIC_OP_READ));
2223
2224        BPCTL_WRITE_REG(pbpctl_dev, MDIC, mdic);
2225
2226        for (i = 0; i < (BPCTLI_GEN_POLL_TIMEOUT * 3); i++) {
2227                usec_delay(50);
2228                mdic = BPCTL_READ_REG(pbpctl_dev, MDIC);
2229                if (mdic & BPCTLI_MDIC_READY)
2230                        break;
2231        }
2232        if (!(mdic & BPCTLI_MDIC_READY)) {
2233                printk("bpctl_mod: MDI Read did not complete\n");
2234                ret_val = -1;
2235                goto out;
2236        }
2237        if (mdic & BPCTLI_MDIC_ERROR) {
2238                printk("bpctl_mod: MDI Error\n");
2239                ret_val = -1;
2240                goto out;
2241        }
2242        *data = (u16) mdic;
2243
2244 out:
2245        return ret_val;
2246}
2247
2248s32 bp75_write_phy_reg_mdic(bpctl_dev_t *pbpctl_dev, u32 offset, u16 data)
2249{
2250        u32 i, mdic = 0;
2251        s32 ret_val = 0;
2252        u32 phy_addr = 1;
2253
2254        mdic = (((u32) data) |
2255                (offset << BPCTLI_MDIC_REG_SHIFT) |
2256                (phy_addr << BPCTLI_MDIC_PHY_SHIFT) | (BPCTLI_MDIC_OP_WRITE));
2257
2258        BPCTL_WRITE_REG(pbpctl_dev, MDIC, mdic);
2259
2260        for (i = 0; i < (BPCTLI_GEN_POLL_TIMEOUT * 3); i++) {
2261                usec_delay(50);
2262                mdic = BPCTL_READ_REG(pbpctl_dev, MDIC);
2263                if (mdic & BPCTLI_MDIC_READY)
2264                        break;
2265        }
2266        if (!(mdic & BPCTLI_MDIC_READY)) {
2267                printk("bpctl_mod: MDI Write did not complete\n");
2268                ret_val = -1;
2269                goto out;
2270        }
2271        if (mdic & BPCTLI_MDIC_ERROR) {
2272                printk("bpctl_mod: MDI Error\n");
2273                ret_val = -1;
2274                goto out;
2275        }
2276
2277 out:
2278        return ret_val;
2279}
2280
2281static s32 bp75_read_phy_reg(bpctl_dev_t *pbpctl_dev, u32 offset, u16 *data)
2282{
2283        s32 ret_val = 0;
2284
2285        ret_val = bp75_acquire_phy(pbpctl_dev);
2286        if (ret_val)
2287                goto out;
2288
2289        if (offset > BPCTLI_MAX_PHY_MULTI_PAGE_REG) {
2290                ret_val = bp75_write_phy_reg_mdic(pbpctl_dev,
2291                                                  BPCTLI_IGP01E1000_PHY_PAGE_SELECT,
2292                                                  (u16) offset);
2293                if (ret_val)
2294                        goto release;
2295        }
2296
2297        ret_val =
2298            bp75_read_phy_reg_mdic(pbpctl_dev,
2299                                   BPCTLI_MAX_PHY_REG_ADDRESS & offset, data);
2300
2301 release:
2302        bp75_release_phy(pbpctl_dev);
2303 out:
2304        return ret_val;
2305}
2306
2307static s32 bp75_write_phy_reg(bpctl_dev_t *pbpctl_dev, u32 offset, u16 data)
2308{
2309        s32 ret_val = 0;
2310
2311        ret_val = bp75_acquire_phy(pbpctl_dev);
2312        if (ret_val)
2313                goto out;
2314
2315        if (offset > BPCTLI_MAX_PHY_MULTI_PAGE_REG) {
2316                ret_val = bp75_write_phy_reg_mdic(pbpctl_dev,
2317                                                  BPCTLI_IGP01E1000_PHY_PAGE_SELECT,
2318                                                  (u16) offset);
2319                if (ret_val)
2320                        goto release;
2321        }
2322
2323        ret_val =
2324            bp75_write_phy_reg_mdic(pbpctl_dev,
2325                                    BPCTLI_MAX_PHY_REG_ADDRESS & offset, data);
2326
2327 release:
2328        bp75_release_phy(pbpctl_dev);
2329
2330 out:
2331        return ret_val;
2332}
2333
2334/* SET_TX  (non-Bypass command :)) */
2335static int set_tx(bpctl_dev_t *pbpctl_dev, int tx_state)
2336{
2337        int ret = 0, ctrl = 0;
2338        bpctl_dev_t *pbpctl_dev_m;
2339        if ((is_bypass_fn(pbpctl_dev)) == 1)
2340                pbpctl_dev_m = pbpctl_dev;
2341        else
2342                pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
2343        if (pbpctl_dev_m == NULL)
2344                return BP_NOT_CAP;
2345        if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
2346                ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
2347                if (!tx_state) {
2348                        if (pbpctl_dev->bp_540) {
2349                                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
2350                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
2351                                                (ctrl | BP10G_SDP1_DIR |
2352                                                 BP10G_SDP1_DATA));
2353
2354                        } else {
2355                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
2356                                                   (ctrl | BPCTLI_CTRL_SDP1_DIR
2357                                                    | BPCTLI_CTRL_SWDPIN1));
2358                        }
2359                } else {
2360                        if (pbpctl_dev->bp_540) {
2361                                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
2362                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
2363                                                ((ctrl | BP10G_SDP1_DIR) &
2364                                                 ~BP10G_SDP1_DATA));
2365                        } else {
2366                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
2367                                                   ((ctrl |
2368                                                     BPCTLI_CTRL_SDP1_DIR) &
2369                                                    ~BPCTLI_CTRL_SWDPIN1));
2370                        }
2371                        return ret;
2372
2373                }
2374        } else if (pbpctl_dev->bp_caps & TX_CTL_CAP) {
2375                if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) {
2376                        if (tx_state) {
2377                                uint16_t mii_reg;
2378                                if (!
2379                                    (ret =
2380                                     bp75_read_phy_reg(pbpctl_dev,
2381                                                       BPCTLI_PHY_CONTROL,
2382                                                       &mii_reg))) {
2383                                        if (mii_reg & BPCTLI_MII_CR_POWER_DOWN) {
2384                                                ret =
2385                                                    bp75_write_phy_reg
2386                                                    (pbpctl_dev,
2387                                                     BPCTLI_PHY_CONTROL,
2388                                                     mii_reg &
2389                                                     ~BPCTLI_MII_CR_POWER_DOWN);
2390                                        }
2391                                }
2392                        } else {
2393                                uint16_t mii_reg;
2394                                if (!
2395                                    (ret =
2396                                     bp75_read_phy_reg(pbpctl_dev,
2397                                                       BPCTLI_PHY_CONTROL,
2398                                                       &mii_reg))) {
2399
2400                                        mii_reg |= BPCTLI_MII_CR_POWER_DOWN;
2401                                        ret =
2402                                            bp75_write_phy_reg(pbpctl_dev,
2403                                                               BPCTLI_PHY_CONTROL,
2404                                                               mii_reg);
2405                                }
2406                        }
2407
2408                }
2409                if (pbpctl_dev->bp_fiber5)
2410                        ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
2411                else if (pbpctl_dev->bp_10gb)
2412                        ctrl = BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
2413                else if (!pbpctl_dev->bp_10g)
2414                        ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
2415                else
2416                        ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
2417
2418                if (!tx_state)
2419                        if (pbpctl_dev->bp_10g9) {
2420                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
2421                                                (ctrl | BP10G_SDP3_DATA |
2422                                                 BP10G_SDP3_DIR));
2423
2424                        } else if (pbpctl_dev->bp_fiber5) {
2425                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
2426                                                   (ctrl |
2427                                                    BPCTLI_CTRL_EXT_SDP6_DIR |
2428                                                    BPCTLI_CTRL_EXT_SDP6_DATA));
2429
2430                        } else if (pbpctl_dev->bp_10gb) {
2431                                if ((pbpctl_dev->func == 1)
2432                                    || (pbpctl_dev->func == 3))
2433                                        BP10GB_WRITE_REG(pbpctl_dev,
2434                                                         MISC_REG_GPIO,
2435                                                         (ctrl |
2436                                                          BP10GB_GPIO0_SET_P1) &
2437                                                         ~(BP10GB_GPIO0_CLR_P1 |
2438                                                           BP10GB_GPIO0_OE_P1));
2439                                else
2440                                        BP10GB_WRITE_REG(pbpctl_dev,
2441                                                         MISC_REG_GPIO,
2442                                                         (ctrl |
2443                                                          BP10GB_GPIO0_OE_P0 |
2444                                                          BP10GB_GPIO0_SET_P0));
2445
2446                        } else if (pbpctl_dev->bp_i80) {
2447                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
2448                                                   (ctrl | BPCTLI_CTRL_SDP1_DIR
2449                                                    | BPCTLI_CTRL_SWDPIN1));
2450
2451                        } else if (pbpctl_dev->bp_540) {
2452                                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
2453                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
2454                                                (ctrl | BP10G_SDP1_DIR |
2455                                                 BP10G_SDP1_DATA));
2456
2457                        }
2458
2459                        else if (!pbpctl_dev->bp_10g)
2460                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
2461                                                   (ctrl | BPCTLI_CTRL_SWDPIO0 |
2462                                                    BPCTLI_CTRL_SWDPIN0));
2463
2464                        else
2465                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
2466                                                (ctrl | BP10G_SDP0_DATA |
2467                                                 BP10G_SDP0_DIR));
2468
2469                else {
2470                        if (pbpctl_dev->bp_10g9) {
2471                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
2472                                                ((ctrl | BP10G_SDP3_DIR) &
2473                                                 ~BP10G_SDP3_DATA));
2474
2475                        } else if (pbpctl_dev->bp_fiber5) {
2476                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT,
2477                                                   ((ctrl |
2478                                                     BPCTLI_CTRL_EXT_SDP6_DIR) &
2479                                                    ~BPCTLI_CTRL_EXT_SDP6_DATA));
2480
2481                        } else if (pbpctl_dev->bp_10gb) {
2482                                if ((bpctl_dev_arr->func == 1)
2483                                    || (bpctl_dev_arr->func == 3))
2484                                        BP10GB_WRITE_REG(pbpctl_dev,
2485                                                         MISC_REG_GPIO,
2486                                                         (ctrl |
2487                                                          BP10GB_GPIO0_CLR_P1) &
2488                                                         ~(BP10GB_GPIO0_SET_P1 |
2489                                                           BP10GB_GPIO0_OE_P1));
2490                                else
2491                                        BP10GB_WRITE_REG(pbpctl_dev,
2492                                                         MISC_REG_GPIO,
2493                                                         (ctrl |
2494                                                          BP10GB_GPIO0_OE_P0 |
2495                                                          BP10GB_GPIO0_CLR_P0));
2496
2497                        } else if (pbpctl_dev->bp_i80) {
2498                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
2499                                                   ((ctrl |
2500                                                     BPCTLI_CTRL_SDP1_DIR) &
2501                                                    ~BPCTLI_CTRL_SWDPIN1));
2502                        } else if (pbpctl_dev->bp_540) {
2503                                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
2504                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
2505                                                ((ctrl | BP10G_SDP1_DIR) &
2506                                                 ~BP10G_SDP1_DATA));
2507                        }
2508
2509                        else if (!pbpctl_dev->bp_10g) {
2510                                BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
2511                                                   ((ctrl | BPCTLI_CTRL_SWDPIO0)
2512                                                    & ~BPCTLI_CTRL_SWDPIN0));
2513                                if (!PEGF_IF_SERIES(pbpctl_dev->subdevice)) {
2514                                        BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL,
2515                                                           (ctrl &
2516                                                            ~
2517                                                            (BPCTLI_CTRL_SDP0_DATA
2518                                                             |
2519                                                             BPCTLI_CTRL_SDP0_DIR)));
2520                                }
2521                        } else
2522                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
2523                                                ((ctrl | BP10G_SDP0_DIR) &
2524                                                 ~BP10G_SDP0_DATA));
2525
2526                }
2527
2528        } else
2529                ret = BP_NOT_CAP;
2530        return ret;
2531
2532}
2533
2534/* SET_FORCE_LINK  (non-Bypass command :)) */
2535static int set_bp_force_link(bpctl_dev_t *pbpctl_dev, int tx_state)
2536{
2537        int ret = 0, ctrl = 0;
2538
2539        if (DBI_IF_SERIES(pbpctl_dev->subdevice)) {
2540
2541                if ((pbpctl_dev->bp_10g) || (pbpctl_dev->bp_10g9)) {
2542
2543                        ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
2544                        if (!tx_state)
2545                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
2546                                                ctrl & ~BP10G_SDP1_DIR);
2547                        else
2548                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
2549                                                ((ctrl | BP10G_SDP1_DIR) &
2550                                                 ~BP10G_SDP1_DATA));
2551                        return ret;
2552                }
2553
2554        }
2555        return BP_NOT_CAP;
2556}
2557
2558/*RESET_CONT 0x20 */
2559int reset_cont(bpctl_dev_t *pbpctl_dev)
2560{
2561        int ret = BP_NOT_CAP;
2562
2563        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
2564                if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
2565                        return BP_NOT_CAP;
2566                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
2567                        write_data(pbpctl_dev, RESET_CONT);
2568                else
2569                        data_pulse(pbpctl_dev, RESET_CONT);
2570                ret = 0;
2571        };
2572        return ret;
2573}
2574
2575/*DIS_BYPASS_CAP 0x22 */
2576int dis_bypass_cap(bpctl_dev_t *pbpctl_dev)
2577{
2578
2579        if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
2580                if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
2581                        write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
2582                        msec_delay_bp(BYPASS_DELAY_INT);
2583                } else {
2584                        write_data(pbpctl_dev, BYPASS_OFF);
2585                        msec_delay_bp(LATCH_DELAY);
2586                        write_data(pbpctl_dev, DIS_BYPASS_CAP);
2587                        msec_delay_bp(BYPASS_CAP_DELAY);
2588                }
2589                return 0;
2590        }
2591        return BP_NOT_CAP;
2592}
2593
2594/*EN_BYPASS_CAP 0x24 */
2595int en_bypass_cap(bpctl_dev_t *pbpctl_dev)
2596{
2597        if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
2598                if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
2599                        write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT);
2600                        msec_delay_bp(BYPASS_DELAY_INT);
2601                } else {
2602                        write_data(pbpctl_dev, EN_BYPASS_CAP);
2603                        msec_delay_bp(BYPASS_CAP_DELAY);
2604                }
2605                return 0;
2606        }
2607        return BP_NOT_CAP;
2608}
2609
2610/* BYPASS_STATE_PWRON 0x26*/
2611int bypass_state_pwron(bpctl_dev_t *pbpctl_dev)
2612{
2613        if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) {
2614                write_data(pbpctl_dev, BYPASS_STATE_PWRON);
2615                if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
2616                        msec_delay_bp(DFLT_PWRON_DELAY);
2617                else
2618                        msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
2619                return 0;
2620        }
2621        return BP_NOT_CAP;
2622}
2623
2624/* NORMAL_STATE_PWRON 0x28*/
2625int normal_state_pwron(bpctl_dev_t *pbpctl_dev)
2626{
2627        if ((pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP)
2628            || (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP)) {
2629                write_data(pbpctl_dev, NORMAL_STATE_PWRON);
2630                if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
2631                        msec_delay_bp(DFLT_PWRON_DELAY);
2632                else
2633                        msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
2634                return 0;
2635        }
2636        return BP_NOT_CAP;
2637}
2638
2639/* BYPASS_STATE_PWROFF 0x27*/
2640int bypass_state_pwroff(bpctl_dev_t *pbpctl_dev)
2641{
2642        if (pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP) {
2643                write_data(pbpctl_dev, BYPASS_STATE_PWROFF);
2644                msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
2645                return 0;
2646        }
2647        return BP_NOT_CAP;
2648}
2649
2650/* NORMAL_STATE_PWROFF 0x29*/
2651int normal_state_pwroff(bpctl_dev_t *pbpctl_dev)
2652{
2653        if ((pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) {
2654                write_data(pbpctl_dev, NORMAL_STATE_PWROFF);
2655                msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
2656                return 0;
2657        }
2658        return BP_NOT_CAP;
2659}
2660
2661/*TAP_STATE_PWRON 0x2a*/
2662int tap_state_pwron(bpctl_dev_t *pbpctl_dev)
2663{
2664        if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) {
2665                write_data(pbpctl_dev, TAP_STATE_PWRON);
2666                msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
2667                return 0;
2668        }
2669        return BP_NOT_CAP;
2670}
2671
2672/*DIS_TAP_CAP 0x2c*/
2673int dis_tap_cap(bpctl_dev_t *pbpctl_dev)
2674{
2675        if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
2676                write_data(pbpctl_dev, DIS_TAP_CAP);
2677                msec_delay_bp(BYPASS_CAP_DELAY);
2678                return 0;
2679        }
2680        return BP_NOT_CAP;
2681}
2682
2683/*EN_TAP_CAP 0x2e*/
2684int en_tap_cap(bpctl_dev_t *pbpctl_dev)
2685{
2686        if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
2687                write_data(pbpctl_dev, EN_TAP_CAP);
2688                msec_delay_bp(BYPASS_CAP_DELAY);
2689                return 0;
2690        }
2691        return BP_NOT_CAP;
2692}
2693
2694/*DISC_STATE_PWRON 0x2a*/
2695int disc_state_pwron(bpctl_dev_t *pbpctl_dev)
2696{
2697        if (pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) {
2698                if (pbpctl_dev->bp_ext_ver >= 0x8) {
2699                        write_data(pbpctl_dev, DISC_STATE_PWRON);
2700                        msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
2701                        return BP_OK;
2702                }
2703        }
2704        return BP_NOT_CAP;
2705}
2706
2707/*DIS_DISC_CAP 0x2c*/
2708int dis_disc_cap(bpctl_dev_t *pbpctl_dev)
2709{
2710        if (pbpctl_dev->bp_caps & DISC_DIS_CAP) {
2711                if (pbpctl_dev->bp_ext_ver >= 0x8) {
2712                        write_data(pbpctl_dev, DIS_DISC_CAP);
2713                        msec_delay_bp(BYPASS_CAP_DELAY);
2714                        return BP_OK;
2715                }
2716        }
2717        return BP_NOT_CAP;
2718}
2719
2720/*DISC_STATE_PWRON 0x2a*/
2721int disc_port_state_pwron(bpctl_dev_t *pbpctl_dev)
2722{
2723        int ret = 0;
2724        bpctl_dev_t *pbpctl_dev_m;
2725
2726        return BP_NOT_CAP;
2727
2728        if ((is_bypass_fn(pbpctl_dev)) == 1)
2729                pbpctl_dev_m = pbpctl_dev;
2730        else
2731                pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
2732        if (pbpctl_dev_m == NULL)
2733                return BP_NOT_CAP;
2734
2735        if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
2736                if (is_bypass_fn(pbpctl_dev) == 1)
2737                        write_data(pbpctl_dev_m, TX_DISA_PWRUP);
2738                else
2739                        write_data(pbpctl_dev_m, TX_DISB_PWRUP);
2740
2741                msec_delay_bp(LATCH_DELAY);
2742
2743        }
2744        return ret;
2745}
2746
2747int normal_port_state_pwron(bpctl_dev_t *pbpctl_dev)
2748{
2749        int ret = 0;
2750        bpctl_dev_t *pbpctl_dev_m;
2751        return BP_NOT_CAP;
2752
2753        if ((is_bypass_fn(pbpctl_dev)) == 1)
2754                pbpctl_dev_m = pbpctl_dev;
2755        else
2756                pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
2757        if (pbpctl_dev_m == NULL)
2758                return BP_NOT_CAP;
2759
2760        if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
2761                if (is_bypass_fn(pbpctl_dev) == 1)
2762                        write_data(pbpctl_dev_m, TX_ENA_PWRUP);
2763                else
2764                        write_data(pbpctl_dev_m, TX_ENB_PWRUP);
2765
2766                msec_delay_bp(LATCH_DELAY);
2767
2768        }
2769        return ret;
2770}
2771
2772/*EN_TAP_CAP 0x2e*/
2773int en_disc_cap(bpctl_dev_t *pbpctl_dev)
2774{
2775        if (pbpctl_dev->bp_caps & DISC_DIS_CAP) {
2776                if (pbpctl_dev->bp_ext_ver >= 0x8) {
2777                        write_data(pbpctl_dev, EN_DISC_CAP);
2778                        msec_delay_bp(BYPASS_CAP_DELAY);
2779                        return BP_OK;
2780                }
2781        }
2782        return BP_NOT_CAP;
2783}
2784
2785int std_nic_on(bpctl_dev_t *pbpctl_dev)
2786{
2787
2788        if (pbpctl_dev->bp_caps & STD_NIC_CAP) {
2789
2790                if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
2791                        write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT);
2792                        msec_delay_bp(BYPASS_DELAY_INT);
2793                        pbpctl_dev->bp_status_un = 0;
2794                        return BP_OK;
2795                }
2796
2797                if (pbpctl_dev->bp_ext_ver >= 0x8) {
2798                        write_data(pbpctl_dev, STD_NIC_ON);
2799                        msec_delay_bp(BYPASS_CAP_DELAY);
2800                        return BP_OK;
2801
2802                }
2803
2804                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
2805                        wdt_off(pbpctl_dev);
2806
2807                        if (pbpctl_dev->bp_caps & BP_CAP) {
2808                                write_data(pbpctl_dev, BYPASS_OFF);
2809                                msec_delay_bp(LATCH_DELAY);
2810                        }
2811
2812                        if (pbpctl_dev->bp_caps & TAP_CAP) {
2813                                write_data(pbpctl_dev, TAP_OFF);
2814                                msec_delay_bp(LATCH_DELAY);
2815                        }
2816
2817                        write_data(pbpctl_dev, NORMAL_STATE_PWRON);
2818                        if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
2819                                msec_delay_bp(DFLT_PWRON_DELAY);
2820                        else
2821                                msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
2822
2823                        if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
2824                                write_data(pbpctl_dev, DIS_BYPASS_CAP);
2825                                msec_delay_bp(BYPASS_CAP_DELAY);
2826                        }
2827
2828                        if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
2829                                write_data(pbpctl_dev, DIS_TAP_CAP);
2830                                msec_delay_bp(BYPASS_CAP_DELAY);
2831
2832                        }
2833                        return 0;
2834                }
2835        }
2836        return BP_NOT_CAP;
2837}
2838
2839int std_nic_off(bpctl_dev_t *pbpctl_dev)
2840{
2841
2842        if (pbpctl_dev->bp_caps & STD_NIC_CAP) {
2843                if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
2844                        write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT);
2845                        msec_delay_bp(BYPASS_DELAY_INT);
2846                        return BP_OK;
2847                }
2848                if (pbpctl_dev->bp_ext_ver >= 0x8) {
2849                        write_data(pbpctl_dev, STD_NIC_OFF);
2850                        msec_delay_bp(BYPASS_CAP_DELAY);
2851                        return BP_OK;
2852
2853                }
2854
2855                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
2856
2857                        if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) {
2858                                write_data(pbpctl_dev, TAP_STATE_PWRON);
2859                                msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
2860                        }
2861
2862                        if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) {
2863                                write_data(pbpctl_dev, BYPASS_STATE_PWRON);
2864                                if (pbpctl_dev->bp_ext_ver > PXG2BPI_VER)
2865                                        msec_delay_bp(LATCH_DELAY +
2866                                                      EEPROM_WR_DELAY);
2867                                else
2868                                        msec_delay_bp(DFLT_PWRON_DELAY);
2869                        }
2870
2871                        if (pbpctl_dev->bp_caps & TAP_DIS_CAP) {
2872                                write_data(pbpctl_dev, EN_TAP_CAP);
2873                                msec_delay_bp(BYPASS_CAP_DELAY);
2874                        }
2875                        if (pbpctl_dev->bp_caps & DISC_DIS_CAP) {
2876                                write_data(pbpctl_dev, EN_DISC_CAP);
2877                                msec_delay_bp(BYPASS_CAP_DELAY);
2878                        }
2879
2880                        if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
2881                                write_data(pbpctl_dev, EN_BYPASS_CAP);
2882                                msec_delay_bp(BYPASS_CAP_DELAY);
2883                        }
2884
2885                        return 0;
2886                }
2887        }
2888        return BP_NOT_CAP;
2889}
2890
2891int wdt_time_left(bpctl_dev_t *pbpctl_dev)
2892{
2893
2894        /* 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; */
2895        unsigned long curr_time = jiffies, delta_time = 0, wdt_on_time =
2896            pbpctl_dev->bypass_wdt_on_time, delta_time_msec = 0;
2897        int time_left = 0;
2898
2899        switch (pbpctl_dev->wdt_status) {
2900        case WDT_STATUS_DIS:
2901                time_left = 0;
2902                break;
2903        case WDT_STATUS_EN:
2904                delta_time =
2905                    (curr_time >=
2906                     wdt_on_time) ? (curr_time - wdt_on_time) : (~wdt_on_time +
2907                                                                 curr_time);
2908                delta_time_msec = jiffies_to_msecs(delta_time);
2909                time_left = pbpctl_dev->bypass_timer_interval - delta_time_msec;
2910                if (time_left < 0) {
2911                        time_left = -1;
2912                        pbpctl_dev->wdt_status = WDT_STATUS_EXP;
2913                }
2914                break;
2915        case WDT_STATUS_EXP:
2916                time_left = -1;
2917                break;
2918        }
2919
2920        return time_left;
2921}
2922
2923static int wdt_timer(bpctl_dev_t *pbpctl_dev, int *time_left)
2924{
2925        int ret = 0;
2926        if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
2927                {
2928                        if (pbpctl_dev->wdt_status == WDT_STATUS_UNKNOWN)
2929                                ret = BP_NOT_CAP;
2930                        else
2931                                *time_left = wdt_time_left(pbpctl_dev);
2932                }
2933
2934        } else
2935                ret = BP_NOT_CAP;
2936        return ret;
2937}
2938
2939static int wdt_timer_reload(bpctl_dev_t *pbpctl_dev)
2940{
2941
2942        int ret = 0;
2943
2944        if ((pbpctl_dev->bp_caps & WD_CTL_CAP) &&
2945            (pbpctl_dev->wdt_status != WDT_STATUS_UNKNOWN)) {
2946                if (pbpctl_dev->wdt_status == WDT_STATUS_DIS)
2947                        return 0;
2948                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
2949                        ret = wdt_pulse(pbpctl_dev);
2950                else if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
2951                        ret = wdt_pulse_int(pbpctl_dev);
2952                else
2953                        ret = send_wdt_pulse(pbpctl_dev);
2954                /* if (ret==-1)
2955                    mod_timer(&pbpctl_dev->bp_timer, jiffies+1);*/
2956                return 1;
2957        }
2958        return BP_NOT_CAP;
2959}
2960
2961static void wd_reset_timer(unsigned long param)
2962{
2963        bpctl_dev_t *pbpctl_dev = (bpctl_dev_t *) param;
2964#ifdef BP_SELF_TEST
2965        struct sk_buff *skb_tmp;
2966#endif
2967
2968        if ((pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) &&
2969            ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)) {
2970                mod_timer(&pbpctl_dev->bp_timer, jiffies + 1);
2971                return;
2972        }
2973#ifdef BP_SELF_TEST
2974
2975        if (pbpctl_dev->bp_self_test_flag == 1) {
2976                skb_tmp = dev_alloc_skb(BPTEST_DATA_LEN + 2);
2977                if ((skb_tmp) && (pbpctl_dev->ndev) && (pbpctl_dev->bp_tx_data)) {
2978                        memcpy(skb_put(skb_tmp, BPTEST_DATA_LEN),
2979                               pbpctl_dev->bp_tx_data, BPTEST_DATA_LEN);
2980                        skb_tmp->dev = pbpctl_dev->ndev;
2981                        skb_tmp->protocol =
2982                            eth_type_trans(skb_tmp, pbpctl_dev->ndev);
2983                        skb_tmp->ip_summed = CHECKSUM_UNNECESSARY;
2984                        netif_receive_skb(skb_tmp);
2985                        goto bp_timer_reload;
2986                        return;
2987                }
2988        }
2989#endif
2990
2991        wdt_timer_reload(pbpctl_dev);
2992#ifdef BP_SELF_TEST
2993 bp_timer_reload:
2994#endif
2995        if (pbpctl_dev->reset_time) {
2996                mod_timer(&pbpctl_dev->bp_timer,
2997                          jiffies + (HZ * pbpctl_dev->reset_time) / 1000);
2998        }
2999}
3000
3001/*WAIT_AT_PWRUP 0x80   */
3002int bp_wait_at_pwup_en(bpctl_dev_t *pbpctl_dev)
3003{
3004
3005        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3006                if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
3007                        write_data(pbpctl_dev, BP_WAIT_AT_PWUP_EN);
3008                        msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
3009
3010                        return BP_OK;
3011                }
3012        }
3013        return BP_NOT_CAP;
3014}
3015
3016/*DIS_WAIT_AT_PWRUP       0x81 */
3017int bp_wait_at_pwup_dis(bpctl_dev_t *pbpctl_dev)
3018{
3019
3020        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3021
3022                if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
3023                        write_data(pbpctl_dev, BP_WAIT_AT_PWUP_DIS);
3024                        msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
3025
3026                        return BP_OK;
3027                }
3028        }
3029        return BP_NOT_CAP;
3030}
3031
3032/*EN_HW_RESET  0x82   */
3033
3034int bp_hw_reset_en(bpctl_dev_t *pbpctl_dev)
3035{
3036
3037        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3038                if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
3039                        write_data(pbpctl_dev, BP_HW_RESET_EN);
3040                        msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
3041
3042                        return BP_OK;
3043                }
3044        }
3045        return BP_NOT_CAP;
3046}
3047
3048/*DIS_HW_RESET             0x83   */
3049
3050int bp_hw_reset_dis(bpctl_dev_t *pbpctl_dev)
3051{
3052
3053        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3054                if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
3055                        write_data(pbpctl_dev, BP_HW_RESET_DIS);
3056                        msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY);
3057
3058                        return BP_OK;
3059                }
3060        }
3061        return BP_NOT_CAP;
3062}
3063
3064
3065int wdt_exp_mode(bpctl_dev_t *pbpctl_dev, int mode)
3066{
3067        uint32_t status_reg = 0, status_reg1 = 0;
3068
3069        if ((pbpctl_dev->bp_caps & (TAP_STATUS_CAP | DISC_CAP)) &&
3070            (pbpctl_dev->bp_caps & BP_CAP)) {
3071                if (pbpctl_dev->bp_ext_ver >= PXE2TBPI_VER) {
3072
3073                        if ((pbpctl_dev->bp_ext_ver >= 0x8) &&
3074                            (mode == 2) && (pbpctl_dev->bp_caps & DISC_CAP)) {
3075                                status_reg1 =
3076                                    read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR);
3077                                if (!(status_reg1 & WDTE_DISC_BPN_MASK))
3078                                        write_reg(pbpctl_dev,
3079                                                  status_reg1 |
3080                                                  WDTE_DISC_BPN_MASK,
3081                                                  STATUS_DISC_REG_ADDR);
3082                                return BP_OK;
3083                        }
3084                }
3085                status_reg = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
3086
3087                if ((mode == 0) && (pbpctl_dev->bp_caps & BP_CAP)) {
3088                        if (pbpctl_dev->bp_ext_ver >= 0x8) {
3089                                status_reg1 =
3090                                    read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR);
3091                                if (status_reg1 & WDTE_DISC_BPN_MASK)
3092                                        write_reg(pbpctl_dev,
3093                                                  status_reg1 &
3094                                                  ~WDTE_DISC_BPN_MASK,
3095                                                  STATUS_DISC_REG_ADDR);
3096                        }
3097                        if (status_reg & WDTE_TAP_BPN_MASK)
3098                                write_reg(pbpctl_dev,
3099                                          status_reg & ~WDTE_TAP_BPN_MASK,
3100                                          STATUS_TAP_REG_ADDR);
3101                        return BP_OK;
3102
3103                } else if ((mode == 1) && (pbpctl_dev->bp_caps & TAP_CAP)) {
3104                        if (!(status_reg & WDTE_TAP_BPN_MASK))
3105                                write_reg(pbpctl_dev,
3106                                          status_reg | WDTE_TAP_BPN_MASK,
3107                                          STATUS_TAP_REG_ADDR);
3108                        /*else return BP_NOT_CAP; */
3109                        return BP_OK;
3110                }
3111
3112        }
3113        return BP_NOT_CAP;
3114}
3115
3116int bypass_fw_ver(bpctl_dev_t *pbpctl_dev)
3117{
3118        if (is_bypass_fn(pbpctl_dev))
3119                return read_reg(pbpctl_dev, VER_REG_ADDR);
3120        else
3121                return BP_NOT_CAP;
3122}
3123
3124int bypass_sign_check(bpctl_dev_t *pbpctl_dev)
3125{
3126
3127        if (is_bypass_fn(pbpctl_dev))
3128                return (((read_reg(pbpctl_dev, PIC_SIGN_REG_ADDR)) ==
3129                         PIC_SIGN_VALUE) ? 1 : 0);
3130        else
3131                return BP_NOT_CAP;
3132}
3133
3134static int tx_status(bpctl_dev_t *pbpctl_dev)
3135{
3136        uint32_t ctrl = 0;
3137        bpctl_dev_t *pbpctl_dev_m;
3138        if ((is_bypass_fn(pbpctl_dev)) == 1)
3139                pbpctl_dev_m = pbpctl_dev;
3140        else
3141                pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
3142        if (pbpctl_dev_m == NULL)
3143                return BP_NOT_CAP;
3144        if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
3145
3146                ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
3147                if (pbpctl_dev->bp_i80)
3148                        return ((ctrl & BPCTLI_CTRL_SWDPIN1) != 0 ? 0 : 1);
3149                if (pbpctl_dev->bp_540) {
3150                        ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
3151
3152                        return ((ctrl & BP10G_SDP1_DATA) != 0 ? 0 : 1);
3153                }
3154
3155        }
3156
3157        if (pbpctl_dev->bp_caps & TX_CTL_CAP) {
3158                if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) {
3159                        uint16_t mii_reg;
3160                        if (!
3161                            (bp75_read_phy_reg
3162                             (pbpctl_dev, BPCTLI_PHY_CONTROL, &mii_reg))) {
3163                                if (mii_reg & BPCTLI_MII_CR_POWER_DOWN)
3164                                        return 0;
3165
3166                                else
3167                                        return 1;
3168                        }
3169                        return -1;
3170                }
3171
3172                if (pbpctl_dev->bp_10g9) {
3173                        return ((BP10G_READ_REG(pbpctl_dev, ESDP) &
3174                                 BP10G_SDP3_DATA) != 0 ? 0 : 1);
3175
3176                } else if (pbpctl_dev->bp_fiber5) {
3177                        ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
3178                        if (ctrl & BPCTLI_CTRL_EXT_SDP6_DATA)
3179                                return 0;
3180                        return 1;
3181                } else if (pbpctl_dev->bp_10gb) {
3182                        ctrl = BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
3183                        BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO,
3184                                         (ctrl | BP10GB_GPIO0_OE_P1) &
3185                                         ~(BP10GB_GPIO0_SET_P1 |
3186                                           BP10GB_GPIO0_CLR_P1));
3187
3188                        if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3))
3189                                return (((BP10GB_READ_REG
3190                                          (pbpctl_dev,
3191                                           MISC_REG_GPIO)) & BP10GB_GPIO0_P1) !=
3192                                        0 ? 0 : 1);
3193                        else
3194                                return (((BP10GB_READ_REG
3195                                          (pbpctl_dev,
3196                                           MISC_REG_GPIO)) & BP10GB_GPIO0_P0) !=
3197                                        0 ? 0 : 1);
3198                }
3199
3200                if (!pbpctl_dev->bp_10g) {
3201
3202                        ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
3203                        if (pbpctl_dev->bp_i80)
3204                                return ((ctrl & BPCTLI_CTRL_SWDPIN1) !=
3205                                        0 ? 0 : 1);
3206                        if (pbpctl_dev->bp_540) {
3207                                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
3208
3209                                return ((ctrl & BP10G_SDP1_DATA) != 0 ? 0 : 1);
3210                        }
3211
3212                        return ((ctrl & BPCTLI_CTRL_SWDPIN0) != 0 ? 0 : 1);
3213                } else
3214                        return ((BP10G_READ_REG(pbpctl_dev, ESDP) &
3215                                 BP10G_SDP0_DATA) != 0 ? 0 : 1);
3216
3217        }
3218        return BP_NOT_CAP;
3219}
3220
3221static int bp_force_link_status(bpctl_dev_t *pbpctl_dev)
3222{
3223
3224        if (DBI_IF_SERIES(pbpctl_dev->subdevice)) {
3225
3226                if ((pbpctl_dev->bp_10g) || (pbpctl_dev->bp_10g9)) {
3227                        return ((BP10G_READ_REG(pbpctl_dev, ESDP) &
3228                                 BP10G_SDP1_DIR) != 0 ? 1 : 0);
3229
3230                }
3231        }
3232        return BP_NOT_CAP;
3233}
3234
3235int bypass_from_last_read(bpctl_dev_t *pbpctl_dev)
3236{
3237        uint32_t ctrl_ext = 0;
3238        bpctl_dev_t *pbpctl_dev_b = NULL;
3239
3240        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3241                pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
3242                if (!pbpctl_dev_b)
3243                        return BP_NOT_CAP;
3244                ctrl_ext = BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT);
3245                BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL_EXT,
3246                                   (ctrl_ext & ~BPCTLI_CTRL_EXT_SDP7_DIR));
3247                ctrl_ext = BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT);
3248                if (ctrl_ext & BPCTLI_CTRL_EXT_SDP7_DATA)
3249                        return 0;
3250                return 1;
3251        } else
3252                return BP_NOT_CAP;
3253}
3254
3255int bypass_status_clear(bpctl_dev_t *pbpctl_dev)
3256{
3257        bpctl_dev_t *pbpctl_dev_b = NULL;
3258
3259        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3260                pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
3261                if (!pbpctl_dev_b)
3262                        return BP_NOT_CAP;
3263                send_bypass_clear_pulse(pbpctl_dev_b, 1);
3264                return 0;
3265        } else
3266                return BP_NOT_CAP;
3267}
3268
3269int bypass_flag_status(bpctl_dev_t *pbpctl_dev)
3270{
3271
3272        if ((pbpctl_dev->bp_caps & BP_CAP)) {
3273                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
3274                        return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
3275                                  BYPASS_FLAG_MASK) ==
3276                                 BYPASS_FLAG_MASK) ? 1 : 0);
3277                }
3278        }
3279        return BP_NOT_CAP;
3280}
3281
3282int bypass_flag_status_clear(bpctl_dev_t *pbpctl_dev)
3283{
3284
3285        if (pbpctl_dev->bp_caps & BP_CAP) {
3286                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
3287                        uint32_t status_reg = 0;
3288                        status_reg = read_reg(pbpctl_dev, STATUS_REG_ADDR);
3289                        write_reg(pbpctl_dev, status_reg & ~BYPASS_FLAG_MASK,
3290                                  STATUS_REG_ADDR);
3291                        return 0;
3292                }
3293        }
3294        return BP_NOT_CAP;
3295}
3296
3297int bypass_change_status(bpctl_dev_t *pbpctl_dev)
3298{
3299        int ret = BP_NOT_CAP;
3300
3301        if (pbpctl_dev->bp_caps & BP_STATUS_CHANGE_CAP) {
3302                if (pbpctl_dev->bp_ext_ver >= 0x8) {
3303                        ret = bypass_flag_status(pbpctl_dev);
3304                        bypass_flag_status_clear(pbpctl_dev);
3305                } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
3306                        ret = bypass_flag_status(pbpctl_dev);
3307                        bypass_flag_status_clear(pbpctl_dev);
3308                } else {
3309                        ret = bypass_from_last_read(pbpctl_dev);
3310                        bypass_status_clear(pbpctl_dev);
3311                }
3312        }
3313        return ret;
3314}
3315
3316int bypass_off_status(bpctl_dev_t *pbpctl_dev)
3317{
3318
3319        if (pbpctl_dev->bp_caps & BP_CAP) {
3320                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
3321                        return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
3322                                  BYPASS_OFF_MASK) == BYPASS_OFF_MASK) ? 1 : 0);
3323                }
3324        }
3325        return BP_NOT_CAP;
3326}
3327
3328static int bypass_status(bpctl_dev_t *pbpctl_dev)
3329{
3330        u32 ctrl_ext = 0;
3331        if (pbpctl_dev->bp_caps & BP_CAP) {
3332
3333                bpctl_dev_t *pbpctl_dev_b = NULL;
3334
3335                pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
3336                if (!pbpctl_dev_b)
3337                        return BP_NOT_CAP;
3338
3339                if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
3340
3341                        if (!pbpctl_dev->bp_status_un)
3342                                return (((BPCTL_READ_REG
3343                                          (pbpctl_dev_b,
3344                                           CTRL_EXT)) &
3345                                         BPCTLI_CTRL_EXT_SDP7_DATA) !=
3346                                        0 ? 1 : 0);
3347                        else
3348                                return BP_NOT_CAP;
3349                }
3350                if (pbpctl_dev->bp_ext_ver >= 0x8) {
3351
3352                        if (pbpctl_dev->bp_10g9) {
3353                                ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL);
3354                                BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL,
3355                                                (ctrl_ext | BP10G_I2C_CLK_OUT));
3356                                return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) &
3357                                         BP10G_I2C_CLK_IN) != 0 ? 0 : 1);
3358
3359                        } else if (pbpctl_dev->bp_540) {
3360                                return (((BP10G_READ_REG(pbpctl_dev_b, ESDP)) &
3361                                         BP10G_SDP0_DATA) != 0 ? 0 : 1);
3362                        }
3363
3364                        else if ((pbpctl_dev->bp_fiber5)
3365                                 || (pbpctl_dev->bp_i80)) {
3366                                return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
3367                                         BPCTLI_CTRL_SWDPIN0) != 0 ? 0 : 1);
3368                        } else if (pbpctl_dev->bp_10gb) {
3369                                ctrl_ext =
3370                                    BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
3371                                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO,
3372                                                 (ctrl_ext | BP10GB_GPIO3_OE_P0)
3373                                                 & ~(BP10GB_GPIO3_SET_P0 |
3374                                                     BP10GB_GPIO3_CLR_P0));
3375
3376                                return (((BP10GB_READ_REG
3377                                          (pbpctl_dev,
3378                                           MISC_REG_GPIO)) & BP10GB_GPIO3_P0) !=
3379                                        0 ? 0 : 1);
3380                        }
3381
3382                        else if (!pbpctl_dev->bp_10g)
3383                                return (((BPCTL_READ_REG
3384                                          (pbpctl_dev_b,
3385                                           CTRL_EXT)) &
3386                                         BPCTLI_CTRL_EXT_SDP7_DATA) !=
3387                                        0 ? 0 : 1);
3388
3389                        else {
3390                                ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP);
3391                                BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
3392                                                (ctrl_ext |
3393                                                 BP10G_SDP7_DATA_OUT));
3394                                return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) &
3395                                         BP10G_SDP7_DATA_IN) != 0 ? 0 : 1);
3396                        }
3397
3398                } else if (pbpctl_dev->media_type == BP_COPPER) {
3399
3400                        return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
3401                                 BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0);
3402                } else {
3403                        if ((bypass_status_clear(pbpctl_dev)) >= 0)
3404                                return bypass_from_last_read(pbpctl_dev);
3405                }
3406
3407        }
3408        return BP_NOT_CAP;
3409}
3410
3411int default_pwron_status(bpctl_dev_t *pbpctl_dev)
3412{
3413
3414        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3415                if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) {
3416                        if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
3417                                return ((((read_reg
3418                                           (pbpctl_dev,
3419                                            STATUS_REG_ADDR)) & DFLT_PWRON_MASK)
3420                                         == DFLT_PWRON_MASK) ? 0 : 1);
3421                        }
3422                }               /*else if ((!pbpctl_dev->bp_caps&BP_DIS_CAP)&&
3423                                   (pbpctl_dev->bp_caps&BP_PWUP_ON_CAP))
3424                                   return 1; */
3425        }
3426        return BP_NOT_CAP;
3427}
3428
3429static int default_pwroff_status(bpctl_dev_t *pbpctl_dev)
3430{
3431
3432        /*if ((!pbpctl_dev->bp_caps&BP_DIS_CAP)&&
3433           (pbpctl_dev->bp_caps&BP_PWOFF_ON_CAP))
3434           return 1; */
3435        if ((pbpctl_dev->bp_caps & SW_CTL_CAP)
3436            && (pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) {
3437                return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
3438                          DFLT_PWROFF_MASK) == DFLT_PWROFF_MASK) ? 0 : 1);
3439        }
3440        return BP_NOT_CAP;
3441}
3442
3443int dis_bypass_cap_status(bpctl_dev_t *pbpctl_dev)
3444{
3445
3446        if (pbpctl_dev->bp_caps & BP_DIS_CAP) {
3447                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
3448                        return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
3449                                  DIS_BYPASS_CAP_MASK) ==
3450                                 DIS_BYPASS_CAP_MASK) ? 1 : 0);
3451                }
3452        }
3453        return BP_NOT_CAP;
3454}
3455
3456int cmd_en_status(bpctl_dev_t *pbpctl_dev)
3457{
3458
3459        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3460                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
3461                        return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
3462                                  CMND_EN_MASK) == CMND_EN_MASK) ? 1 : 0);
3463                }
3464        }
3465        return BP_NOT_CAP;
3466}
3467
3468int wdt_en_status(bpctl_dev_t *pbpctl_dev)
3469{
3470
3471        if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
3472                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
3473                        return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
3474                                  WDT_EN_MASK) == WDT_EN_MASK) ? 1 : 0);
3475                }
3476        }
3477        return BP_NOT_CAP;
3478}
3479
3480int wdt_programmed(bpctl_dev_t *pbpctl_dev, int *timeout)
3481{
3482        int ret = 0;
3483        if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
3484                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
3485                        if ((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
3486                            WDT_EN_MASK) {
3487                                u8 wdt_val;
3488                                wdt_val = read_reg(pbpctl_dev, WDT_REG_ADDR);
3489                                *timeout = (1 << wdt_val) * 100;
3490                        } else
3491                                *timeout = 0;
3492                } else {
3493                        int curr_wdt_status = pbpctl_dev->wdt_status;
3494                        if (curr_wdt_status == WDT_STATUS_UNKNOWN)
3495                                *timeout = -1;
3496                        else
3497                                *timeout =
3498                                    curr_wdt_status ==
3499                                    0 ? 0 : pbpctl_dev->bypass_timer_interval;
3500                };
3501        } else
3502                ret = BP_NOT_CAP;
3503        return ret;
3504}
3505
3506int bypass_support(bpctl_dev_t *pbpctl_dev)
3507{
3508        int ret = 0;
3509
3510        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3511                if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
3512                        ret =
3513                            ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) &
3514                               BYPASS_SUPPORT_MASK) ==
3515                              BYPASS_SUPPORT_MASK) ? 1 : 0);
3516                } else if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
3517                        ret = 1;
3518        } else
3519                ret = BP_NOT_CAP;
3520        return ret;
3521}
3522
3523int tap_support(bpctl_dev_t *pbpctl_dev)
3524{
3525        int ret = 0;
3526
3527        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3528                if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
3529                        ret =
3530                            ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) &
3531                               TAP_SUPPORT_MASK) == TAP_SUPPORT_MASK) ? 1 : 0);
3532                } else if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
3533                        ret = 0;
3534        } else
3535                ret = BP_NOT_CAP;
3536        return ret;
3537}
3538
3539int normal_support(bpctl_dev_t *pbpctl_dev)
3540{
3541        int ret = BP_NOT_CAP;
3542
3543        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3544                if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
3545                        ret =
3546                            ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) &
3547                               NORMAL_UNSUPPORT_MASK) ==
3548                              NORMAL_UNSUPPORT_MASK) ? 0 : 1);
3549                } else
3550                        ret = 1;
3551        };
3552        return ret;
3553}
3554
3555int get_bp_prod_caps(bpctl_dev_t *pbpctl_dev)
3556{
3557        if ((pbpctl_dev->bp_caps & SW_CTL_CAP) &&
3558            (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER))
3559                return read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR);
3560        return BP_NOT_CAP;
3561
3562}
3563
3564int tap_flag_status(bpctl_dev_t *pbpctl_dev)
3565{
3566
3567        if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) {
3568                if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
3569                        return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
3570                                  TAP_FLAG_MASK) == TAP_FLAG_MASK) ? 1 : 0);
3571
3572        }
3573        return BP_NOT_CAP;
3574}
3575
3576int tap_flag_status_clear(bpctl_dev_t *pbpctl_dev)
3577{
3578        uint32_t status_reg = 0;
3579        if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) {
3580                if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
3581                        status_reg = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
3582                        write_reg(pbpctl_dev, status_reg & ~TAP_FLAG_MASK,
3583                                  STATUS_TAP_REG_ADDR);
3584                        return 0;
3585                }
3586        }
3587        return BP_NOT_CAP;
3588}
3589
3590int tap_change_status(bpctl_dev_t *pbpctl_dev)
3591{
3592        int ret = BP_NOT_CAP;
3593        if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
3594                if (pbpctl_dev->bp_caps & TAP_CAP) {
3595                        if (pbpctl_dev->bp_caps & BP_CAP) {
3596                                ret = tap_flag_status(pbpctl_dev);
3597                                tap_flag_status_clear(pbpctl_dev);
3598                        } else {
3599                                ret = bypass_from_last_read(pbpctl_dev);
3600                                bypass_status_clear(pbpctl_dev);
3601                        }
3602                }
3603        }
3604        return ret;
3605}
3606
3607int tap_off_status(bpctl_dev_t *pbpctl_dev)
3608{
3609        if (pbpctl_dev->bp_caps & TAP_CAP) {
3610                if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
3611                        return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
3612                                  TAP_OFF_MASK) == TAP_OFF_MASK) ? 1 : 0);
3613        }
3614        return BP_NOT_CAP;
3615}
3616
3617int tap_status(bpctl_dev_t *pbpctl_dev)
3618{
3619        u32 ctrl_ext = 0;
3620
3621        if (pbpctl_dev->bp_caps & TAP_CAP) {
3622                bpctl_dev_t *pbpctl_dev_b = NULL;
3623
3624                pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
3625                if (!pbpctl_dev_b)
3626                        return BP_NOT_CAP;
3627
3628                if (pbpctl_dev->bp_ext_ver >= 0x8) {
3629                        if (!pbpctl_dev->bp_10g)
3630                                return (((BPCTL_READ_REG
3631                                          (pbpctl_dev_b,
3632                                           CTRL_EXT)) &
3633                                         BPCTLI_CTRL_EXT_SDP6_DATA) !=
3634                                        0 ? 0 : 1);
3635                        else {
3636                                ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP);
3637                                BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
3638                                                (ctrl_ext |
3639                                                 BP10G_SDP6_DATA_OUT));
3640                                return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) &
3641                                         BP10G_SDP6_DATA_IN) != 0 ? 0 : 1);
3642                        }
3643
3644                } else if (pbpctl_dev->media_type == BP_COPPER)
3645                        return (((BPCTL_READ_REG(pbpctl_dev, CTRL)) &
3646                                 BPCTLI_CTRL_SWDPIN0) != 0 ? 1 : 0);
3647                else {
3648                        if ((bypass_status_clear(pbpctl_dev)) >= 0)
3649                                return bypass_from_last_read(pbpctl_dev);
3650                }
3651
3652        }
3653        return BP_NOT_CAP;
3654}
3655
3656int default_pwron_tap_status(bpctl_dev_t *pbpctl_dev)
3657{
3658        if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) {
3659                if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
3660                        return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
3661                                  DFLT_PWRON_TAP_MASK) ==
3662                                 DFLT_PWRON_TAP_MASK) ? 1 : 0);
3663        }
3664        return BP_NOT_CAP;
3665}
3666
3667int dis_tap_cap_status(bpctl_dev_t *pbpctl_dev)
3668{
3669        if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) {
3670                if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)
3671                        return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
3672                                  DIS_TAP_CAP_MASK) ==
3673                                 DIS_TAP_CAP_MASK) ? 1 : 0);
3674        }
3675        return BP_NOT_CAP;
3676}
3677
3678int disc_flag_status(bpctl_dev_t *pbpctl_dev)
3679{
3680
3681        if (pbpctl_dev->bp_caps & DISC_CAP) {
3682                if (pbpctl_dev->bp_ext_ver >= 0x8)
3683                        return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
3684                                  DISC_FLAG_MASK) == DISC_FLAG_MASK) ? 1 : 0);
3685
3686        }
3687        return BP_NOT_CAP;
3688}
3689
3690int disc_flag_status_clear(bpctl_dev_t *pbpctl_dev)
3691{
3692        uint32_t status_reg = 0;
3693        if (pbpctl_dev->bp_caps & DISC_CAP) {
3694                if (pbpctl_dev->bp_ext_ver >= 0x8) {
3695                        status_reg = read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR);
3696                        write_reg(pbpctl_dev, status_reg & ~DISC_FLAG_MASK,
3697                                  STATUS_DISC_REG_ADDR);
3698                        return BP_OK;
3699                }
3700        }
3701        return BP_NOT_CAP;
3702}
3703
3704int disc_change_status(bpctl_dev_t *pbpctl_dev)
3705{
3706        int ret = BP_NOT_CAP;
3707        if (pbpctl_dev->bp_caps & DISC_CAP) {
3708                ret = disc_flag_status(pbpctl_dev);
3709                disc_flag_status_clear(pbpctl_dev);
3710                return ret;
3711        }
3712        return BP_NOT_CAP;
3713}
3714
3715int disc_off_status(bpctl_dev_t *pbpctl_dev)
3716{
3717        bpctl_dev_t *pbpctl_dev_b = NULL;
3718        u32 ctrl_ext = 0;
3719
3720        if (pbpctl_dev->bp_caps & DISC_CAP) {
3721                pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
3722                if (!pbpctl_dev_b)
3723                        return BP_NOT_CAP;
3724                if (DISCF_IF_SERIES(pbpctl_dev->subdevice))
3725                        return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
3726                                  DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0);
3727
3728                if (pbpctl_dev->bp_i80) {
3729                        return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT)) &
3730                                 BPCTLI_CTRL_EXT_SDP6_DATA) != 0 ? 1 : 0);
3731
3732                }
3733                if (pbpctl_dev->bp_540) {
3734                        ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, ESDP);
3735                        return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) &
3736                                 BP10G_SDP2_DATA) != 0 ? 1 : 0);
3737
3738                }
3739                if (pbpctl_dev->media_type == BP_COPPER) {
3740
3741#if 0
3742                        return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
3743                                  DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0);
3744#endif
3745                        if (!pbpctl_dev->bp_10g)
3746                                return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
3747                                         BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0);
3748                        else
3749                                return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) &
3750                                         BP10G_SDP1_DATA) != 0 ? 1 : 0);
3751
3752                } else {
3753
3754                        if (pbpctl_dev->bp_10g9) {
3755                                ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL);
3756                                BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL,
3757                                                (ctrl_ext |
3758                                                 BP10G_I2C_DATA_OUT));
3759                                return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) &
3760                                         BP10G_I2C_DATA_IN) != 0 ? 1 : 0);
3761
3762                        } else if (pbpctl_dev->bp_fiber5) {
3763                                return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
3764                                         BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0);
3765                        } else if (pbpctl_dev->bp_10gb) {
3766                                ctrl_ext =
3767                                    BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
3768                                BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO,
3769                                                 (ctrl_ext | BP10GB_GPIO3_OE_P1)
3770                                                 & ~(BP10GB_GPIO3_SET_P1 |
3771                                                     BP10GB_GPIO3_CLR_P1));
3772
3773                                return (((BP10GB_READ_REG
3774                                          (pbpctl_dev,
3775                                           MISC_REG_GPIO)) & BP10GB_GPIO3_P1) !=
3776                                        0 ? 1 : 0);
3777                        }
3778                        if (!pbpctl_dev->bp_10g) {
3779
3780                                return (((BPCTL_READ_REG
3781                                          (pbpctl_dev_b,
3782                                           CTRL_EXT)) &
3783                                         BPCTLI_CTRL_EXT_SDP6_DATA) !=
3784                                        0 ? 1 : 0);
3785                        } else {
3786                                ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP);
3787                                BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
3788                                                (ctrl_ext |
3789                                                 BP10G_SDP6_DATA_OUT));
3790                                return (((BP10G_READ_REG(pbpctl_dev_b, EODSDP))
3791                                         & BP10G_SDP6_DATA_IN) != 0 ? 1 : 0);
3792                        }
3793
3794                }
3795        }
3796        return BP_NOT_CAP;
3797}
3798
3799static int disc_status(bpctl_dev_t *pbpctl_dev)
3800{
3801        int ctrl = 0;
3802        if (pbpctl_dev->bp_caps & DISC_CAP) {
3803                ctrl = disc_off_status(pbpctl_dev);
3804                if (ctrl < 0)
3805                        return ctrl;
3806                return ((ctrl == 0) ? 1 : 0);
3807        }
3808        return BP_NOT_CAP;
3809}
3810
3811int default_pwron_disc_status(bpctl_dev_t *pbpctl_dev)
3812{
3813        if (pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) {
3814                if (pbpctl_dev->bp_ext_ver >= 0x8)
3815                        return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
3816                                  DFLT_PWRON_DISC_MASK) ==
3817                                 DFLT_PWRON_DISC_MASK) ? 1 : 0);
3818        }
3819        return BP_NOT_CAP;
3820}
3821
3822int dis_disc_cap_status(bpctl_dev_t *pbpctl_dev)
3823{
3824        if (pbpctl_dev->bp_caps & DIS_DISC_CAP) {
3825                if (pbpctl_dev->bp_ext_ver >= 0x8)
3826                        return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
3827                                  DIS_DISC_CAP_MASK) ==
3828                                 DIS_DISC_CAP_MASK) ? 1 : 0);
3829        }
3830        return BP_NOT_CAP;
3831}
3832
3833int disc_port_status(bpctl_dev_t *pbpctl_dev)
3834{
3835        int ret = BP_NOT_CAP;
3836        bpctl_dev_t *pbpctl_dev_m;
3837
3838        if ((is_bypass_fn(pbpctl_dev)) == 1)
3839                pbpctl_dev_m = pbpctl_dev;
3840        else
3841                pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
3842        if (pbpctl_dev_m == NULL)
3843                return BP_NOT_CAP;
3844
3845        if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
3846                if (is_bypass_fn(pbpctl_dev) == 1) {
3847                        return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
3848                                  TX_DISA_MASK) == TX_DISA_MASK) ? 1 : 0);
3849                } else
3850                        return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
3851                                  TX_DISB_MASK) == TX_DISB_MASK) ? 1 : 0);
3852
3853        }
3854        return ret;
3855}
3856
3857int default_pwron_disc_port_status(bpctl_dev_t *pbpctl_dev)
3858{
3859        int ret = BP_NOT_CAP;
3860        bpctl_dev_t *pbpctl_dev_m;
3861
3862        if ((is_bypass_fn(pbpctl_dev)) == 1)
3863                pbpctl_dev_m = pbpctl_dev;
3864        else
3865                pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
3866        if (pbpctl_dev_m == NULL)
3867                return BP_NOT_CAP;
3868
3869        if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
3870                if (is_bypass_fn(pbpctl_dev) == 1)
3871                        return ret;
3872                /*  return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); */
3873                else
3874                        return ret;
3875                /*   return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); */
3876
3877        }
3878        return ret;
3879}
3880
3881int wdt_exp_mode_status(bpctl_dev_t *pbpctl_dev)
3882{
3883        if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
3884                if (pbpctl_dev->bp_ext_ver <= PXG2BPI_VER)
3885                        return 0;       /* bypass mode */
3886                else if (pbpctl_dev->bp_ext_ver == PXG2TBPI_VER)
3887                        return 1;       /* tap mode */
3888                else if (pbpctl_dev->bp_ext_ver >= PXE2TBPI_VER) {
3889                        if (pbpctl_dev->bp_ext_ver >= 0x8) {
3890                                if (((read_reg
3891                                      (pbpctl_dev,
3892                                       STATUS_DISC_REG_ADDR)) &
3893                                     WDTE_DISC_BPN_MASK) == WDTE_DISC_BPN_MASK)
3894                                        return 2;
3895                        }
3896                        return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) &
3897                                  WDTE_TAP_BPN_MASK) ==
3898                                 WDTE_TAP_BPN_MASK) ? 1 : 0);
3899                }
3900        }
3901        return BP_NOT_CAP;
3902}
3903
3904int tpl2_flag_status(bpctl_dev_t *pbpctl_dev)
3905{
3906
3907        if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) {
3908                return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
3909                          TPL2_FLAG_MASK) == TPL2_FLAG_MASK) ? 1 : 0);
3910
3911        }
3912        return BP_NOT_CAP;
3913}
3914
3915int tpl_hw_status(bpctl_dev_t *pbpctl_dev)
3916{
3917        bpctl_dev_t *pbpctl_dev_b = NULL;
3918
3919        pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
3920        if (!pbpctl_dev_b)
3921                return BP_NOT_CAP;
3922
3923        if (TPL_IF_SERIES(pbpctl_dev->subdevice))
3924                return (((BPCTL_READ_REG(pbpctl_dev, CTRL)) &
3925                         BPCTLI_CTRL_SWDPIN0) != 0 ? 1 : 0);
3926        return BP_NOT_CAP;
3927}
3928
3929
3930int bp_wait_at_pwup_status(bpctl_dev_t *pbpctl_dev)
3931{
3932        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3933                if (pbpctl_dev->bp_ext_ver >= 0x8)
3934                        return ((((read_reg(pbpctl_dev, CONT_CONFIG_REG_ADDR)) &
3935                                  WAIT_AT_PWUP_MASK) ==
3936                                 WAIT_AT_PWUP_MASK) ? 1 : 0);
3937        }
3938        return BP_NOT_CAP;
3939}
3940
3941int bp_hw_reset_status(bpctl_dev_t *pbpctl_dev)
3942{
3943
3944        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
3945
3946                if (pbpctl_dev->bp_ext_ver >= 0x8)
3947                        return ((((read_reg(pbpctl_dev, CONT_CONFIG_REG_ADDR)) &
3948                                  EN_HW_RESET_MASK) ==
3949                                 EN_HW_RESET_MASK) ? 1 : 0);
3950        }
3951        return BP_NOT_CAP;
3952}
3953
3954
3955int std_nic_status(bpctl_dev_t *pbpctl_dev)
3956{
3957        int status_val = 0;
3958
3959        if (pbpctl_dev->bp_caps & STD_NIC_CAP) {
3960                if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
3961                        return BP_NOT_CAP;
3962                if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
3963                        return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) &
3964                                  STD_NIC_ON_MASK) == STD_NIC_ON_MASK) ? 1 : 0);
3965                }
3966
3967                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
3968                        if (pbpctl_dev->bp_caps & BP_CAP) {
3969                                status_val =
3970                                    read_reg(pbpctl_dev, STATUS_REG_ADDR);
3971                                if (((!(status_val & WDT_EN_MASK))
3972                                     && ((status_val & STD_NIC_MASK) ==
3973                                         STD_NIC_MASK)))
3974                                        status_val = 1;
3975                                else
3976                                        return 0;
3977                        }
3978                        if (pbpctl_dev->bp_caps & TAP_CAP) {
3979                                status_val =
3980                                    read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
3981                                if ((status_val & STD_NIC_TAP_MASK) ==
3982                                    STD_NIC_TAP_MASK)
3983                                        status_val = 1;
3984                                else
3985                                        return 0;
3986                        }
3987                        if (pbpctl_dev->bp_caps & TAP_CAP) {
3988                                if ((disc_off_status(pbpctl_dev)))
3989                                        status_val = 1;
3990                                else
3991                                        return 0;
3992                        }
3993
3994                        return status_val;
3995                }
3996        }
3997        return BP_NOT_CAP;
3998}
3999
4000/******************************************************/
4001/**************SW_INIT*********************************/
4002/******************************************************/
4003void bypass_caps_init(bpctl_dev_t *pbpctl_dev)
4004{
4005        u_int32_t ctrl_ext = 0;
4006        bpctl_dev_t *pbpctl_dev_m = NULL;
4007
4008#ifdef BYPASS_DEBUG
4009        int ret = 0;
4010        if (!(INTEL_IF_SERIES(adapter->bp_device_block.subdevice))) {
4011                ret = read_reg(pbpctl_dev, VER_REG_ADDR);
4012                printk("VER_REG reg1=%x\n", ret);
4013                ret = read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR);
4014                printk("PRODUCT_CAP reg=%x\n", ret);
4015                ret = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR);
4016                printk("STATUS_TAP reg1=%x\n", ret);
4017                ret = read_reg(pbpctl_dev, 0x7);
4018                printk("SIG_REG reg1=%x\n", ret);
4019                ret = read_reg(pbpctl_dev, STATUS_REG_ADDR);
4020                printk("STATUS_REG_ADDR=%x\n", ret);
4021                ret = read_reg(pbpctl_dev, WDT_REG_ADDR);
4022                printk("WDT_REG_ADDR=%x\n", ret);
4023                ret = read_reg(pbpctl_dev, TMRL_REG_ADDR);
4024                printk("TMRL_REG_ADDR=%x\n", ret);
4025                ret = read_reg(pbpctl_dev, TMRH_REG_ADDR);
4026                printk("TMRH_REG_ADDR=%x\n", ret);
4027        }
4028#endif
4029        if ((pbpctl_dev->bp_fiber5) || (pbpctl_dev->bp_10g9)) {
4030                pbpctl_dev->media_type = BP_FIBER;
4031        } else if (pbpctl_dev->bp_10gb) {
4032                if (BP10GB_CX4_SERIES(pbpctl_dev->subdevice))
4033                        pbpctl_dev->media_type = BP_CX4;
4034                else
4035                        pbpctl_dev->media_type = BP_FIBER;
4036
4037        }
4038
4039        else if (pbpctl_dev->bp_540)
4040                pbpctl_dev->media_type = BP_NONE;
4041        else if (!pbpctl_dev->bp_10g) {
4042
4043                ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
4044                if ((ctrl_ext & BPCTLI_CTRL_EXT_LINK_MODE_MASK) == 0x0)
4045                        pbpctl_dev->media_type = BP_COPPER;
4046                else
4047                        pbpctl_dev->media_type = BP_FIBER;
4048
4049        } else {
4050                if (BP10G_CX4_SERIES(pbpctl_dev->subdevice))
4051                        pbpctl_dev->media_type = BP_CX4;
4052                else
4053                        pbpctl_dev->media_type = BP_FIBER;
4054        }
4055
4056        if (is_bypass_fn(pbpctl_dev)) {
4057
4058                pbpctl_dev->bp_caps |= BP_PWOFF_ON_CAP;
4059                if (pbpctl_dev->media_type == BP_FIBER)
4060                        pbpctl_dev->bp_caps |=
4061                            (TX_CTL_CAP | TX_STATUS_CAP | TPL_CAP);
4062
4063                if (TPL_IF_SERIES(pbpctl_dev->subdevice))
4064                        pbpctl_dev->bp_caps |= TPL_CAP;
4065
4066                if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) {
4067                        pbpctl_dev->bp_caps |=
4068                            (BP_CAP | BP_STATUS_CAP | SW_CTL_CAP |
4069                             BP_PWUP_ON_CAP | BP_PWUP_OFF_CAP | BP_PWOFF_OFF_CAP
4070                             | WD_CTL_CAP | WD_STATUS_CAP | STD_NIC_CAP |
4071                             WD_TIMEOUT_CAP);
4072
4073                        pbpctl_dev->bp_ext_ver = OLD_IF_VER;
4074                        return;
4075                }
4076
4077                if ((pbpctl_dev->bp_fw_ver == 0xff) &&
4078                    OLD_IF_SERIES(pbpctl_dev->subdevice)) {
4079
4080                        pbpctl_dev->bp_caps |=
4081                            (BP_CAP | BP_STATUS_CAP | BP_STATUS_CHANGE_CAP |
4082                             SW_CTL_CAP | BP_PWUP_ON_CAP | WD_CTL_CAP |
4083                             WD_STATUS_CAP | WD_TIMEOUT_CAP);
4084
4085                        pbpctl_dev->bp_ext_ver = OLD_IF_VER;
4086                        return;
4087                }
4088
4089                else {
4090                        switch (pbpctl_dev->bp_fw_ver) {
4091                        case BP_FW_VER_A0:
4092                        case BP_FW_VER_A1:{
4093                                        pbpctl_dev->bp_ext_ver =
4094                                            (pbpctl_dev->
4095                                             bp_fw_ver & EXT_VER_MASK);
4096                                        break;
4097                                }
4098                        default:{
4099                                        if ((bypass_sign_check(pbpctl_dev)) !=
4100                                            1) {
4101                                                pbpctl_dev->bp_caps = 0;
4102                                                return;
4103                                        }
4104                                        pbpctl_dev->bp_ext_ver =
4105                                            (pbpctl_dev->
4106                                             bp_fw_ver & EXT_VER_MASK);
4107                                }
4108                        }
4109                }
4110
4111                if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER)
4112                        pbpctl_dev->bp_caps |=
4113                            (BP_CAP | BP_STATUS_CAP | BP_STATUS_CHANGE_CAP |
4114                             SW_CTL_CAP | BP_DIS_CAP | BP_DIS_STATUS_CAP |
4115                             BP_PWUP_ON_CAP | BP_PWUP_OFF_CAP | BP_PWUP_CTL_CAP
4116                             | WD_CTL_CAP | STD_NIC_CAP | WD_STATUS_CAP |
4117                             WD_TIMEOUT_CAP);
4118                else if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) {
4119                        int cap_reg;
4120
4121                        pbpctl_dev->bp_caps |=
4122                            (SW_CTL_CAP | WD_CTL_CAP | WD_STATUS_CAP |
4123                             WD_TIMEOUT_CAP);
4124                        cap_reg = get_bp_prod_caps(pbpctl_dev);
4125
4126                        if ((cap_reg & NORMAL_UNSUPPORT_MASK) ==
4127                            NORMAL_UNSUPPORT_MASK)
4128                                pbpctl_dev->bp_caps |= NIC_CAP_NEG;
4129                        else
4130                                pbpctl_dev->bp_caps |= STD_NIC_CAP;
4131
4132                        if ((normal_support(pbpctl_dev)) == 1)
4133
4134                                pbpctl_dev->bp_caps |= STD_NIC_CAP;
4135
4136                        else
4137                                pbpctl_dev->bp_caps |= NIC_CAP_NEG;
4138                        if ((cap_reg & BYPASS_SUPPORT_MASK) ==
4139                            BYPASS_SUPPORT_MASK) {
4140                                pbpctl_dev->bp_caps |=
4141                                    (BP_CAP | BP_STATUS_CAP |
4142                                     BP_STATUS_CHANGE_CAP | BP_DIS_CAP |
4143                                     BP_DIS_STATUS_CAP | BP_PWUP_ON_CAP |
4144                                     BP_PWUP_OFF_CAP | BP_PWUP_CTL_CAP);
4145                                if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER7)
4146                                        pbpctl_dev->bp_caps |=
4147                                            BP_PWOFF_ON_CAP | BP_PWOFF_OFF_CAP |
4148                                            BP_PWOFF_CTL_CAP;
4149                        }
4150                        if ((cap_reg & TAP_SUPPORT_MASK) == TAP_SUPPORT_MASK) {
4151                                pbpctl_dev->bp_caps |=
4152                                    (TAP_CAP | TAP_STATUS_CAP |
4153                                     TAP_STATUS_CHANGE_CAP | TAP_DIS_CAP |
4154                                     TAP_DIS_STATUS_CAP | TAP_PWUP_ON_CAP |
4155                                     TAP_PWUP_OFF_CAP | TAP_PWUP_CTL_CAP);
4156                        }
4157                        if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) {
4158                                if ((cap_reg & DISC_SUPPORT_MASK) ==
4159                                    DISC_SUPPORT_MASK)
4160                                        pbpctl_dev->bp_caps |=
4161                                            (DISC_CAP | DISC_DIS_CAP |
4162                                             DISC_PWUP_CTL_CAP);
4163                                if ((cap_reg & TPL2_SUPPORT_MASK) ==
4164                                    TPL2_SUPPORT_MASK) {
4165                                        pbpctl_dev->bp_caps_ex |= TPL2_CAP_EX;
4166                                        pbpctl_dev->bp_caps |= TPL_CAP;
4167                                        pbpctl_dev->bp_tpl_flag =
4168                                            tpl2_flag_status(pbpctl_dev);
4169                                }
4170
4171                        }
4172
4173                        if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER9) {
4174                                if ((cap_reg & DISC_PORT_SUPPORT_MASK) ==
4175                                    DISC_PORT_SUPPORT_MASK) {
4176                                        pbpctl_dev->bp_caps_ex |=
4177                                            DISC_PORT_CAP_EX;
4178                                        pbpctl_dev->bp_caps |=
4179                                            (TX_CTL_CAP | TX_STATUS_CAP);
4180                                }
4181
4182                        }
4183
4184                }
4185                if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) {
4186                        if ((read_reg(pbpctl_dev, STATUS_REG_ADDR)) &
4187                            WDT_EN_MASK)
4188                                pbpctl_dev->wdt_status = WDT_STATUS_EN;
4189                        else
4190                                pbpctl_dev->wdt_status = WDT_STATUS_DIS;
4191                }
4192
4193        } else if ((P2BPFI_IF_SERIES(pbpctl_dev->subdevice)) ||
4194                   (PEGF5_IF_SERIES(pbpctl_dev->subdevice)) ||
4195                   (PEGF80_IF_SERIES(pbpctl_dev->subdevice)) ||
4196                   (BP10G9_IF_SERIES(pbpctl_dev->subdevice))) {
4197                pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP);
4198        }
4199        if ((pbpctl_dev->subdevice & 0xa00) == 0xa00)
4200                pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP);
4201        if (PEG5_IF_SERIES(pbpctl_dev->subdevice))
4202                pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP);
4203
4204        if (BP10GB_IF_SERIES(pbpctl_dev->subdevice))
4205                pbpctl_dev->bp_caps &= ~(TX_CTL_CAP | TX_STATUS_CAP);
4206
4207        pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
4208        if (pbpctl_dev_m != NULL) {
4209                int cap_reg = 0;
4210                if (pbpctl_dev_m->bp_ext_ver >= 0x9) {
4211                        cap_reg = get_bp_prod_caps(pbpctl_dev_m);
4212                        if ((cap_reg & DISC_PORT_SUPPORT_MASK) ==
4213                            DISC_PORT_SUPPORT_MASK)
4214                                pbpctl_dev->bp_caps |=
4215                                    (TX_CTL_CAP | TX_STATUS_CAP);
4216                        pbpctl_dev->bp_caps_ex |= DISC_PORT_CAP_EX;
4217                }
4218        }
4219}
4220
4221int bypass_off_init(bpctl_dev_t *pbpctl_dev)
4222{
4223        int ret = cmnd_on(pbpctl_dev);
4224        if (ret < 0)
4225                return ret;
4226        if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
4227                return dis_bypass_cap(pbpctl_dev);
4228        wdt_off(pbpctl_dev);
4229        if (pbpctl_dev->bp_caps & BP_CAP)
4230                bypass_off(pbpctl_dev);
4231        if (pbpctl_dev->bp_caps & TAP_CAP)
4232                tap_off(pbpctl_dev);
4233        cmnd_off(pbpctl_dev);
4234        return 0;
4235}
4236
4237void remove_bypass_wd_auto(bpctl_dev_t *pbpctl_dev)
4238{
4239#ifdef BP_SELF_TEST
4240        bpctl_dev_t *pbpctl_dev_sl = NULL;
4241#endif
4242
4243        if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
4244
4245                del_timer_sync(&pbpctl_dev->bp_timer);
4246#ifdef BP_SELF_TEST
4247                pbpctl_dev_sl = get_status_port_fn(pbpctl_dev);
4248                if (pbpctl_dev_sl && (pbpctl_dev_sl->ndev)) {
4249                        if ((pbpctl_dev_sl->ndev->netdev_ops)
4250                            && (pbpctl_dev_sl->old_ops)) {
4251                                rtnl_lock();
4252                                pbpctl_dev_sl->ndev->netdev_ops =
4253                                    pbpctl_dev_sl->old_ops;
4254                                pbpctl_dev_sl->old_ops = NULL;
4255
4256                                rtnl_unlock();
4257
4258                        }
4259
4260                }
4261#endif
4262        }
4263
4264}
4265
4266int init_bypass_wd_auto(bpctl_dev_t *pbpctl_dev)
4267{
4268        if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
4269                init_timer(&pbpctl_dev->bp_timer);
4270                pbpctl_dev->bp_timer.function = &wd_reset_timer;
4271                pbpctl_dev->bp_timer.data = (unsigned long)pbpctl_dev;
4272                return 1;
4273        }
4274        return BP_NOT_CAP;
4275}
4276
4277#ifdef BP_SELF_TEST
4278int bp_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
4279{
4280        bpctl_dev_t *pbpctl_dev = NULL, *pbpctl_dev_m = NULL;
4281        int idx_dev = 0;
4282        struct ethhdr *eth = (struct ethhdr *)skb->data;
4283
4284        for (idx_dev = 0;
4285             ((bpctl_dev_arr[idx_dev].ndev != NULL) && (idx_dev < device_num));
4286             idx_dev++) {
4287                if (bpctl_dev_arr[idx_dev].ndev == dev) {
4288                        pbpctl_dev = &bpctl_dev_arr[idx_dev];
4289                        break;
4290                }
4291        }
4292        if (!pbpctl_dev)
4293                return 1;
4294        if ((htons(ETH_P_BPTEST) == eth->h_proto)) {
4295
4296                pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
4297                if (pbpctl_dev_m) {
4298
4299                        if (bypass_status(pbpctl_dev_m)) {
4300                                cmnd_on(pbpctl_dev_m);
4301                                bypass_off(pbpctl_dev_m);
4302                                cmnd_off(pbpctl_dev_m);
4303                        }
4304                        wdt_timer_reload(pbpctl_dev_m);
4305                }
4306                dev_kfree_skb_irq(skb);
4307                return 0;
4308        }
4309        return pbpctl_dev->hard_start_xmit_save(skb, dev);
4310}
4311#endif
4312
4313int set_bypass_wd_auto(bpctl_dev_t *pbpctl_dev, unsigned int param)
4314{
4315        if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
4316                if (pbpctl_dev->reset_time != param) {
4317                        if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
4318                                pbpctl_dev->reset_time =
4319                                    (param <
4320                                     WDT_AUTO_MIN_INT) ? WDT_AUTO_MIN_INT :
4321                                    param;
4322                        else
4323                                pbpctl_dev->reset_time = param;
4324                        if (param)
4325                                mod_timer(&pbpctl_dev->bp_timer, jiffies);
4326                }
4327                return 0;
4328        }
4329        return BP_NOT_CAP;
4330}
4331
4332int get_bypass_wd_auto(bpctl_dev_t *pbpctl_dev)
4333{
4334        if (pbpctl_dev->bp_caps & WD_CTL_CAP)
4335                return pbpctl_dev->reset_time;
4336
4337        return BP_NOT_CAP;
4338}
4339
4340#ifdef BP_SELF_TEST
4341
4342int set_bp_self_test(bpctl_dev_t *pbpctl_dev, unsigned int param)
4343{
4344        bpctl_dev_t *pbpctl_dev_sl = NULL;
4345
4346        if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
4347                pbpctl_dev->bp_self_test_flag = param == 0 ? 0 : 1;
4348                pbpctl_dev_sl = get_status_port_fn(pbpctl_dev);
4349
4350                if ((pbpctl_dev_sl->ndev) && (pbpctl_dev_sl->ndev->netdev_ops)) {
4351                        rtnl_lock();
4352                        if (pbpctl_dev->bp_self_test_flag == 1) {
4353
4354                                pbpctl_dev_sl->old_ops =
4355                                    pbpctl_dev_sl->ndev->netdev_ops;
4356                                pbpctl_dev_sl->new_ops =
4357                                    *pbpctl_dev_sl->old_ops;
4358                                pbpctl_dev_sl->new_ops.ndo_start_xmit =
4359                                    bp_hard_start_xmit;
4360                                pbpctl_dev_sl->ndev->netdev_ops =
4361                                    &pbpctl_dev_sl->new_ops;
4362
4363                        } else if (pbpctl_dev_sl->old_ops) {
4364                                pbpctl_dev_sl->ndev->netdev_ops =
4365                                    pbpctl_dev_sl->old_ops;
4366                                pbpctl_dev_sl->old_ops = NULL;
4367                        }
4368                        rtnl_unlock();
4369                }
4370
4371                set_bypass_wd_auto(pbpctl_dev, param);
4372                return 0;
4373        }
4374        return BP_NOT_CAP;
4375}
4376
4377int get_bp_self_test(bpctl_dev_t *pbpctl_dev)
4378{
4379
4380        if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
4381                if (pbpctl_dev->bp_self_test_flag == 1)
4382                        return pbpctl_dev->reset_time;
4383                else
4384                        return 0;
4385        }
4386        return BP_NOT_CAP;
4387}
4388
4389#endif
4390
4391/**************************************************************/
4392/************************* API ********************************/
4393/**************************************************************/
4394
4395int is_bypass_fn(bpctl_dev_t *pbpctl_dev)
4396{
4397        if (!pbpctl_dev)
4398                return -1;
4399
4400        return (((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) ? 1 : 0);
4401}
4402
4403int set_bypass_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode)
4404{
4405        int ret = 0;
4406
4407        if (!(pbpctl_dev->bp_caps & BP_CAP))
4408                return BP_NOT_CAP;
4409        ret = cmnd_on(pbpctl_dev);
4410        if (ret < 0)
4411                return ret;
4412        if (!bypass_mode)
4413                ret = bypass_off(pbpctl_dev);
4414        else
4415                ret = bypass_on(pbpctl_dev);
4416        cmnd_off(pbpctl_dev);
4417
4418        return ret;
4419}
4420
4421int get_bypass_fn(bpctl_dev_t *pbpctl_dev)
4422{
4423        return bypass_status(pbpctl_dev);
4424}
4425
4426int get_bypass_change_fn(bpctl_dev_t *pbpctl_dev)
4427{
4428        if (!pbpctl_dev)
4429                return -1;
4430
4431        return bypass_change_status(pbpctl_dev);
4432}
4433
4434int set_dis_bypass_fn(bpctl_dev_t *pbpctl_dev, int dis_param)
4435{
4436        int ret = 0;
4437        if (!pbpctl_dev)
4438                return -1;
4439
4440        if (!(pbpctl_dev->bp_caps & BP_DIS_CAP))
4441                return BP_NOT_CAP;
4442        ret = cmnd_on(pbpctl_dev);
4443        if (ret < 0)
4444                return ret;
4445        if (dis_param)
4446                ret = dis_bypass_cap(pbpctl_dev);
4447        else
4448                ret = en_bypass_cap(pbpctl_dev);
4449        cmnd_off(pbpctl_dev);
4450        return ret;
4451}
4452
4453int get_dis_bypass_fn(bpctl_dev_t *pbpctl_dev)
4454{
4455        if (!pbpctl_dev)
4456                return -1;
4457
4458        return dis_bypass_cap_status(pbpctl_dev);
4459}
4460
4461int set_bypass_pwoff_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode)
4462{
4463        int ret = 0;
4464        if (!pbpctl_dev)
4465                return -1;
4466
4467        if (!(pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP))
4468                return BP_NOT_CAP;
4469        ret = cmnd_on(pbpctl_dev);
4470        if (ret < 0)
4471                return ret;
4472        if (bypass_mode)
4473                ret = bypass_state_pwroff(pbpctl_dev);
4474        else
4475                ret = normal_state_pwroff(pbpctl_dev);
4476        cmnd_off(pbpctl_dev);
4477        return ret;
4478}
4479
4480int get_bypass_pwoff_fn(bpctl_dev_t *pbpctl_dev)
4481{
4482        if (!pbpctl_dev)
4483                return -1;
4484
4485        return default_pwroff_status(pbpctl_dev);
4486}
4487
4488int set_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode)
4489{
4490        int ret = 0;
4491        if (!pbpctl_dev)
4492                return -1;
4493
4494        if (!(pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP))
4495                return BP_NOT_CAP;
4496        ret = cmnd_on(pbpctl_dev);
4497        if (ret < 0)
4498                return ret;
4499        if (bypass_mode)
4500                ret = bypass_state_pwron(pbpctl_dev);
4501        else
4502                ret = normal_state_pwron(pbpctl_dev);
4503        cmnd_off(pbpctl_dev);
4504        return ret;
4505}
4506
4507int get_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev)
4508{
4509        if (!pbpctl_dev)
4510                return -1;
4511
4512        return default_pwron_status(pbpctl_dev);
4513}
4514
4515int set_bypass_wd_fn(bpctl_dev_t *pbpctl_dev, int timeout)
4516{
4517        int ret = 0;
4518        if (!pbpctl_dev)
4519                return -1;
4520
4521        if (!(pbpctl_dev->bp_caps & WD_CTL_CAP))
4522                return BP_NOT_CAP;
4523
4524        ret = cmnd_on(pbpctl_dev);
4525        if (ret < 0)
4526                return ret;
4527        if (!timeout)
4528                ret = wdt_off(pbpctl_dev);
4529        else {
4530                wdt_on(pbpctl_dev, timeout);
4531                ret = pbpctl_dev->bypass_timer_interval;
4532        }
4533        cmnd_off(pbpctl_dev);
4534        return ret;
4535}
4536
4537int get_bypass_wd_fn(bpctl_dev_t *pbpctl_dev, int *timeout)
4538{
4539        if (!pbpctl_dev)
4540                return -1;
4541
4542        return wdt_programmed(pbpctl_dev, timeout);
4543}
4544
4545int get_wd_expire_time_fn(bpctl_dev_t *pbpctl_dev, int *time_left)
4546{
4547        if (!pbpctl_dev)
4548                return -1;
4549
4550        return wdt_timer(pbpctl_dev, time_left);
4551}
4552
4553int reset_bypass_wd_timer_fn(bpctl_dev_t *pbpctl_dev)
4554{
4555        if (!pbpctl_dev)
4556                return -1;
4557
4558        return wdt_timer_reload(pbpctl_dev);
4559}
4560
4561int get_wd_set_caps_fn(bpctl_dev_t *pbpctl_dev)
4562{
4563        int bp_status = 0;
4564
4565        unsigned int step_value = TIMEOUT_MAX_STEP + 1, bit_cnt = 0;
4566        if (!pbpctl_dev)
4567                return -1;
4568
4569        if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
4570                return BP_NOT_CAP;
4571
4572        while ((step_value >>= 1))
4573                bit_cnt++;
4574
4575        if (is_bypass_fn(pbpctl_dev)) {
4576                bp_status =
4577                    WD_STEP_COUNT_MASK(bit_cnt) | WDT_STEP_TIME |
4578                    WD_MIN_TIME_MASK(TIMEOUT_UNIT / 100);
4579        } else
4580                return -1;
4581
4582        return bp_status;
4583}
4584
4585int set_std_nic_fn(bpctl_dev_t *pbpctl_dev, int nic_mode)
4586{
4587        int ret = 0;
4588        if (!pbpctl_dev)
4589                return -1;
4590
4591        if (!(pbpctl_dev->bp_caps & STD_NIC_CAP))
4592                return BP_NOT_CAP;
4593
4594        ret = cmnd_on(pbpctl_dev);
4595        if (ret < 0)
4596                return ret;
4597        if (nic_mode)
4598                ret = std_nic_on(pbpctl_dev);
4599        else
4600                ret = std_nic_off(pbpctl_dev);
4601        cmnd_off(pbpctl_dev);
4602        return ret;
4603}
4604
4605int get_std_nic_fn(bpctl_dev_t *pbpctl_dev)
4606{
4607        if (!pbpctl_dev)
4608                return -1;
4609
4610        return std_nic_status(pbpctl_dev);
4611}
4612
4613int set_tap_fn(bpctl_dev_t *pbpctl_dev, int tap_mode)
4614{
4615        if (!pbpctl_dev)
4616                return -1;
4617
4618        if ((pbpctl_dev->bp_caps & TAP_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) {
4619                if (!tap_mode)
4620                        tap_off(pbpctl_dev);
4621                else
4622                        tap_on(pbpctl_dev);
4623                cmnd_off(pbpctl_dev);
4624                return 0;
4625        }
4626        return BP_NOT_CAP;
4627}
4628
4629int get_tap_fn(bpctl_dev_t *pbpctl_dev)
4630{
4631        if (!pbpctl_dev)
4632                return -1;
4633
4634        return tap_status(pbpctl_dev);
4635}
4636
4637int set_tap_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode)
4638{
4639        int ret = 0;
4640        if (!pbpctl_dev)
4641                return -1;
4642
4643        if ((pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP)
4644            && ((cmnd_on(pbpctl_dev)) >= 0)) {
4645                if (tap_mode)
4646                        ret = tap_state_pwron(pbpctl_dev);
4647                else
4648                        ret = normal_state_pwron(pbpctl_dev);
4649                cmnd_off(pbpctl_dev);
4650        } else
4651                ret = BP_NOT_CAP;
4652        return ret;
4653}
4654
4655int get_tap_pwup_fn(bpctl_dev_t *pbpctl_dev)
4656{
4657        int ret = 0;
4658        if (!pbpctl_dev)
4659                return -1;
4660
4661        ret = default_pwron_tap_status(pbpctl_dev);
4662        if (ret < 0)
4663                return ret;
4664        return ((ret == 0) ? 1 : 0);
4665}
4666
4667int get_tap_change_fn(bpctl_dev_t *pbpctl_dev)
4668{
4669        if (!pbpctl_dev)
4670                return -1;
4671
4672        return tap_change_status(pbpctl_dev);
4673}
4674
4675int set_dis_tap_fn(bpctl_dev_t *pbpctl_dev, int dis_param)
4676{
4677        int ret = 0;
4678        if (!pbpctl_dev)
4679                return -1;
4680
4681        if ((pbpctl_dev->bp_caps & TAP_DIS_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) {
4682                if (dis_param)
4683                        ret = dis_tap_cap(pbpctl_dev);
4684                else
4685                        ret = en_tap_cap(pbpctl_dev);
4686                cmnd_off(pbpctl_dev);
4687                return ret;
4688        } else
4689                return BP_NOT_CAP;
4690}
4691
4692int get_dis_tap_fn(bpctl_dev_t *pbpctl_dev)
4693{
4694        if (!pbpctl_dev)
4695                return -1;
4696
4697        return dis_tap_cap_status(pbpctl_dev);
4698}
4699
4700int set_disc_fn(bpctl_dev_t *pbpctl_dev, int disc_mode)
4701{
4702        if (!pbpctl_dev)
4703                return -1;
4704
4705        if ((pbpctl_dev->bp_caps & DISC_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) {
4706                if (!disc_mode)
4707                        disc_off(pbpctl_dev);
4708                else
4709                        disc_on(pbpctl_dev);
4710                cmnd_off(pbpctl_dev);
4711
4712                return BP_OK;
4713        }
4714        return BP_NOT_CAP;
4715}
4716
4717int get_disc_fn(bpctl_dev_t *pbpctl_dev)
4718{
4719        int ret = 0;
4720        if (!pbpctl_dev)
4721                return -1;
4722
4723        ret = disc_status(pbpctl_dev);
4724
4725        return ret;
4726}
4727
4728int set_disc_pwup_fn(bpctl_dev_t *pbpctl_dev, int disc_mode)
4729{
4730        int ret = 0;
4731        if (!pbpctl_dev)
4732                return -1;
4733
4734        if ((pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP)
4735            && ((cmnd_on(pbpctl_dev)) >= 0)) {
4736                if (disc_mode)
4737                        ret = disc_state_pwron(pbpctl_dev);
4738                else
4739                        ret = normal_state_pwron(pbpctl_dev);
4740                cmnd_off(pbpctl_dev);
4741        } else
4742                ret = BP_NOT_CAP;
4743        return ret;
4744}
4745
4746int get_disc_pwup_fn(bpctl_dev_t *pbpctl_dev)
4747{
4748        int ret = 0;
4749        if (!pbpctl_dev)
4750                return -1;
4751
4752        ret = default_pwron_disc_status(pbpctl_dev);
4753        return (ret == 0 ? 1 : (ret < 0 ? BP_NOT_CAP : 0));
4754}
4755
4756int get_disc_change_fn(bpctl_dev_t *pbpctl_dev)
4757{
4758        int ret = 0;
4759        if (!pbpctl_dev)
4760                return -1;
4761
4762        ret = disc_change_status(pbpctl_dev);
4763        return ret;
4764}
4765
4766int set_dis_disc_fn(bpctl_dev_t *pbpctl_dev, int dis_param)
4767{
4768        int ret = 0;
4769        if (!pbpctl_dev)
4770                return -1;
4771
4772        if ((pbpctl_dev->bp_caps & DISC_DIS_CAP)
4773            && ((cmnd_on(pbpctl_dev)) >= 0)) {
4774                if (dis_param)
4775                        ret = dis_disc_cap(pbpctl_dev);
4776                else
4777                        ret = en_disc_cap(pbpctl_dev);
4778                cmnd_off(pbpctl_dev);
4779                return ret;
4780        } else
4781                return BP_NOT_CAP;
4782}
4783
4784int get_dis_disc_fn(bpctl_dev_t *pbpctl_dev)
4785{
4786        int ret = 0;
4787        if (!pbpctl_dev)
4788                return -1;
4789
4790        ret = dis_disc_cap_status(pbpctl_dev);
4791
4792        return ret;
4793}
4794
4795int set_disc_port_fn(bpctl_dev_t *pbpctl_dev, int disc_mode)
4796{
4797        int ret = BP_NOT_CAP;
4798        if (!pbpctl_dev)
4799                return -1;
4800
4801        if (!disc_mode)
4802                ret = disc_port_off(pbpctl_dev);
4803        else
4804                ret = disc_port_on(pbpctl_dev);
4805
4806        return ret;
4807}
4808
4809int get_disc_port_fn(bpctl_dev_t *pbpctl_dev)
4810{
4811        if (!pbpctl_dev)
4812                return -1;
4813
4814        return disc_port_status(pbpctl_dev);
4815}
4816
4817int set_disc_port_pwup_fn(bpctl_dev_t *pbpctl_dev, int disc_mode)
4818{
4819        int ret = BP_NOT_CAP;
4820        if (!pbpctl_dev)
4821                return -1;
4822
4823        if (!disc_mode)
4824                ret = normal_port_state_pwron(pbpctl_dev);
4825        else
4826                ret = disc_port_state_pwron(pbpctl_dev);
4827
4828        return ret;
4829}
4830
4831int get_disc_port_pwup_fn(bpctl_dev_t *pbpctl_dev)
4832{
4833        int ret = 0;
4834        if (!pbpctl_dev)
4835                return -1;
4836
4837        ret = default_pwron_disc_port_status(pbpctl_dev);
4838        if (ret < 0)
4839                return ret;
4840        return ((ret == 0) ? 1 : 0);
4841}
4842
4843int get_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev)
4844{
4845        if (!pbpctl_dev)
4846                return -1;
4847
4848        return wdt_exp_mode_status(pbpctl_dev);
4849}
4850
4851int set_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev, int param)
4852{
4853        if (!pbpctl_dev)
4854                return -1;
4855
4856        return wdt_exp_mode(pbpctl_dev, param);
4857}
4858
4859int reset_cont_fn(bpctl_dev_t *pbpctl_dev)
4860{
4861        int ret = 0;
4862        if (!pbpctl_dev)
4863                return -1;
4864
4865        ret = cmnd_on(pbpctl_dev);
4866        if (ret < 0)
4867                return ret;
4868        return reset_cont(pbpctl_dev);
4869}
4870
4871int set_tx_fn(bpctl_dev_t *pbpctl_dev, int tx_state)
4872{
4873
4874        bpctl_dev_t *pbpctl_dev_b = NULL;
4875        if (!pbpctl_dev)
4876                return -1;
4877
4878        if ((pbpctl_dev->bp_caps & TPL_CAP) &&
4879            (pbpctl_dev->bp_caps & SW_CTL_CAP)) {
4880                if ((pbpctl_dev->bp_tpl_flag))
4881                        return BP_NOT_CAP;
4882        } else {
4883                pbpctl_dev_b = get_master_port_fn(pbpctl_dev);
4884                if (pbpctl_dev_b &&
4885                    (pbpctl_dev_b->bp_caps & TPL_CAP) &&
4886                    (pbpctl_dev_b->bp_tpl_flag))
4887                        return BP_NOT_CAP;
4888        }
4889        return set_tx(pbpctl_dev, tx_state);
4890}
4891
4892int set_bp_force_link_fn(int dev_num, int tx_state)
4893{
4894        static bpctl_dev_t *bpctl_dev_curr;
4895
4896        if ((dev_num < 0) || (dev_num > device_num)
4897            || (bpctl_dev_arr[dev_num].pdev == NULL))
4898                return -1;
4899        bpctl_dev_curr = &bpctl_dev_arr[dev_num];
4900
4901        return set_bp_force_link(bpctl_dev_curr, tx_state);
4902}
4903
4904int set_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev, int param)
4905{
4906        if (!pbpctl_dev)
4907                return -1;
4908
4909        return set_bypass_wd_auto(pbpctl_dev, param);
4910}
4911
4912int get_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev)
4913{
4914        if (!pbpctl_dev)
4915                return -1;
4916
4917        return get_bypass_wd_auto(pbpctl_dev);
4918}
4919
4920#ifdef BP_SELF_TEST
4921int set_bp_self_test_fn(bpctl_dev_t *pbpctl_dev, int param)
4922{
4923        if (!pbpctl_dev)
4924                return -1;
4925
4926        return set_bp_self_test(pbpctl_dev, param);
4927}
4928
4929int get_bp_self_test_fn(bpctl_dev_t *pbpctl_dev)
4930{
4931        if (!pbpctl_dev)
4932                return -1;
4933
4934        return get_bp_self_test(pbpctl_dev);
4935}
4936
4937#endif
4938
4939int get_bypass_caps_fn(bpctl_dev_t *pbpctl_dev)
4940{
4941        if (!pbpctl_dev)
4942                return -1;
4943
4944        return pbpctl_dev->bp_caps;
4945
4946}
4947
4948int get_bypass_slave_fn(bpctl_dev_t *pbpctl_dev, bpctl_dev_t **pbpctl_dev_out)
4949{
4950        int idx_dev = 0;
4951        if (!pbpctl_dev)
4952                return -1;
4953
4954        if ((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) {
4955                for (idx_dev = 0;
4956                     ((bpctl_dev_arr[idx_dev].pdev != NULL)
4957                      && (idx_dev < device_num)); idx_dev++) {
4958                        if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)
4959                            && (bpctl_dev_arr[idx_dev].slot ==
4960                                pbpctl_dev->slot)) {
4961                                if ((pbpctl_dev->func == 0)
4962                                    && (bpctl_dev_arr[idx_dev].func == 1)) {
4963                                        *pbpctl_dev_out =
4964                                            &bpctl_dev_arr[idx_dev];
4965                                        return 1;
4966                                }
4967                                if ((pbpctl_dev->func == 2) &&
4968                                    (bpctl_dev_arr[idx_dev].func == 3)) {
4969                                        *pbpctl_dev_out =
4970                                            &bpctl_dev_arr[idx_dev];
4971                                        return 1;
4972                                }
4973                        }
4974                }
4975                return -1;
4976        } else
4977                return 0;
4978}
4979
4980int is_bypass(bpctl_dev_t *pbpctl_dev)
4981{
4982        if (!pbpctl_dev)
4983                return -1;
4984
4985        if ((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2))
4986                return 1;
4987        else
4988                return 0;
4989}
4990
4991int get_tx_fn(bpctl_dev_t *pbpctl_dev)
4992{
4993        bpctl_dev_t *pbpctl_dev_b = NULL;
4994        if (!pbpctl_dev)
4995                return -1;
4996
4997        if ((pbpctl_dev->bp_caps & TPL_CAP) &&
4998            (pbpctl_dev->bp_caps & SW_CTL_CAP)) {
4999                if ((pbpctl_dev->bp_tpl_flag))
5000                        return BP_NOT_CAP;
5001        } else {
5002                pbpctl_dev_b = get_master_port_fn(pbpctl_dev);
5003                if (pbpctl_dev_b &&
5004                    (pbpctl_dev_b->bp_caps & TPL_CAP) &&
5005                    (pbpctl_dev_b->bp_tpl_flag))
5006                        return BP_NOT_CAP;
5007        }
5008        return tx_status(pbpctl_dev);
5009}
5010
5011int get_bp_force_link_fn(int dev_num)
5012{
5013        static bpctl_dev_t *bpctl_dev_curr;
5014
5015        if ((dev_num < 0) || (dev_num > device_num)
5016            || (bpctl_dev_arr[dev_num].pdev == NULL))
5017                return -1;
5018        bpctl_dev_curr = &bpctl_dev_arr[dev_num];
5019
5020        return bp_force_link_status(bpctl_dev_curr);
5021}
5022
5023static int get_bypass_link_status(bpctl_dev_t *pbpctl_dev)
5024{
5025        if (!pbpctl_dev)
5026                return -1;
5027
5028        if (pbpctl_dev->media_type == BP_FIBER)
5029                return ((BPCTL_READ_REG(pbpctl_dev, CTRL) &
5030                         BPCTLI_CTRL_SWDPIN1));
5031        else
5032                return ((BPCTL_READ_REG(pbpctl_dev, STATUS) &
5033                         BPCTLI_STATUS_LU));
5034
5035}
5036
5037static void bp_tpl_timer_fn(unsigned long param)
5038{
5039        bpctl_dev_t *pbpctl_dev = (bpctl_dev_t *) param;
5040        uint32_t link1, link2;
5041        bpctl_dev_t *pbpctl_dev_b = NULL;
5042
5043        pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
5044        if (!pbpctl_dev_b)
5045                return;
5046
5047        if (!pbpctl_dev->bp_tpl_flag) {
5048                set_tx(pbpctl_dev_b, 1);
5049                set_tx(pbpctl_dev, 1);
5050                return;
5051        }
5052        link1 = get_bypass_link_status(pbpctl_dev);
5053
5054        link2 = get_bypass_link_status(pbpctl_dev_b);
5055        if ((link1) && (tx_status(pbpctl_dev))) {
5056                if ((!link2) && (tx_status(pbpctl_dev_b)))
5057                        set_tx(pbpctl_dev, 0);
5058                else if (!tx_status(pbpctl_dev_b))
5059                        set_tx(pbpctl_dev_b, 1);
5060        } else if ((!link1) && (tx_status(pbpctl_dev))) {
5061                if ((link2) && (tx_status(pbpctl_dev_b)))
5062                        set_tx(pbpctl_dev_b, 0);
5063        } else if ((link1) && (!tx_status(pbpctl_dev))) {
5064                if ((link2) && (tx_status(pbpctl_dev_b)))
5065                        set_tx(pbpctl_dev, 1);
5066        } else if ((!link1) && (!tx_status(pbpctl_dev))) {
5067                if ((link2) && (tx_status(pbpctl_dev_b)))
5068                        set_tx(pbpctl_dev, 1);
5069        }
5070
5071        mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies + BP_LINK_MON_DELAY * HZ);
5072}
5073
5074void remove_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev)
5075{
5076        bpctl_dev_t *pbpctl_dev_b = NULL;
5077        if (!pbpctl_dev)
5078                return;
5079        pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
5080
5081        if (pbpctl_dev->bp_caps & TPL_CAP) {
5082                del_timer_sync(&pbpctl_dev->bp_tpl_timer);
5083                pbpctl_dev->bp_tpl_flag = 0;
5084                pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
5085                if (pbpctl_dev_b)
5086                        set_tx(pbpctl_dev_b, 1);
5087                set_tx(pbpctl_dev, 1);
5088        }
5089        return;
5090}
5091
5092int init_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev)
5093{
5094        if (!pbpctl_dev)
5095                return -1;
5096        if (pbpctl_dev->bp_caps & TPL_CAP) {
5097                init_timer(&pbpctl_dev->bp_tpl_timer);
5098                pbpctl_dev->bp_tpl_timer.function = &bp_tpl_timer_fn;
5099                pbpctl_dev->bp_tpl_timer.data = (unsigned long)pbpctl_dev;
5100                return BP_OK;
5101        }
5102        return BP_NOT_CAP;
5103}
5104
5105int set_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev, unsigned int param)
5106{
5107        if (!pbpctl_dev)
5108                return -1;
5109        if (pbpctl_dev->bp_caps & TPL_CAP) {
5110                if ((param) && (!pbpctl_dev->bp_tpl_flag)) {
5111                        pbpctl_dev->bp_tpl_flag = param;
5112                        mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies + 1);
5113                        return BP_OK;
5114                };
5115                if ((!param) && (pbpctl_dev->bp_tpl_flag))
5116                        remove_bypass_tpl_auto(pbpctl_dev);
5117
5118                return BP_OK;
5119        }
5120        return BP_NOT_CAP;
5121}
5122
5123int get_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev)
5124{
5125        if (!pbpctl_dev)
5126                return -1;
5127        if (pbpctl_dev->bp_caps & TPL_CAP)
5128                return pbpctl_dev->bp_tpl_flag;
5129
5130        return BP_NOT_CAP;
5131}
5132
5133int set_tpl_fn(bpctl_dev_t *pbpctl_dev, int tpl_mode)
5134{
5135
5136        bpctl_dev_t *pbpctl_dev_b = NULL;
5137        if (!pbpctl_dev)
5138                return -1;
5139
5140        pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
5141
5142        if (pbpctl_dev->bp_caps & TPL_CAP) {
5143                if (tpl_mode) {
5144                        pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
5145                        if (pbpctl_dev_b)
5146                                set_tx(pbpctl_dev_b, 1);
5147                        set_tx(pbpctl_dev, 1);
5148                }
5149                if ((TPL_IF_SERIES(pbpctl_dev->subdevice)) ||
5150                    (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX)) {
5151                        pbpctl_dev->bp_tpl_flag = tpl_mode;
5152                        if (!tpl_mode)
5153                                tpl_hw_off(pbpctl_dev);
5154                        else
5155                                tpl_hw_on(pbpctl_dev);
5156                } else
5157                        set_bypass_tpl_auto(pbpctl_dev, tpl_mode);
5158                return 0;
5159        }
5160        return BP_NOT_CAP;
5161}
5162
5163int get_tpl_fn(bpctl_dev_t *pbpctl_dev)
5164{
5165        int ret = BP_NOT_CAP;
5166        if (!pbpctl_dev)
5167                return -1;
5168
5169        if (pbpctl_dev->bp_caps & TPL_CAP) {
5170                if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX)
5171                        return tpl2_flag_status(pbpctl_dev);
5172                ret = pbpctl_dev->bp_tpl_flag;
5173        }
5174        return ret;
5175}
5176
5177int set_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode)
5178{
5179        if (!pbpctl_dev)
5180                return -1;
5181
5182        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
5183                /* bp_lock(pbp_device_block); */
5184                cmnd_on(pbpctl_dev);
5185                if (!tap_mode)
5186                        bp_wait_at_pwup_dis(pbpctl_dev);
5187                else
5188                        bp_wait_at_pwup_en(pbpctl_dev);
5189                cmnd_off(pbpctl_dev);
5190
5191                /* bp_unlock(pbp_device_block); */
5192                return BP_OK;
5193        }
5194        return BP_NOT_CAP;
5195}
5196
5197int get_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev)
5198{
5199        int ret = 0;
5200        if (!pbpctl_dev)
5201                return -1;
5202
5203        /* bp_lock(pbp_device_block); */
5204        ret = bp_wait_at_pwup_status(pbpctl_dev);
5205        /* bp_unlock(pbp_device_block); */
5206
5207        return ret;
5208}
5209
5210int set_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev, int tap_mode)
5211{
5212        if (!pbpctl_dev)
5213                return -1;
5214
5215        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
5216                /*   bp_lock(pbp_device_block); */
5217                cmnd_on(pbpctl_dev);
5218
5219                if (!tap_mode)
5220                        bp_hw_reset_dis(pbpctl_dev);
5221                else
5222                        bp_hw_reset_en(pbpctl_dev);
5223                cmnd_off(pbpctl_dev);
5224                /*    bp_unlock(pbp_device_block); */
5225                return BP_OK;
5226        }
5227        return BP_NOT_CAP;
5228}
5229
5230int get_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev)
5231{
5232        int ret = 0;
5233        if (!pbpctl_dev)
5234                return -1;
5235
5236        /* bp_lock(pbp_device_block); */
5237        ret = bp_hw_reset_status(pbpctl_dev);
5238
5239        /* bp_unlock(pbp_device_block); */
5240
5241        return ret;
5242}
5243
5244
5245int get_bypass_info_fn(bpctl_dev_t *pbpctl_dev, char *dev_name,
5246                       char *add_param)
5247{
5248        if (!pbpctl_dev)
5249                return -1;
5250        if (!is_bypass_fn(pbpctl_dev))
5251                return -1;
5252        strcpy(dev_name, pbpctl_dev->name);
5253        *add_param = pbpctl_dev->bp_fw_ver;
5254        return 0;
5255}
5256
5257int get_dev_idx_bsf(int bus, int slot, int func)
5258{
5259        int idx_dev = 0;
5260        for (idx_dev = 0;
5261             ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num));
5262             idx_dev++) {
5263                if ((bus == bpctl_dev_arr[idx_dev].bus)
5264                    && (slot == bpctl_dev_arr[idx_dev].slot)
5265                    && (func == bpctl_dev_arr[idx_dev].func))
5266
5267                        return idx_dev;
5268        }
5269        return -1;
5270}
5271
5272static void str_low(char *str)
5273{
5274        int i;
5275
5276        for (i = 0; i < strlen(str); i++)
5277                if ((str[i] >= 65) && (str[i] <= 90))
5278                        str[i] += 32;
5279}
5280
5281static unsigned long str_to_hex(char *p)
5282{
5283        unsigned long hex = 0;
5284        unsigned long length = strlen(p), shift = 0;
5285        unsigned char dig = 0;
5286
5287        str_low(p);
5288        length = strlen(p);
5289
5290        if (length == 0)
5291                return 0;
5292
5293        do {
5294                dig = p[--length];
5295                dig = dig < 'a' ? (dig - '0') : (dig - 'a' + 0xa);
5296                hex |= (dig << shift);
5297                shift += 4;
5298        } while (length);
5299        return hex;
5300}
5301
5302static int get_dev_idx(int ifindex)
5303{
5304        int idx_dev = 0;
5305
5306        for (idx_dev = 0;
5307             ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num));
5308             idx_dev++) {
5309                if (ifindex == bpctl_dev_arr[idx_dev].ifindex)
5310                        return idx_dev;
5311        }
5312
5313        return -1;
5314}
5315
5316static bpctl_dev_t *get_dev_idx_p(int ifindex)
5317{
5318        int idx_dev = 0;
5319
5320        for (idx_dev = 0;
5321             ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num));
5322             idx_dev++) {
5323                if (ifindex == bpctl_dev_arr[idx_dev].ifindex)
5324                        return &bpctl_dev_arr[idx_dev];
5325        }
5326
5327        return NULL;
5328}
5329
5330static void if_scan_init(void)
5331{
5332        int idx_dev = 0;
5333        struct net_device *dev;
5334        int ifindex;
5335        /* rcu_read_lock(); */
5336        /* rtnl_lock();     */
5337        /* rcu_read_lock(); */
5338
5339        for_each_netdev(&init_net, dev) {
5340
5341                struct ethtool_drvinfo drvinfo;
5342                char cbuf[32];
5343                char *buf = NULL;
5344                char res[10];
5345                int i = 0;
5346                int bus = 0, slot = 0, func = 0;
5347                ifindex = dev->ifindex;
5348
5349                memset(res, 0, 10);
5350                memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
5351
5352                if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) {
5353                        memset(&drvinfo, 0, sizeof(drvinfo));
5354                        dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
5355                } else
5356                        continue;
5357                if (!strcmp(drvinfo.bus_info, "N/A"))
5358                        continue;
5359                memcpy(&cbuf, drvinfo.bus_info, 32);
5360                buf = &cbuf[0];
5361
5362                while (*buf++ != ':')
5363                        ;
5364                for (i = 0; i < 10; i++, buf++) {
5365                        if (*buf == ':')
5366                                break;
5367                        res[i] = *buf;
5368
5369                }
5370                buf++;
5371                bus = str_to_hex(res);
5372                memset(res, 0, 10);
5373
5374                for (i = 0; i < 10; i++, buf++) {
5375                        if (*buf == '.')
5376                                break;
5377                        res[i] = *buf;
5378
5379                }
5380                buf++;
5381                slot = str_to_hex(res);
5382                func = str_to_hex(buf);
5383                idx_dev = get_dev_idx_bsf(bus, slot, func);
5384
5385                if (idx_dev != -1) {
5386
5387                        bpctl_dev_arr[idx_dev].ifindex = ifindex;
5388                        bpctl_dev_arr[idx_dev].ndev = dev;
5389
5390                }
5391
5392        }
5393        /* rtnl_unlock();     */
5394        /* rcu_read_unlock(); */
5395
5396}
5397
5398static long device_ioctl(struct file *file,     /* see include/linux/fs.h */
5399                         unsigned int ioctl_num,        /* number and param for ioctl */
5400                         unsigned long ioctl_param)
5401{
5402        struct bpctl_cmd bpctl_cmd;
5403        int dev_idx = 0;
5404        bpctl_dev_t *pbpctl_dev_out;
5405        void __user *argp = (void __user *)ioctl_param;
5406        int ret = 0;
5407        unsigned long flags;
5408
5409        static bpctl_dev_t *pbpctl_dev;
5410
5411        /* lock_kernel(); */
5412        if (down_interruptible(&bpctl_sema))
5413                return -ERESTARTSYS;
5414        /* local_irq_save(flags); */
5415        /* if(!spin_trylock_irqsave(&bpvm_lock)){
5416           local_irq_restore(flags);
5417           unlock_bpctl();
5418           unlock_kernel();
5419           return -1;
5420           } */
5421        /* spin_lock_irqsave(&bpvm_lock, flags); */
5422
5423/*
5424* Switch according to the ioctl called
5425*/
5426        if (ioctl_num == IOCTL_TX_MSG(IF_SCAN)) {
5427                if_scan_init();
5428                ret = SUCCESS;
5429                goto bp_exit;
5430        }
5431        if (copy_from_user(&bpctl_cmd, argp, sizeof(struct bpctl_cmd))) {
5432
5433                ret = -EFAULT;
5434                goto bp_exit;
5435        }
5436
5437        if (ioctl_num == IOCTL_TX_MSG(GET_DEV_NUM)) {
5438                bpctl_cmd.out_param[0] = device_num;
5439                if (copy_to_user
5440                    (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) {
5441                        ret = -EFAULT;
5442                        goto bp_exit;
5443                }
5444                ret = SUCCESS;
5445                goto bp_exit;
5446
5447        }
5448        /* lock_bpctl();      */
5449        /* preempt_disable(); */
5450        local_irq_save(flags);
5451        if (!spin_trylock(&bpvm_lock)) {
5452                local_irq_restore(flags);
5453                unlock_bpctl();
5454                return -1;
5455        }
5456
5457/*      preempt_disable();
5458        rcu_read_lock();
5459        spin_lock_irqsave(&bpvm_lock, flags);
5460*/
5461        if ((bpctl_cmd.in_param[5]) ||
5462            (bpctl_cmd.in_param[6]) || (bpctl_cmd.in_param[7]))
5463                dev_idx = get_dev_idx_bsf(bpctl_cmd.in_param[5],
5464                                          bpctl_cmd.in_param[6],
5465                                          bpctl_cmd.in_param[7]);
5466        else if (bpctl_cmd.in_param[1] == 0)
5467                dev_idx = bpctl_cmd.in_param[0];
5468        else
5469                dev_idx = get_dev_idx(bpctl_cmd.in_param[1]);
5470
5471        if (dev_idx < 0 || dev_idx > device_num) {
5472                /* unlock_bpctl();
5473                   preempt_enable(); */
5474                ret = -EOPNOTSUPP;
5475                /* preempt_enable();
5476                   rcu_read_unlock();  */
5477                spin_unlock_irqrestore(&bpvm_lock, flags);
5478                goto bp_exit;
5479        }
5480
5481        bpctl_cmd.out_param[0] = bpctl_dev_arr[dev_idx].bus;
5482        bpctl_cmd.out_param[1] = bpctl_dev_arr[dev_idx].slot;
5483        bpctl_cmd.out_param[2] = bpctl_dev_arr[dev_idx].func;
5484        bpctl_cmd.out_param[3] = bpctl_dev_arr[dev_idx].ifindex;
5485
5486        if ((bpctl_dev_arr[dev_idx].bp_10gb)
5487            && (!(bpctl_dev_arr[dev_idx].ifindex))) {
5488                printk("Please load network driver for %s adapter!\n",
5489                       bpctl_dev_arr[dev_idx].name);
5490                bpctl_cmd.status = -1;
5491                ret = SUCCESS;
5492                /* preempt_enable(); */
5493                /* rcu_read_unlock(); */
5494                spin_unlock_irqrestore(&bpvm_lock, flags);
5495                goto bp_exit;
5496
5497        }
5498        if ((bpctl_dev_arr[dev_idx].bp_10gb) && (bpctl_dev_arr[dev_idx].ndev)) {
5499                if (!(bpctl_dev_arr[dev_idx].ndev->flags & IFF_UP)) {
5500                        if (!(bpctl_dev_arr[dev_idx].ndev->flags & IFF_UP)) {
5501                                printk
5502                                    ("Please bring up network interfaces for %s adapter!\n",
5503                                     bpctl_dev_arr[dev_idx].name);
5504                                bpctl_cmd.status = -1;
5505                                ret = SUCCESS;
5506                                /* preempt_enable(); */
5507                                /* rcu_read_unlock(); */
5508                                spin_unlock_irqrestore(&bpvm_lock, flags);
5509                                goto bp_exit;
5510                        }
5511
5512                }
5513        }
5514
5515        if ((dev_idx < 0) || (dev_idx > device_num)
5516            || (bpctl_dev_arr[dev_idx].pdev == NULL)) {
5517                bpctl_cmd.status = -1;
5518                goto bpcmd_exit;
5519        }
5520
5521        pbpctl_dev = &bpctl_dev_arr[dev_idx];
5522
5523        switch (ioctl_num) {
5524        case IOCTL_TX_MSG(SET_BYPASS_PWOFF):
5525                bpctl_cmd.status =
5526                    set_bypass_pwoff_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5527                break;
5528
5529        case IOCTL_TX_MSG(GET_BYPASS_PWOFF):
5530                bpctl_cmd.status = get_bypass_pwoff_fn(pbpctl_dev);
5531                break;
5532
5533        case IOCTL_TX_MSG(SET_BYPASS_PWUP):
5534                bpctl_cmd.status =
5535                    set_bypass_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5536                break;
5537
5538        case IOCTL_TX_MSG(GET_BYPASS_PWUP):
5539                bpctl_cmd.status = get_bypass_pwup_fn(pbpctl_dev);
5540                break;
5541
5542        case IOCTL_TX_MSG(SET_BYPASS_WD):
5543                bpctl_cmd.status =
5544                    set_bypass_wd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5545                break;
5546
5547        case IOCTL_TX_MSG(GET_BYPASS_WD):
5548                bpctl_cmd.status =
5549                    get_bypass_wd_fn(pbpctl_dev, (int *)&(bpctl_cmd.data[0]));
5550                break;
5551
5552        case IOCTL_TX_MSG(GET_WD_EXPIRE_TIME):
5553                bpctl_cmd.status =
5554                    get_wd_expire_time_fn(pbpctl_dev,
5555                                          (int *)&(bpctl_cmd.data[0]));
5556                break;
5557
5558        case IOCTL_TX_MSG(RESET_BYPASS_WD_TIMER):
5559                bpctl_cmd.status = reset_bypass_wd_timer_fn(pbpctl_dev);
5560                break;
5561
5562        case IOCTL_TX_MSG(GET_WD_SET_CAPS):
5563                bpctl_cmd.status = get_wd_set_caps_fn(pbpctl_dev);
5564                break;
5565
5566        case IOCTL_TX_MSG(SET_STD_NIC):
5567                bpctl_cmd.status =
5568                    set_std_nic_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5569                break;
5570
5571        case IOCTL_TX_MSG(GET_STD_NIC):
5572                bpctl_cmd.status = get_std_nic_fn(pbpctl_dev);
5573                break;
5574
5575        case IOCTL_TX_MSG(SET_TAP):
5576                bpctl_cmd.status =
5577                    set_tap_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5578                break;
5579
5580        case IOCTL_TX_MSG(GET_TAP):
5581                bpctl_cmd.status = get_tap_fn(pbpctl_dev);
5582                break;
5583
5584        case IOCTL_TX_MSG(GET_TAP_CHANGE):
5585                bpctl_cmd.status = get_tap_change_fn(pbpctl_dev);
5586                break;
5587
5588        case IOCTL_TX_MSG(SET_DIS_TAP):
5589                bpctl_cmd.status =
5590                    set_dis_tap_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5591                break;
5592
5593        case IOCTL_TX_MSG(GET_DIS_TAP):
5594                bpctl_cmd.status = get_dis_tap_fn(pbpctl_dev);
5595                break;
5596
5597        case IOCTL_TX_MSG(SET_TAP_PWUP):
5598                bpctl_cmd.status =
5599                    set_tap_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5600                break;
5601
5602        case IOCTL_TX_MSG(GET_TAP_PWUP):
5603                bpctl_cmd.status = get_tap_pwup_fn(pbpctl_dev);
5604                break;
5605
5606        case IOCTL_TX_MSG(SET_WD_EXP_MODE):
5607                bpctl_cmd.status =
5608                    set_wd_exp_mode_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5609                break;
5610
5611        case IOCTL_TX_MSG(GET_WD_EXP_MODE):
5612                bpctl_cmd.status = get_wd_exp_mode_fn(pbpctl_dev);
5613                break;
5614
5615        case IOCTL_TX_MSG(GET_DIS_BYPASS):
5616                bpctl_cmd.status = get_dis_bypass_fn(pbpctl_dev);
5617                break;
5618
5619        case IOCTL_TX_MSG(SET_DIS_BYPASS):
5620                bpctl_cmd.status =
5621                    set_dis_bypass_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5622                break;
5623
5624        case IOCTL_TX_MSG(GET_BYPASS_CHANGE):
5625                bpctl_cmd.status = get_bypass_change_fn(pbpctl_dev);
5626                break;
5627
5628        case IOCTL_TX_MSG(GET_BYPASS):
5629                bpctl_cmd.status = get_bypass_fn(pbpctl_dev);
5630                break;
5631
5632        case IOCTL_TX_MSG(SET_BYPASS):
5633                bpctl_cmd.status =
5634                    set_bypass_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5635                break;
5636
5637        case IOCTL_TX_MSG(GET_BYPASS_CAPS):
5638                bpctl_cmd.status = get_bypass_caps_fn(pbpctl_dev);
5639                /*preempt_enable(); */
5640                /*rcu_read_unlock();*/
5641                spin_unlock_irqrestore(&bpvm_lock, flags);
5642                if (copy_to_user
5643                    (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) {
5644                        /*unlock_bpctl();   */
5645                        /*preempt_enable(); */
5646                        ret = -EFAULT;
5647                        goto bp_exit;
5648                }
5649                goto bp_exit;
5650
5651        case IOCTL_TX_MSG(GET_BYPASS_SLAVE):
5652                bpctl_cmd.status =
5653                    get_bypass_slave_fn(pbpctl_dev, &pbpctl_dev_out);
5654                if (bpctl_cmd.status == 1) {
5655                        bpctl_cmd.out_param[4] = pbpctl_dev_out->bus;
5656                        bpctl_cmd.out_param[5] = pbpctl_dev_out->slot;
5657                        bpctl_cmd.out_param[6] = pbpctl_dev_out->func;
5658                        bpctl_cmd.out_param[7] = pbpctl_dev_out->ifindex;
5659                }
5660                break;
5661
5662        case IOCTL_TX_MSG(IS_BYPASS):
5663                bpctl_cmd.status = is_bypass(pbpctl_dev);
5664                break;
5665        case IOCTL_TX_MSG(SET_TX):
5666                bpctl_cmd.status = set_tx_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5667                break;
5668        case IOCTL_TX_MSG(GET_TX):
5669                bpctl_cmd.status = get_tx_fn(pbpctl_dev);
5670                break;
5671        case IOCTL_TX_MSG(SET_WD_AUTORESET):
5672                bpctl_cmd.status =
5673                    set_wd_autoreset_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5674
5675                break;
5676        case IOCTL_TX_MSG(GET_WD_AUTORESET):
5677
5678                bpctl_cmd.status = get_wd_autoreset_fn(pbpctl_dev);
5679                break;
5680        case IOCTL_TX_MSG(SET_DISC):
5681                bpctl_cmd.status =
5682                    set_disc_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5683                break;
5684        case IOCTL_TX_MSG(GET_DISC):
5685                bpctl_cmd.status = get_disc_fn(pbpctl_dev);
5686                break;
5687        case IOCTL_TX_MSG(GET_DISC_CHANGE):
5688                bpctl_cmd.status = get_disc_change_fn(pbpctl_dev);
5689                break;
5690        case IOCTL_TX_MSG(SET_DIS_DISC):
5691                bpctl_cmd.status =
5692                    set_dis_disc_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5693                break;
5694        case IOCTL_TX_MSG(GET_DIS_DISC):
5695                bpctl_cmd.status = get_dis_disc_fn(pbpctl_dev);
5696                break;
5697        case IOCTL_TX_MSG(SET_DISC_PWUP):
5698                bpctl_cmd.status =
5699                    set_disc_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5700                break;
5701        case IOCTL_TX_MSG(GET_DISC_PWUP):
5702                bpctl_cmd.status = get_disc_pwup_fn(pbpctl_dev);
5703                break;
5704
5705        case IOCTL_TX_MSG(GET_BYPASS_INFO):
5706
5707                bpctl_cmd.status =
5708                    get_bypass_info_fn(pbpctl_dev, (char *)&bpctl_cmd.data,
5709                                       (char *)&bpctl_cmd.out_param[4]);
5710                break;
5711
5712        case IOCTL_TX_MSG(SET_TPL):
5713                bpctl_cmd.status =
5714                    set_tpl_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5715                break;
5716
5717        case IOCTL_TX_MSG(GET_TPL):
5718                bpctl_cmd.status = get_tpl_fn(pbpctl_dev);
5719                break;
5720        case IOCTL_TX_MSG(SET_BP_WAIT_AT_PWUP):
5721                bpctl_cmd.status =
5722                    set_bp_wait_at_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5723                break;
5724
5725        case IOCTL_TX_MSG(GET_BP_WAIT_AT_PWUP):
5726                bpctl_cmd.status = get_bp_wait_at_pwup_fn(pbpctl_dev);
5727                break;
5728        case IOCTL_TX_MSG(SET_BP_HW_RESET):
5729                bpctl_cmd.status =
5730                    set_bp_hw_reset_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5731                break;
5732
5733        case IOCTL_TX_MSG(GET_BP_HW_RESET):
5734                bpctl_cmd.status = get_bp_hw_reset_fn(pbpctl_dev);
5735                break;
5736#ifdef BP_SELF_TEST
5737        case IOCTL_TX_MSG(SET_BP_SELF_TEST):
5738                bpctl_cmd.status =
5739                    set_bp_self_test_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5740
5741                break;
5742        case IOCTL_TX_MSG(GET_BP_SELF_TEST):
5743                bpctl_cmd.status = get_bp_self_test_fn(pbpctl_dev);
5744                break;
5745
5746#endif
5747#if 0
5748        case IOCTL_TX_MSG(SET_DISC_PORT):
5749                bpctl_cmd.status =
5750                    set_disc_port_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5751                break;
5752
5753        case IOCTL_TX_MSG(GET_DISC_PORT):
5754                bpctl_cmd.status = get_disc_port_fn(pbpctl_dev);
5755                break;
5756
5757        case IOCTL_TX_MSG(SET_DISC_PORT_PWUP):
5758                bpctl_cmd.status =
5759                    set_disc_port_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
5760                break;
5761
5762        case IOCTL_TX_MSG(GET_DISC_PORT_PWUP):
5763                bpctl_cmd.status = get_disc_port_pwup_fn(pbpctl_dev);
5764                break;
5765#endif
5766        case IOCTL_TX_MSG(SET_BP_FORCE_LINK):
5767                bpctl_cmd.status =
5768                    set_bp_force_link_fn(dev_idx, bpctl_cmd.in_param[2]);
5769                break;
5770
5771        case IOCTL_TX_MSG(GET_BP_FORCE_LINK):
5772                bpctl_cmd.status = get_bp_force_link_fn(dev_idx);
5773                break;
5774
5775        default:
5776                /*    unlock_bpctl(); */
5777
5778                ret = -EOPNOTSUPP;
5779                /* preempt_enable(); */
5780                /* rcu_read_unlock();*/
5781                spin_unlock_irqrestore(&bpvm_lock, flags);
5782                goto bp_exit;
5783        }
5784        /* unlock_bpctl();   */
5785        /* preempt_enable(); */
5786 bpcmd_exit:
5787        /* rcu_read_unlock(); */
5788        spin_unlock_irqrestore(&bpvm_lock, flags);
5789        if (copy_to_user(argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd)))
5790                ret = -EFAULT;
5791        ret = SUCCESS;
5792 bp_exit:
5793        /* unlock_kernel(); */
5794        /* spin_unlock_irqrestore(&bpvm_lock, flags); */
5795        unlock_bpctl();
5796        /* unlock_kernel(); */
5797        return ret;
5798}
5799
5800static const struct file_operations Fops = {
5801        .owner = THIS_MODULE,
5802        .unlocked_ioctl = device_ioctl,
5803};
5804
5805#ifndef PCI_DEVICE
5806#define PCI_DEVICE(vend, dev) \
5807        .vendor = (vend), .device = (dev), \
5808        .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
5809#endif
5810
5811#define SILICOM_E1000BP_ETHERNET_DEVICE(device_id) {\
5812        PCI_DEVICE(SILICOM_VID, device_id)}
5813
5814enum board_type {
5815        PXG2BPFI,
5816        PXG2BPFIL,
5817        PXG2BPFILX,
5818        PXG2BPFILLX,
5819        PXGBPI,
5820        PXGBPIG,
5821        PXG2TBFI,
5822        PXG4BPI,
5823        PXG4BPFI,
5824        PEG4BPI,
5825        PEG2BPI,
5826        PEG4BPIN,
5827        PEG2BPFI,
5828        PEG2BPFILX,
5829        PMCXG2BPFI,
5830        PMCXG2BPFIN,
5831        PEG4BPII,
5832        PEG4BPFII,
5833        PXG4BPFILX,
5834        PMCXG2BPIN,
5835        PMCXG4BPIN,
5836        PXG2BISC1,
5837        PEG2TBFI,
5838        PXG2TBI,
5839        PXG4BPFID,
5840        PEG4BPFI,
5841        PEG4BPIPT,
5842        PXG6BPI,
5843        PEG4BPIL,
5844        PMCXG2BPIN2,
5845        PMCXG4BPIN2,
5846        PMCX2BPI,
5847        PEG2BPFID,
5848        PEG2BPFIDLX,
5849        PMCX4BPI,
5850        MEG2BPFILN,
5851        MEG2BPFINX,
5852        PEG4BPFILX,
5853        PE10G2BPISR,
5854        PE10G2BPILR,
5855        MHIO8AD,
5856        PE10G2BPICX4,
5857        PEG2BPI5,
5858        PEG6BPI,
5859        PEG4BPFI5,
5860        PEG4BPFI5LX,
5861        MEG2BPFILXLN,
5862        PEG2BPIX1,
5863        MEG2BPFILXNX,
5864        XE10G2BPIT,
5865        XE10G2BPICX4,
5866        XE10G2BPISR,
5867        XE10G2BPILR,
5868        PEG4BPIIO,
5869        XE10G2BPIXR,
5870        PE10GDBISR,
5871        PE10GDBILR,
5872        PEG2BISC6,
5873        PEG6BPIFC,
5874        PE10G2BPTCX4,
5875        PE10G2BPTSR,
5876        PE10G2BPTLR,
5877        PE10G2BPTT,
5878        PEG4BPI6,
5879        PEG4BPFI6,
5880        PEG4BPFI6LX,
5881        PEG4BPFI6ZX,
5882        PEG2BPI6,
5883        PEG2BPFI6,
5884        PEG2BPFI6LX,
5885        PEG2BPFI6ZX,
5886        PEG2BPFI6FLXM,
5887        PEG4BPI6FC,
5888        PEG4BPFI6FC,
5889        PEG4BPFI6FCLX,
5890        PEG4BPFI6FCZX,
5891        PEG6BPI6,
5892        PEG2BPI6SC6,
5893        MEG2BPI6,
5894        XEG2BPI6,
5895        MEG4BPI6,
5896        PEG2BPFI5,
5897        PEG2BPFI5LX,
5898        PXEG4BPFI,
5899        M1EG2BPI6,
5900        M1EG2BPFI6,
5901        M1EG2BPFI6LX,
5902        M1EG2BPFI6ZX,
5903        M1EG4BPI6,
5904        M1EG4BPFI6,
5905        M1EG4BPFI6LX,
5906        M1EG4BPFI6ZX,
5907        M1EG6BPI6,
5908        M1E2G4BPi80,
5909        M1E2G4BPFi80,
5910        M1E2G4BPFi80LX,
5911        M1E2G4BPFi80ZX,
5912        PE210G2SPI9,
5913        M1E10G2BPI9CX4,
5914        M1E10G2BPI9SR,
5915        M1E10G2BPI9LR,
5916        M1E10G2BPI9T,
5917        PE210G2BPI9CX4,
5918        PE210G2BPI9SR,
5919        PE210G2BPI9LR,
5920        PE210G2BPI9T,
5921        M2EG2BPFI6,
5922        M2EG2BPFI6LX,
5923        M2EG2BPFI6ZX,
5924        M2EG4BPI6,
5925        M2EG4BPFI6,
5926        M2EG4BPFI6LX,
5927        M2EG4BPFI6ZX,
5928        M2EG6BPI6,
5929        PEG2DBI6,
5930        PEG2DBFI6,
5931        PEG2DBFI6LX,
5932        PEG2DBFI6ZX,
5933        PE2G4BPi80,
5934        PE2G4BPFi80,
5935        PE2G4BPFi80LX,
5936        PE2G4BPFi80ZX,
5937        PE2G4BPi80L,
5938        M6E2G8BPi80A,
5939
5940        PE2G2BPi35,
5941        PAC1200BPi35,
5942        PE2G2BPFi35,
5943        PE2G2BPFi35LX,
5944        PE2G2BPFi35ZX,
5945        PE2G4BPi35,
5946        PE2G4BPi35L,
5947        PE2G4BPFi35,
5948        PE2G4BPFi35LX,
5949        PE2G4BPFi35ZX,
5950
5951        PE2G6BPi35,
5952        PE2G6BPi35CX,
5953
5954        PE2G2BPi80,
5955        PE2G2BPFi80,
5956        PE2G2BPFi80LX,
5957        PE2G2BPFi80ZX,
5958        M2E10G2BPI9CX4,
5959        M2E10G2BPI9SR,
5960        M2E10G2BPI9LR,
5961        M2E10G2BPI9T,
5962        M6E2G8BPi80,
5963        PE210G2DBi9SR,
5964        PE210G2DBi9SRRB,
5965        PE210G2DBi9LR,
5966        PE210G2DBi9LRRB,
5967        PE310G4DBi940SR,
5968        PE310G4BPi9T,
5969        PE310G4BPi9SR,
5970        PE310G4BPi9LR,
5971        PE210G2BPi40,
5972};
5973
5974typedef struct _bpmod_info_t {
5975        unsigned int vendor;
5976        unsigned int device;
5977        unsigned int subvendor;
5978        unsigned int subdevice;
5979        unsigned int index;
5980        char *bp_name;
5981
5982} bpmod_info_t;
5983
5984typedef struct _dev_desc {
5985        char *name;
5986} dev_desc_t;
5987
5988dev_desc_t dev_desc[] = {
5989        {"Silicom Bypass PXG2BPFI-SD series adapter"},
5990        {"Silicom Bypass PXG2BPFIL-SD series adapter"},
5991        {"Silicom Bypass PXG2BPFILX-SD series adapter"},
5992        {"Silicom Bypass PXG2BPFILLX-SD series adapter"},
5993        {"Silicom Bypass PXG2BPI-SD series adapter"},
5994        {"Silicom Bypass PXG2BPIG-SD series adapter"},
5995        {"Silicom Bypass PXG2TBFI-SD series adapter"},
5996        {"Silicom Bypass PXG4BPI-SD series adapter"},
5997        {"Silicom Bypass PXG4BPFI-SD series adapter"},
5998        {"Silicom Bypass PEG4BPI-SD series adapter"},
5999        {"Silicom Bypass PEG2BPI-SD series adapter"},
6000        {"Silicom Bypass PEG4BPIN-SD series adapter"},
6001        {"Silicom Bypass PEG2BPFI-SD series adapter"},
6002        {"Silicom Bypass PEG2BPFI-LX-SD series adapter"},
6003        {"Silicom Bypass PMCX2BPFI-SD series adapter"},
6004        {"Silicom Bypass PMCX2BPFI-N series adapter"},
6005        {"Intel Bypass PEG2BPII series adapter"},
6006        {"Intel Bypass PEG2BPFII series adapter"},
6007        {"Silicom Bypass PXG4BPFILX-SD series adapter"},
6008        {"Silicom Bypass PMCX2BPI-N series adapter"},
6009        {"Silicom Bypass PMCX4BPI-N series adapter"},
6010        {"Silicom Bypass PXG2BISC1-SD series adapter"},
6011        {"Silicom Bypass PEG2TBFI-SD series adapter"},
6012        {"Silicom Bypass PXG2TBI-SD series adapter"},
6013        {"Silicom Bypass PXG4BPFID-SD series adapter"},
6014        {"Silicom Bypass PEG4BPFI-SD series adapter"},
6015        {"Silicom Bypass PEG4BPIPT-SD series adapter"},
6016        {"Silicom Bypass PXG6BPI-SD series adapter"},
6017        {"Silicom Bypass PEG4BPIL-SD series adapter"},
6018        {"Silicom Bypass PMCX2BPI-N2 series adapter"},
6019        {"Silicom Bypass PMCX4BPI-N2 series adapter"},
6020        {"Silicom Bypass PMCX2BPI-SD series adapter"},
6021        {"Silicom Bypass PEG2BPFID-SD series adapter"},
6022        {"Silicom Bypass PEG2BPFIDLX-SD series adapter"},
6023        {"Silicom Bypass PMCX4BPI-SD series adapter"},
6024        {"Silicom Bypass MEG2BPFILN-SD series adapter"},
6025        {"Silicom Bypass MEG2BPFINX-SD series adapter"},
6026        {"Silicom Bypass PEG4BPFILX-SD series adapter"},
6027        {"Silicom Bypass PE10G2BPISR-SD series adapter"},
6028        {"Silicom Bypass PE10G2BPILR-SD series adapter"},
6029        {"Silicom Bypass MHIO8AD-SD series adapter"},
6030        {"Silicom Bypass PE10G2BPICX4-SD series adapter"},
6031        {"Silicom Bypass PEG2BPI5-SD series adapter"},
6032        {"Silicom Bypass PEG6BPI5-SD series adapter"},
6033        {"Silicom Bypass PEG4BPFI5-SD series adapter"},
6034        {"Silicom Bypass PEG4BPFI5LX-SD series adapter"},
6035        {"Silicom Bypass MEG2BPFILXLN-SD series adapter"},
6036        {"Silicom Bypass PEG2BPIX1-SD series adapter"},
6037        {"Silicom Bypass MEG2BPFILXNX-SD series adapter"},
6038        {"Silicom Bypass XE10G2BPIT-SD series adapter"},
6039        {"Silicom Bypass XE10G2BPICX4-SD series adapter"},
6040        {"Silicom Bypass XE10G2BPISR-SD series adapter"},
6041        {"Silicom Bypass XE10G2BPILR-SD series adapter"},
6042        {"Intel Bypass PEG2BPFII0 series adapter"},
6043        {"Silicom Bypass XE10G2BPIXR series adapter"},
6044        {"Silicom Bypass PE10G2DBISR series adapter"},
6045        {"Silicom Bypass PEG2BI5SC6 series adapter"},
6046        {"Silicom Bypass PEG6BPI5FC series adapter"},
6047
6048        {"Silicom Bypass PE10G2BPTCX4 series adapter"},
6049        {"Silicom Bypass PE10G2BPTSR series adapter"},
6050        {"Silicom Bypass PE10G2BPTLR series adapter"},
6051        {"Silicom Bypass PE10G2BPTT series adapter"},
6052        {"Silicom Bypass PEG4BPI6 series adapter"},
6053        {"Silicom Bypass PEG4BPFI6 series adapter"},
6054        {"Silicom Bypass PEG4BPFI6LX series adapter"},
6055        {"Silicom Bypass PEG4BPFI6ZX series adapter"},
6056        {"Silicom Bypass PEG2BPI6 series adapter"},
6057        {"Silicom Bypass PEG2BPFI6 series adapter"},
6058        {"Silicom Bypass PEG2BPFI6LX series adapter"},
6059        {"Silicom Bypass PEG2BPFI6ZX series adapter"},
6060        {"Silicom Bypass PEG2BPFI6FLXM series adapter"},
6061        {"Silicom Bypass PEG4BPI6FC series adapter"},
6062        {"Silicom Bypass PEG4BPFI6FC series adapter"},
6063        {"Silicom Bypass PEG4BPFI6FCLX series adapter"},
6064        {"Silicom Bypass PEG4BPFI6FCZX series adapter"},
6065        {"Silicom Bypass PEG6BPI6 series adapter"},
6066        {"Silicom Bypass PEG2BPI6SC6 series adapter"},
6067        {"Silicom Bypass MEG2BPI6 series adapter"},
6068        {"Silicom Bypass XEG2BPI6 series adapter"},
6069        {"Silicom Bypass MEG4BPI6 series adapter"},
6070        {"Silicom Bypass PEG2BPFI5-SD series adapter"},
6071        {"Silicom Bypass PEG2BPFI5LX-SD series adapter"},
6072        {"Silicom Bypass PXEG4BPFI-SD series adapter"},
6073        {"Silicom Bypass MxEG2BPI6 series adapter"},
6074        {"Silicom Bypass MxEG2BPFI6 series adapter"},
6075        {"Silicom Bypass MxEG2BPFI6LX series adapter"},
6076        {"Silicom Bypass MxEG2BPFI6ZX series adapter"},
6077        {"Silicom Bypass MxEG4BPI6 series adapter"},
6078        {"Silicom Bypass MxEG4BPFI6 series adapter"},
6079        {"Silicom Bypass MxEG4BPFI6LX series adapter"},
6080        {"Silicom Bypass MxEG4BPFI6ZX series adapter"},
6081        {"Silicom Bypass MxEG6BPI6 series adapter"},
6082        {"Silicom Bypass MxE2G4BPi80 series adapter"},
6083        {"Silicom Bypass MxE2G4BPFi80 series adapter"},
6084        {"Silicom Bypass MxE2G4BPFi80LX series adapter"},
6085        {"Silicom Bypass MxE2G4BPFi80ZX series adapter"},
6086
6087        {"Silicom Bypass PE210G2SPI9 series adapter"},
6088
6089        {"Silicom Bypass MxE210G2BPI9CX4 series adapter"},
6090        {"Silicom Bypass MxE210G2BPI9SR series adapter"},
6091        {"Silicom Bypass MxE210G2BPI9LR series adapter"},
6092        {"Silicom Bypass MxE210G2BPI9T series adapter"},
6093
6094        {"Silicom Bypass PE210G2BPI9CX4 series adapter"},
6095        {"Silicom Bypass PE210G2BPI9SR series adapter"},
6096        {"Silicom Bypass PE210G2BPI9LR series adapter"},
6097        {"Silicom Bypass PE210G2BPI9T series adapter"},
6098
6099        {"Silicom Bypass M2EG2BPFI6 series adapter"},
6100        {"Silicom Bypass M2EG2BPFI6LX series adapter"},
6101        {"Silicom Bypass M2EG2BPFI6ZX series adapter"},
6102        {"Silicom Bypass M2EG4BPI6 series adapter"},
6103        {"Silicom Bypass M2EG4BPFI6 series adapter"},
6104        {"Silicom Bypass M2EG4BPFI6LX series adapter"},
6105        {"Silicom Bypass M2EG4BPFI6ZX series adapter"},
6106        {"Silicom Bypass M2EG6BPI6 series adapter"},
6107
6108        {"Silicom Bypass PEG2DBI6    series adapter"},
6109        {"Silicom Bypass PEG2DBFI6   series adapter"},
6110        {"Silicom Bypass PEG2DBFI6LX series adapter"},
6111        {"Silicom Bypass PEG2DBFI6ZX series adapter"},
6112
6113        {"Silicom Bypass PE2G4BPi80 series adapter"},
6114        {"Silicom Bypass PE2G4BPFi80 series adapter"},
6115        {"Silicom Bypass PE2G4BPFi80LX series adapter"},
6116        {"Silicom Bypass PE2G4BPFi80ZX series adapter"},
6117
6118        {"Silicom Bypass PE2G4BPi80L series adapter"},
6119        {"Silicom Bypass MxE2G8BPi80A series adapter"},
6120
6121        {"Silicom Bypass PE2G2BPi35 series adapter"},
6122        {"Silicom Bypass PAC1200BPi35 series adapter"},
6123        {"Silicom Bypass PE2G2BPFi35 series adapter"},
6124        {"Silicom Bypass PE2G2BPFi35LX series adapter"},
6125        {"Silicom Bypass PE2G2BPFi35ZX series adapter"},
6126
6127        {"Silicom Bypass PE2G4BPi35 series adapter"},
6128        {"Silicom Bypass PE2G4BPi35L series adapter"},
6129        {"Silicom Bypass PE2G4BPFi35 series adapter"},
6130        {"Silicom Bypass PE2G4BPFi35LX series adapter"},
6131        {"Silicom Bypass PE2G4BPFi35ZX series adapter"},
6132
6133        {"Silicom Bypass PE2G6BPi35 series adapter"},
6134        {"Silicom Bypass PE2G6BPi35CX series adapter"},
6135
6136        {"Silicom Bypass PE2G2BPi80 series adapter"},
6137        {"Silicom Bypass PE2G2BPFi80 series adapter"},
6138        {"Silicom Bypass PE2G2BPFi80LX series adapter"},
6139        {"Silicom Bypass PE2G2BPFi80ZX series adapter"},
6140
6141        {"Silicom Bypass M2E10G2BPI9CX4 series adapter"},
6142        {"Silicom Bypass M2E10G2BPI9SR series adapter"},
6143        {"Silicom Bypass M2E10G2BPI9LR series adapter"},
6144        {"Silicom Bypass M2E10G2BPI9T series adapter"},
6145        {"Silicom Bypass MxE2G8BPi80 series adapter"},
6146        {"Silicom Bypass PE210G2DBi9SR series adapter"},
6147        {"Silicom Bypass PE210G2DBi9SRRB series adapter"},
6148        {"Silicom Bypass PE210G2DBi9LR series adapter"},
6149        {"Silicom Bypass PE210G2DBi9LRRB series adapter"},
6150        {"Silicom Bypass PE310G4DBi9-SR series adapter"},
6151        {"Silicom Bypass PE310G4BPi9T series adapter"},
6152        {"Silicom Bypass PE310G4BPi9SR series adapter"},
6153        {"Silicom Bypass PE310G4BPi9LR series adapter"},
6154        {"Silicom Bypass PE210G2BPi40T series adapter"},
6155        {0},
6156};
6157
6158static bpmod_info_t tx_ctl_pci_tbl[] = {
6159        {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFI_SSID, PXG2BPFI,
6160         "PXG2BPFI-SD"},
6161        {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFIL_SSID, PXG2BPFIL,
6162         "PXG2BPFIL-SD"},
6163        {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILX_SSID, PXG2BPFILX,
6164         "PXG2BPFILX-SD"},
6165        {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILLX_SSID, PXG2BPFILLX,
6166         "PXG2BPFILLXSD"},
6167        {0x8086, 0x1010, SILICOM_SVID, SILICOM_PXGBPI_SSID, PXGBPI,
6168         "PXG2BPI-SD"},
6169        {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXGBPIG_SSID, PXGBPIG,
6170         "PXG2BPIG-SD"},
6171        {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2TBFI_SSID, PXG2TBFI,
6172         "PXG2TBFI-SD"},
6173        {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI,
6174         "PXG4BPI-SD"},
6175        {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI,
6176         "PXG4BPFI-SD"},
6177        {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFILX_SSID, PXG4BPFILX,
6178         "PXG4BPFILX-SD"},
6179        {0x8086, 0x1079, SILICOM_SVID, SILICOM_PEG4BPI_SSID, PEG4BPI,
6180         "PEXG4BPI-SD"},
6181        {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPI_SSID, PEG2BPI,
6182         "PEG2BPI-SD"},
6183        {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIN_SSID, PEG4BPIN,
6184         "PEG4BPI-SD"},
6185        {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFI_SSID, PEG2BPFI,
6186         "PEG2BPFI-SD"},
6187        {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFILX_SSID, PEG2BPFILX,
6188         "PEG2BPFILX-SD"},
6189        {0x8086, 0x107a, SILICOM_SVID, SILICOM_PMCXG2BPFI_SSID, PMCXG2BPFI,
6190         "PMCX2BPFI-SD"},
6191        {0x8086, 0x107a, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPFIN_SSID,
6192         PMCXG2BPFIN, "PMCX2BPFI-N"},
6193        {0x8086, INTEL_PEG4BPII_PID, 0x8086, INTEL_PEG4BPII_SSID, PEG4BPII,
6194         "PEG4BPII"},
6195        {0x8086, INTEL_PEG4BPIIO_PID, 0x8086, INTEL_PEG4BPIIO_SSID, PEG4BPIIO,
6196         "PEG4BPII0"},
6197        {0x8086, INTEL_PEG4BPFII_PID, 0x8086, INTEL_PEG4BPFII_SSID, PEG4BPFII,
6198         "PEG4BPFII"},
6199        {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN_SSID,
6200         PMCXG2BPIN, "PMCX2BPI-N"},
6201        {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN_SSID,
6202         PMCXG4BPIN, "PMCX4BPI-N"},
6203        {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1,
6204         "PXG2BISC1-SD"},
6205        {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2TBFI_SSID, PEG2TBFI,
6206         "PEG2TBFI-SD"},
6207        {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI,
6208         "PXG2TBI-SD"},
6209        {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFID_SSID, PXG4BPFID,
6210         "PXG4BPFID-SD"},
6211        {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI,
6212         "PEG4BPFI-SD"},
6213        {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIPT_SSID, PEG4BPIPT,
6214         "PEG4BPIPT-SD"},
6215        {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG6BPI_SSID, PXG6BPI,
6216         "PXG6BPI-SD"},
6217        {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
6218         SILICOM_PEG4BPIL_SSID /*PCI_ANY_ID */ , PEG4BPIL, "PEG4BPIL-SD"},
6219        {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN2_SSID,
6220         PMCXG2BPIN2, "PMCX2BPI-N2"},
6221        {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN2_SSID,
6222         PMCXG4BPIN2, "PMCX4BPI-N2"},
6223        {0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX2BPI_SSID, PMCX2BPI,
6224         "PMCX2BPI-SD"},
6225        {0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX4BPI_SSID, PMCX4BPI,
6226         "PMCX4BPI-SD"},
6227        {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFID_SSID, PEG2BPFID,
6228         "PEG2BPFID-SD"},
6229        {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFIDLX_SSID, PEG2BPFIDLX,
6230         "PEG2BPFIDLXSD"},
6231        {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILN_SSID, MEG2BPFILN,
6232         "MEG2BPFILN-SD"},
6233        {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFINX_SSID, MEG2BPFINX,
6234         "MEG2BPFINX-SD"},
6235        {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFILX_SSID, PEG4BPFILX,
6236         "PEG4BPFILX-SD"},
6237        {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPISR_SSID,
6238         PE10G2BPISR, "PE10G2BPISR"},
6239        {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPILR_SSID,
6240         PE10G2BPILR, "PE10G2BPILR"},
6241        {0x8086, 0x10a9, SILICOM_SVID, SILICOM_MHIO8AD_SSID, MHIO8AD,
6242         "MHIO8AD-SD"},
6243        {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPICX4_SSID,
6244         PE10G2BPISR, "PE10G2BPICX4"},
6245        {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
6246         SILICOM_PEG2BPI5_SSID /*PCI_ANY_ID */ , PEG2BPI5, "PEG2BPI5-SD"},
6247        {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
6248         SILICOM_PEG6BPI_SSID /*PCI_ANY_ID */ , PEG6BPI, "PEG6BPI5"},
6249        {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG4BPFI5_SSID,
6250         PEG4BPFI5, "PEG4BPFI5"},
6251        {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ ,
6252         SILICOM_PEG4BPFI5LX_SSID, PEG4BPFI5LX, "PEG4BPFI5LX"},
6253        {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXLN_SSID, MEG2BPFILXLN,
6254         "MEG2BPFILXLN"},
6255        {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPIX1_SSID, PEG2BPIX1,
6256         "PEG2BPIX1-SD"},
6257        {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXNX_SSID, MEG2BPFILXNX,
6258         "MEG2BPFILXNX"},
6259        {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPIT_SSID, XE10G2BPIT,
6260         "XE10G2BPIT"},
6261        {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPICX4_SSID,
6262         XE10G2BPICX4, "XE10G2BPICX4"},
6263        {0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPISR_SSID, XE10G2BPISR,
6264         "XE10G2BPISR"},
6265        {0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPILR_SSID, XE10G2BPILR,
6266         "XE10G2BPILR"},
6267        {0x8086, 0x10C6, NOKIA_XE10G2BPIXR_SVID, NOKIA_XE10G2BPIXR_SSID,
6268         XE10G2BPIXR, "XE10G2BPIXR"},
6269        {0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBISR_SSID, PE10GDBISR,
6270         "PE10G2DBISR"},
6271        {0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBILR_SSID, PE10GDBILR,
6272         "PE10G2DBILR"},
6273        {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
6274         SILICOM_PEG2BISC6_SSID /*PCI_ANY_ID */ , PEG2BISC6, "PEG2BI5SC6"},
6275        {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
6276         SILICOM_PEG6BPIFC_SSID /*PCI_ANY_ID */ , PEG6BPIFC, "PEG6BPI5FC"},
6277
6278        {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
6279         SILICOM_PE10G2BPTCX4_SSID, PE10G2BPTCX4, "PE10G2BPTCX4"},
6280        {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
6281         SILICOM_PE10G2BPTSR_SSID, PE10G2BPTSR, "PE10G2BPTSR"},
6282        {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
6283         SILICOM_PE10G2BPTLR_SSID, PE10G2BPTLR, "PE10G2BPTLR"},
6284        {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
6285         SILICOM_PE10G2BPTT_SSID, PE10G2BPTT, "PE10G2BPTT"},
6286
6287        /* {BROADCOM_VID, BROADCOM_PE10G2_PID, PCI_ANY_ID, PCI_ANY_ID, PE10G2BPTCX4, "PE10G2BPTCX4"}, */
6288
6289        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6290         SILICOM_PEG4BPI6_SSID /*PCI_ANY_ID */ , PEG4BPI6, "PEG4BPI6"},
6291        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6292         SILICOM_PEG4BPFI6_SSID /*PCI_ANY_ID */ , PEG4BPFI6, "PEG4BPFI6"},
6293        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6294         SILICOM_PEG4BPFI6LX_SSID /*PCI_ANY_ID */ , PEG4BPFI6LX, "PEG4BPFI6LX"},
6295        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6296         SILICOM_PEG4BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6ZX, "PEG4BPFI6ZX"},
6297        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6298         SILICOM_PEG2BPI6_SSID /*PCI_ANY_ID */ , PEG2BPI6, "PEG2BPI6"},
6299        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6300         SILICOM_PEG2BPFI6_SSID /*PCI_ANY_ID */ , PEG2BPFI6, "PEG2BPFI6"},
6301        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6302         SILICOM_PEG2BPFI6LX_SSID /*PCI_ANY_ID */ , PEG2BPFI6LX, "PEG2BPFI6LX"},
6303        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6304         SILICOM_PEG2BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG2BPFI6ZX, "PEG2BPFI6ZX"},
6305        {0x8086, 0x10e7, SILICOM_SVID /*PCI_ANY_ID */ ,
6306         SILICOM_PEG2BPFI6FLXM_SSID /*PCI_ANY_ID */ , PEG2BPFI6FLXM,
6307         "PEG2BPFI6FLXM"},
6308        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6309         SILICOM_PEG4BPI6FC_SSID /*PCI_ANY_ID */ , PEG4BPI6FC, "PEG4BPI6FC"},
6310        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6311         SILICOM_PEG4BPFI6FC_SSID /*PCI_ANY_ID */ , PEG4BPFI6FC, "PEG4BPFI6FC"},
6312        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6313         SILICOM_PEG4BPFI6FCLX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCLX,
6314         "PEG4BPFI6FCLX"},
6315        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6316         SILICOM_PEG4BPFI6FCZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCZX,
6317         "PEG4BPFI6FCZX"},
6318        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6319         SILICOM_PEG6BPI6_SSID /*PCI_ANY_ID */ , PEG6BPI6, "PEG6BPI6"},
6320        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6321         SILICOM_PEG2BPI6SC6_SSID /*PCI_ANY_ID */ , PEG2BPI6SC6,
6322         "PEG6BPI62SC6"},
6323        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6324         SILICOM_MEG2BPI6_SSID /*PCI_ANY_ID */ , MEG2BPI6, "MEG2BPI6"},
6325        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6326         SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID */ , XEG2BPI6, "XEG2BPI6"},
6327        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6328         SILICOM_MEG4BPI6_SSID /*PCI_ANY_ID */ , MEG4BPI6, "MEG4BPI6"},
6329
6330        {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG2BPFI5_SSID,
6331         PEG2BPFI5, "PEG2BPFI5"},
6332        {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ ,
6333         SILICOM_PEG2BPFI5LX_SSID, PEG2BPFI5LX, "PEG2BPFI5LX"},
6334
6335        {0x8086, 0x105f, SILICOM_SVID, SILICOM_PXEG4BPFI_SSID, PXEG4BPFI,
6336         "PXEG4BPFI-SD"},
6337
6338        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6339         SILICOM_M1EG2BPI6_SSID /*PCI_ANY_ID */ , M1EG2BPI6, "MxEG2BPI6"},
6340
6341        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6342         SILICOM_M1EG2BPFI6_SSID /*PCI_ANY_ID */ , M1EG2BPFI6, "MxEG2BPFI6"},
6343        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6344         SILICOM_M1EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6LX,
6345         "MxEG2BPFI6LX"},
6346        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6347         SILICOM_M1EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6ZX,
6348         "MxEG2BPFI6ZX"},
6349
6350        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6351         SILICOM_M1EG4BPI6_SSID /*PCI_ANY_ID */ , M1EG4BPI6, "MxEG4BPI6"},
6352
6353        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6354         SILICOM_M1EG4BPFI6_SSID /*PCI_ANY_ID */ , M1EG4BPFI6, "MxEG4BPFI6"},
6355        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6356         SILICOM_M1EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6LX,
6357         "MxEG4BPFI6LX"},
6358        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6359         SILICOM_M1EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6ZX,
6360         "MxEG4BPFI6ZX"},
6361
6362        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6363         SILICOM_M1EG6BPI6_SSID /*PCI_ANY_ID */ , M1EG6BPI6, "MxEG6BPI6"},
6364
6365        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6366         SILICOM_M1E2G4BPi80_SSID /*PCI_ANY_ID */ , M1E2G4BPi80, "MxE2G4BPi80"},
6367        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6368         SILICOM_M1E2G4BPFi80_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80,
6369         "MxE2G4BPFi80"},
6370        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6371         SILICOM_M1E2G4BPFi80LX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80LX,
6372         "MxE2G4BPFi80LX"},
6373        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6374         SILICOM_M1E2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80ZX,
6375         "MxE2G4BPFi80ZX"},
6376
6377        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6378         SILICOM_M2EG2BPFI6_SSID /*PCI_ANY_ID */ , M2EG2BPFI6, "M2EG2BPFI6"},
6379        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6380         SILICOM_M2EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6LX,
6381         "M2EG2BPFI6LX"},
6382        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6383         SILICOM_M2EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6ZX,
6384         "M2EG2BPFI6ZX"},
6385
6386        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6387         SILICOM_M2EG4BPI6_SSID /*PCI_ANY_ID */ , M2EG4BPI6, "M2EG4BPI6"},
6388
6389        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6390         SILICOM_M2EG4BPFI6_SSID /*PCI_ANY_ID */ , M2EG4BPFI6, "M2EG4BPFI6"},
6391        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6392         SILICOM_M2EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6LX,
6393         "M2EG4BPFI6LX"},
6394        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6395         SILICOM_M2EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6ZX,
6396         "M2EG4BPFI6ZX"},
6397
6398        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6399         SILICOM_M2EG6BPI6_SSID /*PCI_ANY_ID */ , M2EG6BPI6, "M2EG6BPI6"},
6400
6401        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6402         SILICOM_PEG2DBI6_SSID /*PCI_ANY_ID */ , PEG2DBI6, "PEG2DBI6"},
6403        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6404         SILICOM_PEG2DBFI6_SSID /*PCI_ANY_ID */ , PEG2DBFI6, "PEG2DBFI6"},
6405        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6406         SILICOM_PEG2DBFI6LX_SSID /*PCI_ANY_ID */ , PEG2DBFI6LX, "PEG2DBFI6LX"},
6407        {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6408         SILICOM_PEG2DBFI6ZX_SSID /*PCI_ANY_ID */ , PEG2DBFI6ZX, "PEG2DBFI6ZX"},
6409
6410        {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
6411         SILICOM_PE210G2DBi9SR_SSID, PE210G2DBi9SR, "PE210G2DBi9SR"},
6412        {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
6413         SILICOM_PE210G2DBi9LR_SSID, PE210G2DBi9LR, "PE210G2DBi9LR"},
6414        {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
6415         SILICOM_PE310G4DBi940SR_SSID, PE310G4DBi940SR, "PE310G4DBi9SR"},
6416
6417        {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6418         SILICOM_PE310G4BPi9T_SSID, PE310G4BPi9T, "PE310G4BPi9T"},
6419        {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6420         SILICOM_PE310G4BPi9SR_SSID, PE310G4BPi9SR, "PE310G4BPi9SR"},
6421        {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6422         SILICOM_PE310G4BPi9LR_SSID, PE310G4BPi9LR, "PE310G4BPi9LR"},
6423
6424        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6425         SILICOM_PE2G4BPi80_SSID /*PCI_ANY_ID */ , PE2G4BPi80, "PE2G4BPi80"},
6426        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6427         SILICOM_PE2G4BPFi80_SSID /*PCI_ANY_ID */ , PE2G4BPFi80, "PE2G4BPFi80"},
6428        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6429         SILICOM_PE2G4BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80LX,
6430         "PE2G4BPFi80LX"},
6431        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6432         SILICOM_PE2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80ZX,
6433         "PE2G4BPFi80ZX"},
6434
6435        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6436         SILICOM_PE2G4BPi80L_SSID /*PCI_ANY_ID */ , PE2G4BPi80L, "PE2G4BPi80L"},
6437
6438        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6439         SILICOM_M6E2G8BPi80A_SSID /*PCI_ANY_ID */ , M6E2G8BPi80A,
6440         "MxE2G8BPi80A"},
6441
6442        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6443         SILICOM_PE2G2BPi35_SSID /*PCI_ANY_ID */ , PE2G2BPi35, "PE2G2BPi35"},
6444        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6445         SILICOM_PAC1200BPi35_SSID /*PCI_ANY_ID */ , PAC1200BPi35,
6446         "PAC1200BPi35"},
6447
6448        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6449         SILICOM_PE2G2BPFi35_SSID /*PCI_ANY_ID */ , PE2G2BPFi35, "PE2G2BPFi35"},
6450        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6451         SILICOM_PE2G2BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35LX,
6452         "PE2G2BPFi35LX"},
6453        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6454         SILICOM_PE2G2BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35ZX,
6455         "PE2G2BPFi35ZX"},
6456
6457        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6458         SILICOM_PE2G4BPi35_SSID /*PCI_ANY_ID */ , PE2G4BPi35, "PE2G4BPi35"},
6459
6460        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6461         SILICOM_PE2G4BPi35L_SSID /*PCI_ANY_ID */ , PE2G4BPi35L, "PE2G4BPi35L"},
6462
6463        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6464         SILICOM_PE2G4BPFi35_SSID /*PCI_ANY_ID */ , PE2G4BPFi35, "PE2G4BPFi35"},
6465        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6466         SILICOM_PE2G4BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35LX,
6467         "PE2G4BPFi35LX"},
6468        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6469         SILICOM_PE2G4BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35ZX,
6470         "PE2G4BPFi35ZX"},
6471
6472        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6473         SILICOM_PE2G6BPi35_SSID /*PCI_ANY_ID */ , PE2G6BPi35, "PE2G6BPi35"},
6474
6475
6476        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa0, PE2G6BPi35CX,
6477         "PE2G6BPi35CX"},
6478        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa1, PE2G6BPi35CX,
6479         "PE2G6BPi35CX"},
6480        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa2, PE2G6BPi35CX,
6481         "PE2G6BPi35CX"},
6482        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa3, PE2G6BPi35CX,
6483         "PE2G6BPi35CX"},
6484        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa4, PE2G6BPi35CX,
6485         "PE2G6BPi35CX"},
6486        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa5, PE2G6BPi35CX,
6487         "PE2G6BPi35CX"},
6488        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa6, PE2G6BPi35CX,
6489         "PE2G6BPi35CX"},
6490        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa7, PE2G6BPi35CX,
6491         "PE2G6BPi35CX"},
6492        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa8, PE2G6BPi35CX,
6493         "PE2G6BPi35CX"},
6494        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa9, PE2G6BPi35CX,
6495         "PE2G6BPi35CX"},
6496        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaa, PE2G6BPi35CX,
6497         "PE2G6BPi35CX"},
6498        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaab, PE2G6BPi35CX,
6499         "PE2G6BPi35CX"},
6500        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaac, PE2G6BPi35CX,
6501         "PE2G6BPi35CX"},
6502        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaad, PE2G6BPi35CX,
6503         "PE2G6BPi35CX"},
6504        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaae, PE2G6BPi35CX,
6505         "PE2G6BPi35CX"},
6506        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaf, PE2G6BPi35CX,
6507         "PE2G6BPi35CX"},
6508        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab0, PE2G6BPi35CX,
6509         "PE2G6BPi35CX"},
6510        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab1, PE2G6BPi35CX,
6511         "PE2G6BPi35CX"},
6512        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab2, PE2G6BPi35CX,
6513         "PE2G6BPi35CX"},
6514        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab3, PE2G6BPi35CX,
6515         "PE2G6BPi35CX"},
6516        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab4, PE2G6BPi35CX,
6517         "PE2G6BPi35CX"},
6518        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab5, PE2G6BPi35CX,
6519         "PE2G6BPi35CX"},
6520        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab6, PE2G6BPi35CX,
6521         "PE2G6BPi35CX"},
6522        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab7, PE2G6BPi35CX,
6523         "PE2G6BPi35CX"},
6524        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab8, PE2G6BPi35CX,
6525         "PE2G6BPi35CX"},
6526        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab9, PE2G6BPi35CX,
6527         "PE2G6BPi35CX"},
6528        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaba, PE2G6BPi35CX,
6529         "PE2G6BPi35CX"},
6530        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabb, PE2G6BPi35CX,
6531         "PE2G6BPi35CX"},
6532        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabc, PE2G6BPi35CX,
6533         "PE2G6BPi35CX"},
6534        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabd, PE2G6BPi35CX,
6535         "PE2G6BPi35CX"},
6536        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabe, PE2G6BPi35CX,
6537         "PE2G6BPi35CX"},
6538        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabf, PE2G6BPi35CX,
6539         "PE2G6BPi35CX"},
6540
6541        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6542         SILICOM_PE2G2BPi80_SSID /*PCI_ANY_ID */ , PE2G2BPi80, "PE2G2BPi80"},
6543        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6544         SILICOM_PE2G2BPFi80_SSID /*PCI_ANY_ID */ , PE2G2BPFi80, "PE2G2BPFi80"},
6545        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6546         SILICOM_PE2G2BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi80LX,
6547         "PE2G2BPFi80LX"},
6548        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6549         SILICOM_PE2G2BPFi80ZX_SSID /*PCI_ANY_ID */ , PE2G2BPFi80ZX,
6550         "PE2G2BPFi80ZX"},
6551
6552        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6553         SILICOM_MEG2BPI6_SSID /*PCI_ANY_ID */ , MEG2BPI6, "MEG2BPI6"},
6554        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6555         SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID */ , XEG2BPI6, "XEG2BPI6"},
6556
6557#if 0
6558        {0x8086, 0x10fb, 0x8086, INTEL_PE210G2SPI9_SSID, PE210G2SPI9,
6559         "PE210G2SPI9"},
6560#endif
6561        {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6562         SILICOM_M1E10G2BPI9CX4_SSID /*PCI_ANY_ID */ , M1E10G2BPI9CX4,
6563         "MxE210G2BPI9CX4"},
6564        {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6565         SILICOM_M1E10G2BPI9SR_SSID /*PCI_ANY_ID */ , M1E10G2BPI9SR,
6566         "MxE210G2BPI9SR"},
6567        {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6568         SILICOM_M1E10G2BPI9LR_SSID /*PCI_ANY_ID */ , M1E10G2BPI9LR,
6569         "MxE210G2BPI9LR"},
6570        {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6571         SILICOM_M1E10G2BPI9T_SSID /*PCI_ANY_ID */ , M1E10G2BPI9T,
6572         "MxE210G2BPI9T"},
6573
6574        {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6575         SILICOM_M2E10G2BPI9CX4_SSID /*PCI_ANY_ID */ , M2E10G2BPI9CX4,
6576         "M2E10G2BPI9CX4"},
6577        {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6578         SILICOM_M2E10G2BPI9SR_SSID /*PCI_ANY_ID */ , M2E10G2BPI9SR,
6579         "M2E10G2BPI9SR"},
6580        {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6581         SILICOM_M2E10G2BPI9LR_SSID /*PCI_ANY_ID */ , M2E10G2BPI9LR,
6582         "M2E10G2BPI9LR"},
6583        {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6584         SILICOM_M2E10G2BPI9T_SSID /*PCI_ANY_ID */ , M2E10G2BPI9T,
6585         "M2E10G2BPI9T"},
6586
6587        {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9CX4_SSID,
6588         PE210G2BPI9CX4, "PE210G2BPI9CX4"},
6589        {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9SR_SSID,
6590         PE210G2BPI9SR, "PE210G2BPI9SR"},
6591        {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9LR_SSID,
6592         PE210G2BPI9LR, "PE210G2BPI9LR"},
6593        {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9T_SSID, PE210G2BPI9T,
6594         "PE210G2BPI9T"},
6595
6596#if 0
6597        {0x1374, 0x2c, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI,
6598         "PXG4BPI-SD"},
6599
6600        {0x1374, 0x2d, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI,
6601         "PXG4BPFI-SD"},
6602
6603        {0x1374, 0x3f, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI,
6604         "PXG2TBI-SD"},
6605
6606        {0x1374, 0x3d, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1,
6607         "PXG2BISC1-SD"},
6608
6609        {0x1374, 0x40, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI,
6610         "PEG4BPFI-SD"},
6611
6612#ifdef BP_SELF_TEST
6613        {0x1374, 0x28, SILICOM_SVID, 0x28, PXGBPI, "PXG2BPI-SD"},
6614#endif
6615#endif
6616        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6617         SILICOM_M6E2G8BPi80_SSID /*PCI_ANY_ID */ , M6E2G8BPi80, "MxE2G8BPi80"},
6618        {0x8086, 0x1528, SILICOM_SVID /*PCI_ANY_ID */ ,
6619         SILICOM_PE210G2BPi40_SSID /*PCI_ANY_ID */ , PE210G2BPi40,
6620         "PE210G2BPi40T"},
6621
6622        /* required last entry */
6623        {0,}
6624};
6625
6626static void find_fw(bpctl_dev_t *dev)
6627{
6628        unsigned long mmio_start, mmio_len;
6629        struct pci_dev *pdev1 = dev->pdev;
6630
6631        if ((OLD_IF_SERIES(dev->subdevice)) ||
6632            (INTEL_IF_SERIES(dev->subdevice)))
6633                dev->bp_fw_ver = 0xff;
6634        else
6635                dev->bp_fw_ver = bypass_fw_ver(dev);
6636
6637        if (dev->bp_10gb == 1 && dev->bp_fw_ver == 0xff) {
6638                int cnt = 100;
6639                while (cnt--) {
6640                        iounmap((void *)dev->mem_map);
6641                        mmio_start = pci_resource_start(pdev1, 0);
6642                        mmio_len = pci_resource_len(pdev1, 0);
6643
6644                        dev->mem_map = (unsigned long)
6645                            ioremap(mmio_start, mmio_len);
6646
6647                        dev->bp_fw_ver = bypass_fw_ver(dev);
6648                        if (dev->bp_fw_ver == 0xa8)
6649                                break;
6650                }
6651        }
6652        /* dev->bp_fw_ver=0xa8; */
6653        printk("firmware version: 0x%x\n", dev->bp_fw_ver);
6654}
6655
6656static int init_one(bpctl_dev_t *dev, bpmod_info_t *info, struct pci_dev *pdev1)
6657{
6658        unsigned long mmio_start, mmio_len;
6659
6660        dev->pdev = pdev1;
6661        mmio_start = pci_resource_start(pdev1, 0);
6662        mmio_len = pci_resource_len(pdev1, 0);
6663
6664        dev->desc = dev_desc[info->index].name;
6665        dev->name = info->bp_name;
6666        dev->device = info->device;
6667        dev->vendor = info->vendor;
6668        dev->subdevice = info->subdevice;
6669        dev->subvendor = info->subvendor;
6670        dev->func = PCI_FUNC(pdev1->devfn);
6671        dev->slot = PCI_SLOT(pdev1->devfn);
6672        dev->bus = pdev1->bus->number;
6673        dev->mem_map = (unsigned long)ioremap(mmio_start, mmio_len);
6674#ifdef BP_SYNC_FLAG
6675        spin_lock_init(&dev->bypass_wr_lock);
6676#endif
6677        if (BP10G9_IF_SERIES(dev->subdevice))
6678                dev->bp_10g9 = 1;
6679        if (BP10G_IF_SERIES(dev->subdevice))
6680                dev->bp_10g = 1;
6681        if (PEG540_IF_SERIES(dev->subdevice))
6682                dev->bp_540 = 1;
6683        if (PEGF5_IF_SERIES(dev->subdevice))
6684                dev->bp_fiber5 = 1;
6685        if (PEG80_IF_SERIES(dev->subdevice))
6686                dev->bp_i80 = 1;
6687        if (PEGF80_IF_SERIES(dev->subdevice))
6688                dev->bp_i80 = 1;
6689        if ((dev->subdevice & 0xa00) == 0xa00)
6690                dev->bp_i80 = 1;
6691        if (BP10GB_IF_SERIES(dev->subdevice)) {
6692                if (dev->ifindex == 0) {
6693                        unregister_chrdev(major_num, DEVICE_NAME);
6694                        printk("Please load network driver for %s adapter!\n",
6695                             dev->name);
6696                        return -1;
6697                }
6698
6699                if (dev->ndev && !(dev->ndev->flags & IFF_UP)) {
6700                        unregister_chrdev(major_num, DEVICE_NAME);
6701                        printk("Please bring up network interfaces for %s adapter!\n",
6702                             dev->name);
6703                        return -1;
6704                }
6705                dev->bp_10gb = 1;
6706        }
6707
6708        if (!dev->bp_10g9) {
6709                if (is_bypass_fn(dev)) {
6710                        printk(KERN_INFO "%s found, ",
6711                               dev->name);
6712                        find_fw(dev);
6713                }
6714                dev->wdt_status = WDT_STATUS_UNKNOWN;
6715                dev->reset_time = 0;
6716                atomic_set(&dev->wdt_busy, 0);
6717                dev->bp_status_un = 1;
6718
6719                bypass_caps_init(dev);
6720
6721                init_bypass_wd_auto(dev);
6722                init_bypass_tpl_auto(dev);
6723                if (NOKIA_SERIES(dev->subdevice))
6724                        reset_cont(dev);
6725        }
6726#ifdef BP_SELF_TEST
6727        dev->bp_tx_data = kzalloc(BPTEST_DATA_LEN, GFP_KERNEL);
6728        if (dev->bp_tx_data) {
6729                memset(dev->bp_tx_data, 0xff, 6);
6730                memset(dev->bp_tx_data + 6, 0x0, 1);
6731                memset(dev->bp_tx_data + 7, 0xaa, 5);
6732                *(__be16 *)(dev->bp_tx_data + 12) = htons(ETH_P_BPTEST);
6733        } else
6734                printk("bp_ctl: Memory allocation error!\n");
6735#endif
6736        return 0;
6737}
6738
6739/*
6740* Initialize the module - Register the character device
6741*/
6742
6743static int __init bypass_init_module(void)
6744{
6745        int ret_val, idx, idx_dev = 0;
6746        struct pci_dev *pdev1 = NULL;
6747        bpctl_dev_t *dev;
6748
6749        printk(BP_MOD_DESCR " v" BP_MOD_VER "\n");
6750        ret_val = register_chrdev(major_num, DEVICE_NAME, &Fops);
6751        if (ret_val < 0) {
6752                printk("%s failed with %d\n", DEVICE_NAME, ret_val);
6753                return ret_val;
6754        }
6755        major_num = ret_val;    /* dynamic */
6756        for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) {
6757                while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor,
6758                                               tx_ctl_pci_tbl[idx].device,
6759                                               tx_ctl_pci_tbl[idx].subvendor,
6760                                               tx_ctl_pci_tbl[idx].subdevice,
6761                                               pdev1))) {
6762
6763                        device_num++;
6764                }
6765        }
6766        if (!device_num) {
6767                printk("No such device\n");
6768                unregister_chrdev(major_num, DEVICE_NAME);
6769                return -1;
6770        }
6771
6772        bpctl_dev_arr = kmalloc((device_num) * sizeof(bpctl_dev_t), GFP_KERNEL);
6773
6774        if (!bpctl_dev_arr) {
6775                printk("Allocation error\n");
6776                unregister_chrdev(major_num, DEVICE_NAME);
6777                return -1;
6778        }
6779        memset(bpctl_dev_arr, 0, ((device_num) * sizeof(bpctl_dev_t)));
6780
6781        pdev1 = NULL;
6782        dev = bpctl_dev_arr;
6783        for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) {
6784                while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor,
6785                                               tx_ctl_pci_tbl[idx].device,
6786                                               tx_ctl_pci_tbl[idx].subvendor,
6787                                               tx_ctl_pci_tbl[idx].subdevice,
6788                                               pdev1))) {
6789                        if (init_one(dev, &tx_ctl_pci_tbl[idx], pdev1) < 0)
6790                                return -1;
6791                        dev++;
6792                }
6793        }
6794        if_scan_init();
6795
6796        sema_init(&bpctl_sema, 1);
6797        spin_lock_init(&bpvm_lock);
6798        {
6799
6800                bpctl_dev_t *pbpctl_dev_c = NULL;
6801                for (idx_dev = 0, dev = bpctl_dev_arr;
6802                     idx_dev < device_num && dev->pdev;
6803                     idx_dev++, dev++) {
6804                        if (dev->bp_10g9) {
6805                                pbpctl_dev_c = get_status_port_fn(dev);
6806                                if (is_bypass_fn(dev)) {
6807                                        printk(KERN_INFO "%s found, ",
6808                                               dev->name);
6809                                        dev->bp_fw_ver = bypass_fw_ver(dev);
6810                                        printk("firmware version: 0x%x\n",
6811                                               dev->bp_fw_ver);
6812                                }
6813                                dev->wdt_status = WDT_STATUS_UNKNOWN;
6814                                dev->reset_time = 0;
6815                                atomic_set(&dev->wdt_busy, 0);
6816                                dev->bp_status_un = 1;
6817
6818                                bypass_caps_init(dev);
6819
6820                                init_bypass_wd_auto(dev);
6821                                init_bypass_tpl_auto(dev);
6822
6823                        }
6824
6825                }
6826        }
6827
6828        register_netdevice_notifier(&bp_notifier_block);
6829#ifdef BP_PROC_SUPPORT
6830        {
6831                int i = 0;
6832                /* unsigned long flags; */
6833                /* rcu_read_lock(); */
6834                bp_proc_create();
6835                for (i = 0; i < device_num; i++) {
6836                        if (bpctl_dev_arr[i].ifindex) {
6837                                /* spin_lock_irqsave(&bpvm_lock, flags); */
6838                                bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]);
6839                                bypass_proc_create_dev_sd(&bpctl_dev_arr[i]);
6840                                /* spin_unlock_irqrestore(&bpvm_lock, flags); */
6841                        }
6842
6843                }
6844                /* rcu_read_unlock(); */
6845        }
6846#endif
6847
6848        return 0;
6849}
6850
6851/*
6852* Cleanup - unregister the appropriate file from /proc
6853*/
6854static void __exit bypass_cleanup_module(void)
6855{
6856        int i;
6857        unregister_netdevice_notifier(&bp_notifier_block);
6858
6859        for (i = 0; i < device_num; i++) {
6860                /* unsigned long flags; */
6861#ifdef BP_PROC_SUPPORT
6862/*      spin_lock_irqsave(&bpvm_lock, flags);
6863        rcu_read_lock(); */
6864                bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]);
6865/*      spin_unlock_irqrestore(&bpvm_lock, flags);
6866        rcu_read_unlock(); */
6867#endif
6868                remove_bypass_wd_auto(&bpctl_dev_arr[i]);
6869                bpctl_dev_arr[i].reset_time = 0;
6870
6871                remove_bypass_tpl_auto(&bpctl_dev_arr[i]);
6872        }
6873
6874        /* unmap all devices */
6875        for (i = 0; i < device_num; i++) {
6876#ifdef BP_SELF_TEST
6877                kfree(bpctl_dev_arr[i].bp_tx_data);
6878#endif
6879                iounmap((void *)(bpctl_dev_arr[i].mem_map));
6880        }
6881
6882        /* free all devices space */
6883        kfree(bpctl_dev_arr);
6884
6885/*
6886* Unregister the device
6887*/
6888        unregister_chrdev(major_num, DEVICE_NAME);
6889}
6890
6891module_init(bypass_init_module);
6892module_exit(bypass_cleanup_module);
6893
6894int is_bypass_sd(int ifindex)
6895{
6896        return is_bypass(get_dev_idx_p(ifindex));
6897}
6898EXPORT_SYMBOL(is_bypass_sd);
6899
6900int set_bypass_sd(int ifindex, int bypass_mode)
6901{
6902
6903        return set_bypass_fn(get_dev_idx_p(ifindex), bypass_mode);
6904}
6905EXPORT_SYMBOL(set_bypass_sd);
6906
6907int get_bypass_sd(int ifindex)
6908{
6909
6910        return get_bypass_fn(get_dev_idx_p(ifindex));
6911}
6912EXPORT_SYMBOL(get_bypass_sd);
6913
6914int get_bypass_change_sd(int ifindex)
6915{
6916
6917        return get_bypass_change_fn(get_dev_idx_p(ifindex));
6918}
6919EXPORT_SYMBOL(get_bypass_change_sd);
6920
6921int set_dis_bypass_sd(int ifindex, int dis_param)
6922{
6923        return set_dis_bypass_fn(get_dev_idx_p(ifindex), dis_param);
6924}
6925EXPORT_SYMBOL(set_dis_bypass_sd);
6926
6927int get_dis_bypass_sd(int ifindex)
6928{
6929
6930        return get_dis_bypass_fn(get_dev_idx_p(ifindex));
6931}
6932EXPORT_SYMBOL(get_dis_bypass_sd);
6933
6934int set_bypass_pwoff_sd(int ifindex, int bypass_mode)
6935{
6936        return set_bypass_pwoff_fn(get_dev_idx_p(ifindex), bypass_mode);
6937
6938}
6939EXPORT_SYMBOL(set_bypass_pwoff_sd);
6940
6941int get_bypass_pwoff_sd(int ifindex)
6942{
6943        return get_bypass_pwoff_fn(get_dev_idx_p(ifindex));
6944
6945}
6946EXPORT_SYMBOL(get_bypass_pwoff_sd);
6947
6948int set_bypass_pwup_sd(int ifindex, int bypass_mode)
6949{
6950        return set_bypass_pwup_fn(get_dev_idx_p(ifindex), bypass_mode);
6951
6952}
6953EXPORT_SYMBOL(set_bypass_pwup_sd);
6954
6955int get_bypass_pwup_sd(int ifindex)
6956{
6957        return get_bypass_pwup_fn(get_dev_idx_p(ifindex));
6958
6959}
6960EXPORT_SYMBOL(get_bypass_pwup_sd);
6961
6962int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set)
6963{
6964        if ((is_bypass(get_dev_idx_p(if_index))) <= 0)
6965                return BP_NOT_CAP;
6966        *ms_timeout_set = set_bypass_wd_fn(get_dev_idx_p(if_index), ms_timeout);
6967        return 0;
6968}
6969EXPORT_SYMBOL(set_bypass_wd_sd);
6970
6971int get_bypass_wd_sd(int ifindex, int *timeout)
6972{
6973        return get_bypass_wd_fn(get_dev_idx_p(ifindex), timeout);
6974
6975}
6976EXPORT_SYMBOL(get_bypass_wd_sd);
6977
6978int get_wd_expire_time_sd(int ifindex, int *time_left)
6979{
6980        return get_wd_expire_time_fn(get_dev_idx_p(ifindex), time_left);
6981}
6982EXPORT_SYMBOL(get_wd_expire_time_sd);
6983
6984int reset_bypass_wd_timer_sd(int ifindex)
6985{
6986        return reset_bypass_wd_timer_fn(get_dev_idx_p(ifindex));
6987
6988}
6989EXPORT_SYMBOL(reset_bypass_wd_timer_sd);
6990
6991int get_wd_set_caps_sd(int ifindex)
6992{
6993        return get_wd_set_caps_fn(get_dev_idx_p(ifindex));
6994
6995}
6996EXPORT_SYMBOL(get_wd_set_caps_sd);
6997
6998int set_std_nic_sd(int ifindex, int nic_mode)
6999{
7000        return set_std_nic_fn(get_dev_idx_p(ifindex), nic_mode);
7001
7002}
7003EXPORT_SYMBOL(set_std_nic_sd);
7004
7005int get_std_nic_sd(int ifindex)
7006{
7007        return get_std_nic_fn(get_dev_idx_p(ifindex));
7008
7009}
7010EXPORT_SYMBOL(get_std_nic_sd);
7011
7012int set_tap_sd(int ifindex, int tap_mode)
7013{
7014        return set_tap_fn(get_dev_idx_p(ifindex), tap_mode);
7015
7016}
7017EXPORT_SYMBOL(set_tap_sd);
7018
7019int get_tap_sd(int ifindex)
7020{
7021        return get_tap_fn(get_dev_idx_p(ifindex));
7022
7023}
7024EXPORT_SYMBOL(get_tap_sd);
7025
7026int set_tap_pwup_sd(int ifindex, int tap_mode)
7027{
7028        return set_tap_pwup_fn(get_dev_idx_p(ifindex), tap_mode);
7029
7030}
7031EXPORT_SYMBOL(set_tap_pwup_sd);
7032
7033int get_tap_pwup_sd(int ifindex)
7034{
7035        return get_tap_pwup_fn(get_dev_idx_p(ifindex));
7036
7037}
7038EXPORT_SYMBOL(get_tap_pwup_sd);
7039
7040int get_tap_change_sd(int ifindex)
7041{
7042        return get_tap_change_fn(get_dev_idx_p(ifindex));
7043
7044}
7045EXPORT_SYMBOL(get_tap_change_sd);
7046
7047int set_dis_tap_sd(int ifindex, int dis_param)
7048{
7049        return set_dis_tap_fn(get_dev_idx_p(ifindex), dis_param);
7050
7051}
7052EXPORT_SYMBOL(set_dis_tap_sd);
7053
7054int get_dis_tap_sd(int ifindex)
7055{
7056        return get_dis_tap_fn(get_dev_idx_p(ifindex));
7057
7058}
7059EXPORT_SYMBOL(get_dis_tap_sd);
7060
7061int set_bp_disc_sd(int ifindex, int disc_mode)
7062{
7063        return set_disc_fn(get_dev_idx_p(ifindex), disc_mode);
7064
7065}
7066EXPORT_SYMBOL(set_bp_disc_sd);
7067
7068int get_bp_disc_sd(int ifindex)
7069{
7070        return get_disc_fn(get_dev_idx_p(ifindex));
7071
7072}
7073EXPORT_SYMBOL(get_bp_disc_sd);
7074
7075int set_bp_disc_pwup_sd(int ifindex, int disc_mode)
7076{
7077        return set_disc_pwup_fn(get_dev_idx_p(ifindex), disc_mode);
7078
7079}
7080EXPORT_SYMBOL(set_bp_disc_pwup_sd);
7081
7082int get_bp_disc_pwup_sd(int ifindex)
7083{
7084        return get_disc_pwup_fn(get_dev_idx_p(ifindex));
7085
7086}
7087EXPORT_SYMBOL(get_bp_disc_pwup_sd);
7088
7089int get_bp_disc_change_sd(int ifindex)
7090{
7091        return get_disc_change_fn(get_dev_idx_p(ifindex));
7092
7093}
7094EXPORT_SYMBOL(get_bp_disc_change_sd);
7095
7096int set_bp_dis_disc_sd(int ifindex, int dis_param)
7097{
7098        return set_dis_disc_fn(get_dev_idx_p(ifindex), dis_param);
7099
7100}
7101EXPORT_SYMBOL(set_bp_dis_disc_sd);
7102
7103int get_bp_dis_disc_sd(int ifindex)
7104{
7105        return get_dis_disc_fn(get_dev_idx_p(ifindex));
7106
7107}
7108EXPORT_SYMBOL(get_bp_dis_disc_sd);
7109
7110int get_wd_exp_mode_sd(int ifindex)
7111{
7112        return get_wd_exp_mode_fn(get_dev_idx_p(ifindex));
7113}
7114EXPORT_SYMBOL(get_wd_exp_mode_sd);
7115
7116int set_wd_exp_mode_sd(int ifindex, int param)
7117{
7118        return set_wd_exp_mode_fn(get_dev_idx_p(ifindex), param);
7119
7120}
7121EXPORT_SYMBOL(set_wd_exp_mode_sd);
7122
7123int reset_cont_sd(int ifindex)
7124{
7125        return reset_cont_fn(get_dev_idx_p(ifindex));
7126
7127}
7128
7129int set_tx_sd(int ifindex, int tx_state)
7130{
7131        return set_tx_fn(get_dev_idx_p(ifindex), tx_state);
7132
7133}
7134EXPORT_SYMBOL(set_tx_sd);
7135
7136int set_tpl_sd(int ifindex, int tpl_state)
7137{
7138        return set_tpl_fn(get_dev_idx_p(ifindex), tpl_state);
7139
7140}
7141EXPORT_SYMBOL(set_tpl_sd);
7142
7143int set_bp_hw_reset_sd(int ifindex, int status)
7144{
7145        return set_bp_hw_reset_fn(get_dev_idx_p(ifindex), status);
7146
7147}
7148EXPORT_SYMBOL(set_bp_hw_reset_sd);
7149
7150int set_wd_autoreset_sd(int ifindex, int param)
7151{
7152        return set_wd_autoreset_fn(get_dev_idx_p(ifindex), param);
7153
7154}
7155EXPORT_SYMBOL(set_wd_autoreset_sd);
7156
7157int get_wd_autoreset_sd(int ifindex)
7158{
7159        return get_wd_autoreset_fn(get_dev_idx_p(ifindex));
7160
7161}
7162EXPORT_SYMBOL(get_wd_autoreset_sd);
7163
7164int get_bypass_caps_sd(int ifindex)
7165{
7166        return get_bypass_caps_fn(get_dev_idx_p(ifindex));
7167}
7168EXPORT_SYMBOL(get_bypass_caps_sd);
7169
7170int get_bypass_slave_sd(int ifindex)
7171{
7172        bpctl_dev_t *pbpctl_dev_out;
7173        int ret = get_bypass_slave_fn(get_dev_idx_p(ifindex), &pbpctl_dev_out);
7174        if (ret == 1)
7175                return pbpctl_dev_out->ifindex;
7176        return -1;
7177
7178}
7179EXPORT_SYMBOL(get_bypass_slave_sd);
7180
7181int get_tx_sd(int ifindex)
7182{
7183        return get_tx_fn(get_dev_idx_p(ifindex));
7184
7185}
7186EXPORT_SYMBOL(get_tx_sd);
7187
7188int get_tpl_sd(int ifindex)
7189{
7190        return get_tpl_fn(get_dev_idx_p(ifindex));
7191
7192}
7193EXPORT_SYMBOL(get_tpl_sd);
7194
7195int get_bp_hw_reset_sd(int ifindex)
7196{
7197        return get_bp_hw_reset_fn(get_dev_idx_p(ifindex));
7198
7199}
7200EXPORT_SYMBOL(get_bp_hw_reset_sd);
7201
7202int get_bypass_info_sd(int ifindex, struct bp_info *bp_info)
7203{
7204        return get_bypass_info_fn(get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver);
7205}
7206EXPORT_SYMBOL(get_bypass_info_sd);
7207
7208int bp_if_scan_sd(void)
7209{
7210        if_scan_init();
7211        return 0;
7212}
7213EXPORT_SYMBOL(bp_if_scan_sd);
7214
7215#define BP_PROC_DIR "bypass"
7216
7217static struct proc_dir_entry *bp_procfs_dir;
7218
7219int bp_proc_create(void)
7220{
7221        bp_procfs_dir = proc_mkdir(BP_PROC_DIR, init_net.proc_net);
7222        if (bp_procfs_dir == (struct proc_dir_entry *)0) {
7223                printk(KERN_DEBUG
7224                       "Could not create procfs nicinfo directory %s\n",
7225                       BP_PROC_DIR);
7226                return -1;
7227        }
7228        return 0;
7229}
7230
7231static int procfs_add(char *proc_name, const struct file_operations *fops,
7232                      bpctl_dev_t *dev)
7233{
7234        struct bypass_pfs_sd *pfs = &dev->bypass_pfs_set;
7235        if (!proc_create_data(proc_name, 0644, pfs->bypass_entry, fops, dev))
7236                return -1;
7237        return 0;
7238}
7239
7240#define RO_FOPS(name)   \
7241static int name##_open(struct inode *inode, struct file *file)  \
7242{                                                               \
7243        return single_open(file, show_##name, PDE_DATA(inode));\
7244}                                                               \
7245static const struct file_operations name##_ops = {              \
7246        .open = name##_open,                                    \
7247        .read = seq_read,                                       \
7248        .llseek = seq_lseek,                                    \
7249        .release = single_release,                              \
7250};
7251
7252#define RW_FOPS(name)   \
7253static int name##_open(struct inode *inode, struct file *file)  \
7254{                                                               \
7255        return single_open(file, show_##name, PDE_DATA(inode));\
7256}                                                               \
7257static const struct file_operations name##_ops = {              \
7258        .open = name##_open,                                    \
7259        .read = seq_read,                                       \
7260        .write = name##_write,                                  \
7261        .llseek = seq_lseek,                                    \
7262        .release = single_release,                              \
7263};
7264
7265static int show_bypass_info(struct seq_file *m, void *v)
7266{
7267        bpctl_dev_t *dev = m->private;
7268
7269        seq_printf(m, "Name\t\t\t%s\n", dev->name);
7270        seq_printf(m, "Firmware version\t0x%x\n", dev->bp_fw_ver);
7271        return 0;
7272}
7273RO_FOPS(bypass_info)
7274
7275static int show_bypass_slave(struct seq_file *m, void *v)
7276{
7277        bpctl_dev_t *dev = m->private;
7278        bpctl_dev_t *slave = get_status_port_fn(dev);
7279        if (!slave)
7280                slave = dev;
7281        if (!slave)
7282                seq_puts(m, "fail\n");
7283        else if (slave->ndev)
7284                seq_printf(m, "%s\n", slave->ndev->name);
7285        return 0;
7286}
7287RO_FOPS(bypass_slave)
7288
7289static int show_bypass_caps(struct seq_file *m, void *v)
7290{
7291        bpctl_dev_t *dev = m->private;
7292        int ret = get_bypass_caps_fn(dev);
7293        if (ret == BP_NOT_CAP)
7294                seq_puts(m, "-1\n");
7295        else
7296                seq_printf(m, "0x%x\n", ret);
7297        return 0;
7298}
7299RO_FOPS(bypass_caps)
7300
7301static int show_wd_set_caps(struct seq_file *m, void *v)
7302{
7303        bpctl_dev_t *dev = m->private;
7304        int ret = get_wd_set_caps_fn(dev);
7305        if (ret == BP_NOT_CAP)
7306                seq_puts(m, "-1\n");
7307        else
7308                seq_printf(m, "0x%x\n", ret);
7309        return 0;
7310}
7311RO_FOPS(wd_set_caps)
7312
7313static int user_on_off(const void __user *buffer, size_t count)
7314{
7315
7316        char kbuf[256];
7317        int length = 0;
7318
7319        if (count > (sizeof(kbuf) - 1))
7320                return -1;
7321
7322        if (copy_from_user(&kbuf, buffer, count))
7323                return -1;
7324
7325        kbuf[count] = '\0';
7326        length = strlen(kbuf);
7327        if (kbuf[length - 1] == '\n')
7328                kbuf[--length] = '\0';
7329
7330        if (strcmp(kbuf, "on") == 0)
7331                return 1;
7332        if (strcmp(kbuf, "off") == 0)
7333                return 0;
7334        return 0;
7335}
7336
7337static ssize_t bypass_write(struct file *file, const char __user *buffer,
7338                                  size_t count, loff_t *pos)
7339{
7340        int bypass_param = user_on_off(buffer, count);
7341        if (bypass_param < 0)
7342                return -1;
7343
7344        set_bypass_fn(PDE_DATA(file_inode(file)), bypass_param);
7345        return count;
7346}
7347static int show_bypass(struct seq_file *m, void *v)
7348{
7349        bpctl_dev_t *dev = m->private;
7350        int ret = get_bypass_fn(dev);
7351        if (ret == BP_NOT_CAP)
7352                seq_puts(m, "fail\n");
7353        else if (ret == 1)
7354                seq_puts(m, "on\n");
7355        else if (ret == 0)
7356                seq_puts(m, "off\n");
7357        return 0;
7358}
7359RW_FOPS(bypass)
7360
7361static ssize_t tap_write(struct file *file, const char __user *buffer,
7362                                  size_t count, loff_t *pos)
7363{
7364        int tap_param = user_on_off(buffer, count);
7365        if (tap_param < 0)
7366                return -1;
7367
7368        set_tap_fn(PDE_DATA(file_inode(file)), tap_param);
7369        return count;
7370}
7371static int show_tap(struct seq_file *m, void *v)
7372{
7373        bpctl_dev_t *dev = m->private;
7374        int ret = get_tap_fn(dev);
7375        if (ret == BP_NOT_CAP)
7376                seq_puts(m, "fail\n");
7377        else if (ret == 1)
7378                seq_puts(m, "on\n");
7379        else if (ret == 0)
7380                seq_puts(m, "off\n");
7381        return 0;
7382}
7383RW_FOPS(tap)
7384
7385static ssize_t disc_write(struct file *file, const char __user *buffer,
7386                                  size_t count, loff_t *pos)
7387{
7388        int tap_param = user_on_off(buffer, count);
7389        if (tap_param < 0)
7390                return -1;
7391
7392        set_disc_fn(PDE_DATA(file_inode(file)), tap_param);
7393        return count;
7394}
7395static int show_disc(struct seq_file *m, void *v)
7396{
7397        bpctl_dev_t *dev = m->private;
7398        int ret = get_disc_fn(dev);
7399        if (ret == BP_NOT_CAP)
7400                seq_puts(m, "fail\n");
7401        else if (ret == 1)
7402                seq_puts(m, "on\n");
7403        else if (ret == 0)
7404                seq_puts(m, "off\n");
7405        return 0;
7406}
7407RW_FOPS(disc)
7408
7409static int show_bypass_change(struct seq_file *m, void *v)
7410{
7411        bpctl_dev_t *dev = m->private;
7412        int ret = get_bypass_change_fn(dev);
7413        if (ret == 1)
7414                seq_puts(m, "on\n");
7415        else if (ret == 0)
7416                seq_puts(m, "off\n");
7417        else
7418                seq_puts(m, "fail\n");
7419        return 0;
7420}
7421RO_FOPS(bypass_change)
7422
7423static int show_tap_change(struct seq_file *m, void *v)
7424{
7425        bpctl_dev_t *dev = m->private;
7426        int ret = get_tap_change_fn(dev);
7427        if (ret == 1)
7428                seq_puts(m, "on\n");
7429        else if (ret == 0)
7430                seq_puts(m, "off\n");
7431        else
7432                seq_puts(m, "fail\n");
7433        return 0;
7434}
7435RO_FOPS(tap_change)
7436
7437static int show_disc_change(struct seq_file *m, void *v)
7438{
7439        bpctl_dev_t *dev = m->private;
7440        int ret = get_disc_change_fn(dev);
7441        if (ret == 1)
7442                seq_puts(m, "on\n");
7443        else if (ret == 0)
7444                seq_puts(m, "off\n");
7445        else
7446                seq_puts(m, "fail\n");
7447        return 0;
7448}
7449RO_FOPS(disc_change)
7450
7451static ssize_t bypass_wd_write(struct file *file, const char __user *buffer,
7452                                  size_t count, loff_t *pos)
7453{
7454        bpctl_dev_t *dev = PDE_DATA(file_inode(file));
7455        int timeout;
7456        int ret = kstrtoint_from_user(buffer, count, 10, &timeout);
7457        if (ret)
7458                return ret;
7459        set_bypass_wd_fn(dev, timeout);
7460        return count;
7461}
7462static int show_bypass_wd(struct seq_file *m, void *v)
7463{
7464        bpctl_dev_t *dev = m->private;
7465        int ret = 0, timeout = 0;
7466
7467        ret = get_bypass_wd_fn(dev, &timeout);
7468        if (ret == BP_NOT_CAP)
7469                seq_puts(m,  "fail\n");
7470        else if (timeout == -1)
7471                seq_puts(m,  "unknown\n");
7472        else if (timeout == 0)
7473                seq_puts(m,  "disable\n");
7474        else
7475                seq_printf(m, "%d\n", timeout);
7476        return 0;
7477}
7478RW_FOPS(bypass_wd)
7479
7480static int show_wd_expire_time(struct seq_file *m, void *v)
7481{
7482        bpctl_dev_t *dev = m->private;
7483        int ret = 0, timeout = 0;
7484        ret = get_wd_expire_time_fn(dev, &timeout);
7485        if (ret == BP_NOT_CAP)
7486                seq_puts(m, "fail\n");
7487        else if (timeout == -1)
7488                seq_puts(m, "expire\n");
7489        else if (timeout == 0)
7490                seq_puts(m, "disable\n");
7491        else
7492                seq_printf(m, "%d\n", timeout);
7493        return 0;
7494}
7495RO_FOPS(wd_expire_time)
7496
7497static ssize_t tpl_write(struct file *file, const char __user *buffer,
7498                                  size_t count, loff_t *pos)
7499{
7500        bpctl_dev_t *dev = PDE_DATA(file_inode(file));
7501        int tpl_param = user_on_off(buffer, count);
7502        if (tpl_param < 0)
7503                return -1;
7504
7505        set_tpl_fn(dev, tpl_param);
7506        return count;
7507}
7508static int show_tpl(struct seq_file *m, void *v)
7509{
7510        bpctl_dev_t *dev = m->private;
7511        int ret = get_tpl_fn(dev);
7512        if (ret == BP_NOT_CAP)
7513                seq_puts(m, "fail\n");
7514        else if (ret == 1)
7515                seq_puts(m, "on\n");
7516        else if (ret == 0)
7517                seq_puts(m, "off\n");
7518        return 0;
7519}
7520RW_FOPS(tpl)
7521
7522#ifdef PMC_FIX_FLAG
7523static ssize_t wait_at_pwup_write(struct file *file, const char __user *buffer,
7524                                  size_t count, loff_t *pos)
7525{
7526        bpctl_dev_t *dev = PDE_DATA(file_inode(file));
7527        int tpl_param = user_on_off(buffer, count);
7528        if (tpl_param < 0)
7529                return -1;
7530
7531        set_bp_wait_at_pwup_fn(dev, tpl_param);
7532        return count;
7533}
7534static int show_wait_at_pwup(struct seq_file *m, void *v)
7535{
7536        bpctl_dev_t *dev = m->private;
7537        int ret = get_bp_wait_at_pwup_fn(dev);
7538        if (ret == BP_NOT_CAP)
7539                seq_puts(m, "fail\n");
7540        else if (ret == 1)
7541                seq_puts(m, "on\n");
7542        else if (ret == 0)
7543                seq_puts(m, "off\n");
7544        return 0;
7545}
7546RW_FOPS(wait_at_pwup)
7547
7548static ssize_t hw_reset_write(struct file *file, const char __user *buffer,
7549                                  size_t count, loff_t *pos)
7550{
7551        bpctl_dev_t *dev = PDE_DATA(file_inode(file));
7552        int tpl_param = user_on_off(buffer, count);
7553        if (tpl_param < 0)
7554                return -1;
7555
7556        set_bp_hw_reset_fn(dev, tpl_param);
7557        return count;
7558}
7559static int show_hw_reset(struct seq_file *m, void *v)
7560{
7561        bpctl_dev_t *dev = m->private;
7562        int ret = get_bp_hw_reset_fn(dev);
7563        if (ret == BP_NOT_CAP)
7564                seq_puts(m, "fail\n");
7565        else if (ret == 1)
7566                seq_puts(m, "on\n");
7567        else if (ret == 0)
7568                seq_puts(m, "off\n");
7569        return 0;
7570}
7571RW_FOPS(hw_reset)
7572
7573#endif                          /*PMC_WAIT_FLAG */
7574
7575static int show_reset_bypass_wd(struct seq_file *m, void *v)
7576{
7577        bpctl_dev_t *dev = m->private;
7578        int ret = reset_bypass_wd_timer_fn(dev);
7579        if (ret == BP_NOT_CAP)
7580                seq_puts(m, "fail\n");
7581        else if (ret == 0)
7582                seq_puts(m, "disable\n");
7583        else if (ret == 1)
7584                seq_puts(m, "success\n");
7585        return 0;
7586}
7587RO_FOPS(reset_bypass_wd)
7588
7589static ssize_t dis_bypass_write(struct file *file, const char __user *buffer,
7590                                  size_t count, loff_t *pos)
7591{
7592        int bypass_param = user_on_off(buffer, count);
7593        if (bypass_param < 0)
7594                return -EINVAL;
7595
7596        set_dis_bypass_fn(PDE_DATA(file_inode(file)), bypass_param);
7597        return count;
7598}
7599static int show_dis_bypass(struct seq_file *m, void *v)
7600{
7601        bpctl_dev_t *dev = m->private;
7602        int ret = get_dis_bypass_fn(dev);
7603        if (ret == BP_NOT_CAP)
7604                seq_puts(m, "fail\n");
7605        else if (ret == 0)
7606                seq_puts(m, "off\n");
7607        else
7608                seq_puts(m, "on\n");
7609        return 0;
7610}
7611RW_FOPS(dis_bypass)
7612
7613static ssize_t dis_tap_write(struct file *file, const char __user *buffer,
7614                                  size_t count, loff_t *pos)
7615{
7616        int tap_param = user_on_off(buffer, count);
7617        if (tap_param < 0)
7618                return -EINVAL;
7619
7620        set_dis_tap_fn(PDE_DATA(file_inode(file)), tap_param);
7621        return count;
7622}
7623static int show_dis_tap(struct seq_file *m, void *v)
7624{
7625        bpctl_dev_t *dev = m->private;
7626        int ret = get_dis_tap_fn(dev);
7627        if (ret == BP_NOT_CAP)
7628                seq_puts(m, "fail\n");
7629        else if (ret == 0)
7630                seq_puts(m, "off\n");
7631        else
7632                seq_puts(m, "on\n");
7633        return 0;
7634}
7635RW_FOPS(dis_tap)
7636
7637static ssize_t dis_disc_write(struct file *file, const char __user *buffer,
7638                                  size_t count, loff_t *pos)
7639{
7640        int tap_param = user_on_off(buffer, count);
7641        if (tap_param < 0)
7642                return -EINVAL;
7643
7644        set_dis_disc_fn(PDE_DATA(file_inode(file)), tap_param);
7645        return count;
7646}
7647static int show_dis_disc(struct seq_file *m, void *v)
7648{
7649        bpctl_dev_t *dev = m->private;
7650        int ret = get_dis_disc_fn(dev);
7651        if (ret == BP_NOT_CAP)
7652                seq_puts(m, "fail\n");
7653        else if (ret == 0)
7654                seq_puts(m, "off\n");
7655        else
7656                seq_puts(m, "on\n");
7657        return 0;
7658}
7659RW_FOPS(dis_disc)
7660
7661static ssize_t bypass_pwup_write(struct file *file, const char __user *buffer,
7662                                  size_t count, loff_t *pos)
7663{
7664        int bypass_param = user_on_off(buffer, count);
7665        if (bypass_param < 0)
7666                return -EINVAL;
7667
7668        set_bypass_pwup_fn(PDE_DATA(file_inode(file)), bypass_param);
7669        return count;
7670}
7671static int show_bypass_pwup(struct seq_file *m, void *v)
7672{
7673        bpctl_dev_t *dev = m->private;
7674        int ret = get_bypass_pwup_fn(dev);
7675        if (ret == BP_NOT_CAP)
7676                seq_puts(m, "fail\n");
7677        else if (ret == 0)
7678                seq_puts(m, "off\n");
7679        else
7680                seq_puts(m, "on\n");
7681        return 0;
7682}
7683RW_FOPS(bypass_pwup)
7684
7685static ssize_t bypass_pwoff_write(struct file *file, const char __user *buffer,
7686                                  size_t count, loff_t *pos)
7687{
7688        int bypass_param = user_on_off(buffer, count);
7689        if (bypass_param < 0)
7690                return -EINVAL;
7691
7692        set_bypass_pwoff_fn(PDE_DATA(file_inode(file)), bypass_param);
7693        return count;
7694}
7695static int show_bypass_pwoff(struct seq_file *m, void *v)
7696{
7697        bpctl_dev_t *dev = m->private;
7698        int ret = get_bypass_pwoff_fn(dev);
7699        if (ret == BP_NOT_CAP)
7700                seq_puts(m, "fail\n");
7701        else if (ret == 0)
7702                seq_puts(m, "off\n");
7703        else
7704                seq_puts(m, "on\n");
7705        return 0;
7706}
7707RW_FOPS(bypass_pwoff)
7708
7709static ssize_t tap_pwup_write(struct file *file, const char __user *buffer,
7710                                  size_t count, loff_t *pos)
7711{
7712        int tap_param = user_on_off(buffer, count);
7713        if (tap_param < 0)
7714                return -EINVAL;
7715
7716        set_tap_pwup_fn(PDE_DATA(file_inode(file)), tap_param);
7717        return count;
7718}
7719static int show_tap_pwup(struct seq_file *m, void *v)
7720{
7721        bpctl_dev_t *dev = m->private;
7722        int ret = get_tap_pwup_fn(dev);
7723        if (ret == BP_NOT_CAP)
7724                seq_puts(m, "fail\n");
7725        else if (ret == 0)
7726                seq_puts(m, "off\n");
7727        else
7728                seq_puts(m, "on\n");
7729        return 0;
7730}
7731RW_FOPS(tap_pwup)
7732
7733static ssize_t disc_pwup_write(struct file *file, const char __user *buffer,
7734                                  size_t count, loff_t *pos)
7735{
7736        int tap_param = user_on_off(buffer, count);
7737        if (tap_param < 0)
7738                return -EINVAL;
7739
7740        set_disc_pwup_fn(PDE_DATA(file_inode(file)), tap_param);
7741        return count;
7742}
7743static int show_disc_pwup(struct seq_file *m, void *v)
7744{
7745        bpctl_dev_t *dev = m->private;
7746        int ret = get_disc_pwup_fn(dev);
7747        if (ret == BP_NOT_CAP)
7748                seq_puts(m, "fail\n");
7749        else if (ret == 0)
7750                seq_puts(m, "off\n");
7751        else
7752                seq_puts(m, "on\n");
7753        return 0;
7754}
7755RW_FOPS(disc_pwup)
7756
7757static ssize_t std_nic_write(struct file *file, const char __user *buffer,
7758                                  size_t count, loff_t *pos)
7759{
7760        int bypass_param = user_on_off(buffer, count);
7761        if (bypass_param < 0)
7762                return -EINVAL;
7763
7764        set_std_nic_fn(PDE_DATA(file_inode(file)), bypass_param);
7765        return count;
7766}
7767static int show_std_nic(struct seq_file *m, void *v)
7768{
7769        bpctl_dev_t *dev = m->private;
7770        int ret = get_std_nic_fn(dev);
7771        if (ret == BP_NOT_CAP)
7772                seq_puts(m, "fail\n");
7773        else if (ret == 0)
7774                seq_puts(m, "off\n");
7775        else
7776                seq_puts(m, "on\n");
7777        return 0;
7778}
7779RW_FOPS(std_nic)
7780
7781static ssize_t wd_exp_mode_write(struct file *file, const char __user *buffer,
7782                                  size_t count, loff_t *pos)
7783{
7784        char kbuf[256];
7785        int bypass_param = 0, length = 0;
7786
7787        if (count > (sizeof(kbuf) - 1))
7788                return -1;
7789
7790        if (copy_from_user(&kbuf, buffer, count))
7791                return -1;
7792
7793        kbuf[count] = '\0';
7794        length = strlen(kbuf);
7795        if (kbuf[length - 1] == '\n')
7796                kbuf[--length] = '\0';
7797
7798        if (strcmp(kbuf, "tap") == 0)
7799                bypass_param = 1;
7800        else if (strcmp(kbuf, "bypass") == 0)
7801                bypass_param = 0;
7802        else if (strcmp(kbuf, "disc") == 0)
7803                bypass_param = 2;
7804
7805        set_wd_exp_mode_fn(PDE_DATA(file_inode(file)), bypass_param);
7806
7807        return count;
7808}
7809static int show_wd_exp_mode(struct seq_file *m, void *v)
7810{
7811        bpctl_dev_t *dev = m->private;
7812        int ret = get_wd_exp_mode_fn(dev);
7813        if (ret == 1)
7814                seq_puts(m, "tap\n");
7815        else if (ret == 0)
7816                seq_puts(m, "bypass\n");
7817        else if (ret == 2)
7818                seq_puts(m, "disc\n");
7819        else
7820                seq_puts(m, "fail\n");
7821        return 0;
7822}
7823RW_FOPS(wd_exp_mode)
7824
7825static ssize_t wd_autoreset_write(struct file *file, const char __user *buffer,
7826                                  size_t count, loff_t *pos)
7827{
7828        int timeout;
7829        int ret = kstrtoint_from_user(buffer, count, 10, &timeout);
7830        if (ret)
7831                return ret;
7832        set_wd_autoreset_fn(PDE_DATA(file_inode(file)), timeout);
7833        return count;
7834}
7835static int show_wd_autoreset(struct seq_file *m, void *v)
7836{
7837        bpctl_dev_t *dev = m->private;
7838        int ret = get_wd_autoreset_fn(dev);
7839        if (ret >= 0)
7840                seq_printf(m, "%d\n", ret);
7841        else
7842                seq_puts(m, "fail\n");
7843        return 0;
7844}
7845RW_FOPS(wd_autoreset)
7846
7847int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block)
7848{
7849        struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set);
7850        static struct proc_dir_entry *procfs_dir;
7851        int ret = 0;
7852
7853        if (!pbp_device_block->ndev)
7854                return -1;
7855        sprintf(current_pfs->dir_name, "bypass_%s",
7856                pbp_device_block->ndev->name);
7857
7858        if (!bp_procfs_dir)
7859                return -1;
7860
7861        /* create device proc dir */
7862        procfs_dir = proc_mkdir(current_pfs->dir_name, bp_procfs_dir);
7863        if (!procfs_dir) {
7864                printk(KERN_DEBUG "Could not create procfs directory %s\n",
7865                       current_pfs->dir_name);
7866                return -1;
7867        }
7868        current_pfs->bypass_entry = procfs_dir;
7869
7870#define ENTRY(x) (ret |= procfs_add(#x, &x##_ops, pbp_device_block))
7871
7872        ENTRY(bypass_info);
7873        if (pbp_device_block->bp_caps & SW_CTL_CAP) {
7874                /* Create set param proc's */
7875                ENTRY(bypass_slave);
7876                ENTRY(bypass_caps);
7877                ENTRY(wd_set_caps);
7878                ENTRY(bypass_wd);
7879                ENTRY(wd_expire_time);
7880                ENTRY(reset_bypass_wd);
7881                ENTRY(std_nic);
7882                if (pbp_device_block->bp_caps & BP_CAP) {
7883                        ENTRY(bypass);
7884                        ENTRY(dis_bypass);
7885                        ENTRY(bypass_pwup);
7886                        ENTRY(bypass_pwoff);
7887                        ENTRY(bypass_change);
7888                }
7889                if (pbp_device_block->bp_caps & TAP_CAP) {
7890                        ENTRY(tap);
7891                        ENTRY(dis_tap);
7892                        ENTRY(tap_pwup);
7893                        ENTRY(tap_change);
7894                }
7895                if (pbp_device_block->bp_caps & DISC_CAP) {
7896                        ENTRY(disc);
7897                        ENTRY(dis_disc);
7898                        ENTRY(disc_pwup);
7899                        ENTRY(disc_change);
7900                }
7901
7902                ENTRY(wd_exp_mode);
7903                ENTRY(wd_autoreset);
7904                ENTRY(tpl);
7905#ifdef PMC_FIX_FLAG
7906                ENTRY(wait_at_pwup);
7907                ENTRY(hw_reset);
7908#endif
7909        }
7910#undef ENTRY
7911        if (ret < 0)
7912                printk(KERN_DEBUG "Create proc entry failed\n");
7913
7914        return ret;
7915}
7916
7917int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block)
7918{
7919
7920        struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set;
7921        remove_proc_subtree(current_pfs->dir_name, bp_procfs_dir);
7922        current_pfs->bypass_entry = NULL;
7923        return 0;
7924}
7925