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