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