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