]> Pileus Git - ~andy/linux/blob - drivers/staging/silicom/bpctl_mod.c
Merge tag 'v3.12-rc3' into irq/core
[~andy/linux] / 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 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 };
106
107 static struct bpctl_dev *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 struct bpctl_dev *get_master_port_fn(struct bpctl_dev *pbpctl_dev);
114 static int disc_status(struct bpctl_dev *pbpctl_dev);
115 static int bypass_status(struct bpctl_dev *pbpctl_dev);
116 static int wdt_timer(struct bpctl_dev *pbpctl_dev, int *time_left);
117 static struct bpctl_dev *get_status_port_fn(struct bpctl_dev *pbpctl_dev);
118 static void if_scan_init(void);
119
120 int bypass_proc_create_dev_sd(struct bpctl_dev *pbp_device_block);
121 int bypass_proc_remove_dev_sd(struct bpctl_dev *pbp_device_block);
122 int bp_proc_create(void);
123
124 int is_bypass_fn(struct bpctl_dev *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 = netdev_notifier_info_to_dev(ptr);
132         static struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev);
288 int wdt_time_left(struct bpctl_dev *pbpctl_dev);
289
290 static void write_pulse(struct bpctl_dev *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         struct bpctl_dev *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(struct bpctl_dev *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         struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev, unsigned char value,
769                       unsigned char addr)
770 {
771         uint32_t ctrl_ext = 0, ctrl = 0;
772         struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev, unsigned char value)
938 {
939         write_reg(pbpctl_dev, value, CMND_REG_ADDR);
940 }
941
942 static int read_reg(struct bpctl_dev *pbpctl_dev, unsigned char addr)
943 {
944         uint32_t ctrl_ext = 0, ctrl = 0, ctrl_value = 0;
945         struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
1212 {
1213         uint32_t ctrl_ext = 0, ctrl = 0;
1214         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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 struct bpctl_dev *lookup_port(struct bpctl_dev *dev)
1684 {
1685         struct bpctl_dev *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 struct bpctl_dev *get_status_port_fn(struct bpctl_dev *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 struct bpctl_dev *get_master_port_fn(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev, unsigned char value)
1744 {
1745         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
1912 {
1913         int ret = 0;
1914         struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
1937 {
1938         int ret = 0;
1939         struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
1962 {
1963         int ret = 0, ctrl = 0;
1964         struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
1990 {
1991         int ret = 0, ctrl = 0;
1992         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev, int tx_state)
2336 {
2337         int ret = 0, ctrl = 0;
2338         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
2722 {
2723         int ret = 0;
2724         struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
2748 {
2749         int ret = 0;
2750         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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         struct bpctl_dev *pbpctl_dev = (struct bpctl_dev *) 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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
3135 {
3136         uint32_t ctrl = 0;
3137         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
3236 {
3237         uint32_t ctrl_ext = 0;
3238         struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
3256 {
3257         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
3329 {
3330         u32 ctrl_ext = 0;
3331         if (pbpctl_dev->bp_caps & BP_CAP) {
3332
3333                 struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
3618 {
3619         u32 ctrl_ext = 0;
3620
3621         if (pbpctl_dev->bp_caps & TAP_CAP) {
3622                 struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
3716 {
3717         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
3834 {
3835         int ret = BP_NOT_CAP;
3836         struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
3858 {
3859         int ret = BP_NOT_CAP;
3860         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
3916 {
3917         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
4004 {
4005         u_int32_t ctrl_ext = 0;
4006         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
4238 {
4239 #ifdef BP_SELF_TEST
4240         struct bpctl_dev *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(struct bpctl_dev *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         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev, unsigned int param)
4343 {
4344         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
4422 {
4423         return bypass_status(pbpctl_dev);
4424 }
4425
4426 int get_bypass_change_fn(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev, int tx_state)
4872 {
4873
4874         struct bpctl_dev *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 struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev, struct bpctl_dev **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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
4992 {
4993         struct bpctl_dev *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 struct bpctl_dev *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(struct bpctl_dev *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         struct bpctl_dev *pbpctl_dev = (struct bpctl_dev *) param;
5040         uint32_t link1, link2;
5041         struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev)
5075 {
5076         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *pbpctl_dev, int tpl_mode)
5134 {
5135
5136         struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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(struct bpctl_dev *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 struct bpctl_dev *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         struct bpctl_dev *pbpctl_dev_out;
5405         void __user *argp = (void __user *)ioctl_param;
5406         int ret = 0;
5407         unsigned long flags;
5408
5409         static struct bpctl_dev *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 struct bpmod_info {
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 };
5983
5984 struct {
5985         char *name;
5986 } dev_desc[] = {
5987         {"Silicom Bypass PXG2BPFI-SD series adapter"},
5988         {"Silicom Bypass PXG2BPFIL-SD series adapter"},
5989         {"Silicom Bypass PXG2BPFILX-SD series adapter"},
5990         {"Silicom Bypass PXG2BPFILLX-SD series adapter"},
5991         {"Silicom Bypass PXG2BPI-SD series adapter"},
5992         {"Silicom Bypass PXG2BPIG-SD series adapter"},
5993         {"Silicom Bypass PXG2TBFI-SD series adapter"},
5994         {"Silicom Bypass PXG4BPI-SD series adapter"},
5995         {"Silicom Bypass PXG4BPFI-SD series adapter"},
5996         {"Silicom Bypass PEG4BPI-SD series adapter"},
5997         {"Silicom Bypass PEG2BPI-SD series adapter"},
5998         {"Silicom Bypass PEG4BPIN-SD series adapter"},
5999         {"Silicom Bypass PEG2BPFI-SD series adapter"},
6000         {"Silicom Bypass PEG2BPFI-LX-SD series adapter"},
6001         {"Silicom Bypass PMCX2BPFI-SD series adapter"},
6002         {"Silicom Bypass PMCX2BPFI-N series adapter"},
6003         {"Intel Bypass PEG2BPII series adapter"},
6004         {"Intel Bypass PEG2BPFII series adapter"},
6005         {"Silicom Bypass PXG4BPFILX-SD series adapter"},
6006         {"Silicom Bypass PMCX2BPI-N series adapter"},
6007         {"Silicom Bypass PMCX4BPI-N series adapter"},
6008         {"Silicom Bypass PXG2BISC1-SD series adapter"},
6009         {"Silicom Bypass PEG2TBFI-SD series adapter"},
6010         {"Silicom Bypass PXG2TBI-SD series adapter"},
6011         {"Silicom Bypass PXG4BPFID-SD series adapter"},
6012         {"Silicom Bypass PEG4BPFI-SD series adapter"},
6013         {"Silicom Bypass PEG4BPIPT-SD series adapter"},
6014         {"Silicom Bypass PXG6BPI-SD series adapter"},
6015         {"Silicom Bypass PEG4BPIL-SD series adapter"},
6016         {"Silicom Bypass PMCX2BPI-N2 series adapter"},
6017         {"Silicom Bypass PMCX4BPI-N2 series adapter"},
6018         {"Silicom Bypass PMCX2BPI-SD series adapter"},
6019         {"Silicom Bypass PEG2BPFID-SD series adapter"},
6020         {"Silicom Bypass PEG2BPFIDLX-SD series adapter"},
6021         {"Silicom Bypass PMCX4BPI-SD series adapter"},
6022         {"Silicom Bypass MEG2BPFILN-SD series adapter"},
6023         {"Silicom Bypass MEG2BPFINX-SD series adapter"},
6024         {"Silicom Bypass PEG4BPFILX-SD series adapter"},
6025         {"Silicom Bypass PE10G2BPISR-SD series adapter"},
6026         {"Silicom Bypass PE10G2BPILR-SD series adapter"},
6027         {"Silicom Bypass MHIO8AD-SD series adapter"},
6028         {"Silicom Bypass PE10G2BPICX4-SD series adapter"},
6029         {"Silicom Bypass PEG2BPI5-SD series adapter"},
6030         {"Silicom Bypass PEG6BPI5-SD series adapter"},
6031         {"Silicom Bypass PEG4BPFI5-SD series adapter"},
6032         {"Silicom Bypass PEG4BPFI5LX-SD series adapter"},
6033         {"Silicom Bypass MEG2BPFILXLN-SD series adapter"},
6034         {"Silicom Bypass PEG2BPIX1-SD series adapter"},
6035         {"Silicom Bypass MEG2BPFILXNX-SD series adapter"},
6036         {"Silicom Bypass XE10G2BPIT-SD series adapter"},
6037         {"Silicom Bypass XE10G2BPICX4-SD series adapter"},
6038         {"Silicom Bypass XE10G2BPISR-SD series adapter"},
6039         {"Silicom Bypass XE10G2BPILR-SD series adapter"},
6040         {"Intel Bypass PEG2BPFII0 series adapter"},
6041         {"Silicom Bypass XE10G2BPIXR series adapter"},
6042         {"Silicom Bypass PE10G2DBISR series adapter"},
6043         {"Silicom Bypass PEG2BI5SC6 series adapter"},
6044         {"Silicom Bypass PEG6BPI5FC series adapter"},
6045
6046         {"Silicom Bypass PE10G2BPTCX4 series adapter"},
6047         {"Silicom Bypass PE10G2BPTSR series adapter"},
6048         {"Silicom Bypass PE10G2BPTLR series adapter"},
6049         {"Silicom Bypass PE10G2BPTT series adapter"},
6050         {"Silicom Bypass PEG4BPI6 series adapter"},
6051         {"Silicom Bypass PEG4BPFI6 series adapter"},
6052         {"Silicom Bypass PEG4BPFI6LX series adapter"},
6053         {"Silicom Bypass PEG4BPFI6ZX series adapter"},
6054         {"Silicom Bypass PEG2BPI6 series adapter"},
6055         {"Silicom Bypass PEG2BPFI6 series adapter"},
6056         {"Silicom Bypass PEG2BPFI6LX series adapter"},
6057         {"Silicom Bypass PEG2BPFI6ZX series adapter"},
6058         {"Silicom Bypass PEG2BPFI6FLXM series adapter"},
6059         {"Silicom Bypass PEG4BPI6FC series adapter"},
6060         {"Silicom Bypass PEG4BPFI6FC series adapter"},
6061         {"Silicom Bypass PEG4BPFI6FCLX series adapter"},
6062         {"Silicom Bypass PEG4BPFI6FCZX series adapter"},
6063         {"Silicom Bypass PEG6BPI6 series adapter"},
6064         {"Silicom Bypass PEG2BPI6SC6 series adapter"},
6065         {"Silicom Bypass MEG2BPI6 series adapter"},
6066         {"Silicom Bypass XEG2BPI6 series adapter"},
6067         {"Silicom Bypass MEG4BPI6 series adapter"},
6068         {"Silicom Bypass PEG2BPFI5-SD series adapter"},
6069         {"Silicom Bypass PEG2BPFI5LX-SD series adapter"},
6070         {"Silicom Bypass PXEG4BPFI-SD series adapter"},
6071         {"Silicom Bypass MxEG2BPI6 series adapter"},
6072         {"Silicom Bypass MxEG2BPFI6 series adapter"},
6073         {"Silicom Bypass MxEG2BPFI6LX series adapter"},
6074         {"Silicom Bypass MxEG2BPFI6ZX series adapter"},
6075         {"Silicom Bypass MxEG4BPI6 series adapter"},
6076         {"Silicom Bypass MxEG4BPFI6 series adapter"},
6077         {"Silicom Bypass MxEG4BPFI6LX series adapter"},
6078         {"Silicom Bypass MxEG4BPFI6ZX series adapter"},
6079         {"Silicom Bypass MxEG6BPI6 series adapter"},
6080         {"Silicom Bypass MxE2G4BPi80 series adapter"},
6081         {"Silicom Bypass MxE2G4BPFi80 series adapter"},
6082         {"Silicom Bypass MxE2G4BPFi80LX series adapter"},
6083         {"Silicom Bypass MxE2G4BPFi80ZX series adapter"},
6084
6085         {"Silicom Bypass PE210G2SPI9 series adapter"},
6086
6087         {"Silicom Bypass MxE210G2BPI9CX4 series adapter"},
6088         {"Silicom Bypass MxE210G2BPI9SR series adapter"},
6089         {"Silicom Bypass MxE210G2BPI9LR series adapter"},
6090         {"Silicom Bypass MxE210G2BPI9T series adapter"},
6091
6092         {"Silicom Bypass PE210G2BPI9CX4 series adapter"},
6093         {"Silicom Bypass PE210G2BPI9SR series adapter"},
6094         {"Silicom Bypass PE210G2BPI9LR series adapter"},
6095         {"Silicom Bypass PE210G2BPI9T series adapter"},
6096
6097         {"Silicom Bypass M2EG2BPFI6 series adapter"},
6098         {"Silicom Bypass M2EG2BPFI6LX series adapter"},
6099         {"Silicom Bypass M2EG2BPFI6ZX series adapter"},
6100         {"Silicom Bypass M2EG4BPI6 series adapter"},
6101         {"Silicom Bypass M2EG4BPFI6 series adapter"},
6102         {"Silicom Bypass M2EG4BPFI6LX series adapter"},
6103         {"Silicom Bypass M2EG4BPFI6ZX series adapter"},
6104         {"Silicom Bypass M2EG6BPI6 series adapter"},
6105
6106         {"Silicom Bypass PEG2DBI6    series adapter"},
6107         {"Silicom Bypass PEG2DBFI6   series adapter"},
6108         {"Silicom Bypass PEG2DBFI6LX series adapter"},
6109         {"Silicom Bypass PEG2DBFI6ZX series adapter"},
6110
6111         {"Silicom Bypass PE2G4BPi80 series adapter"},
6112         {"Silicom Bypass PE2G4BPFi80 series adapter"},
6113         {"Silicom Bypass PE2G4BPFi80LX series adapter"},
6114         {"Silicom Bypass PE2G4BPFi80ZX series adapter"},
6115
6116         {"Silicom Bypass PE2G4BPi80L series adapter"},
6117         {"Silicom Bypass MxE2G8BPi80A series adapter"},
6118
6119         {"Silicom Bypass PE2G2BPi35 series adapter"},
6120         {"Silicom Bypass PAC1200BPi35 series adapter"},
6121         {"Silicom Bypass PE2G2BPFi35 series adapter"},
6122         {"Silicom Bypass PE2G2BPFi35LX series adapter"},
6123         {"Silicom Bypass PE2G2BPFi35ZX series adapter"},
6124
6125         {"Silicom Bypass PE2G4BPi35 series adapter"},
6126         {"Silicom Bypass PE2G4BPi35L series adapter"},
6127         {"Silicom Bypass PE2G4BPFi35 series adapter"},
6128         {"Silicom Bypass PE2G4BPFi35LX series adapter"},
6129         {"Silicom Bypass PE2G4BPFi35ZX series adapter"},
6130
6131         {"Silicom Bypass PE2G6BPi35 series adapter"},
6132         {"Silicom Bypass PE2G6BPi35CX series adapter"},
6133
6134         {"Silicom Bypass PE2G2BPi80 series adapter"},
6135         {"Silicom Bypass PE2G2BPFi80 series adapter"},
6136         {"Silicom Bypass PE2G2BPFi80LX series adapter"},
6137         {"Silicom Bypass PE2G2BPFi80ZX series adapter"},
6138
6139         {"Silicom Bypass M2E10G2BPI9CX4 series adapter"},
6140         {"Silicom Bypass M2E10G2BPI9SR series adapter"},
6141         {"Silicom Bypass M2E10G2BPI9LR series adapter"},
6142         {"Silicom Bypass M2E10G2BPI9T series adapter"},
6143         {"Silicom Bypass MxE2G8BPi80 series adapter"},
6144         {"Silicom Bypass PE210G2DBi9SR series adapter"},
6145         {"Silicom Bypass PE210G2DBi9SRRB series adapter"},
6146         {"Silicom Bypass PE210G2DBi9LR series adapter"},
6147         {"Silicom Bypass PE210G2DBi9LRRB series adapter"},
6148         {"Silicom Bypass PE310G4DBi9-SR series adapter"},
6149         {"Silicom Bypass PE310G4BPi9T series adapter"},
6150         {"Silicom Bypass PE310G4BPi9SR series adapter"},
6151         {"Silicom Bypass PE310G4BPi9LR series adapter"},
6152         {"Silicom Bypass PE210G2BPi40T series adapter"},
6153         {0},
6154 };
6155
6156 static struct bpmod_info tx_ctl_pci_tbl[] = {
6157         {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFI_SSID, PXG2BPFI,
6158          "PXG2BPFI-SD"},
6159         {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFIL_SSID, PXG2BPFIL,
6160          "PXG2BPFIL-SD"},
6161         {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILX_SSID, PXG2BPFILX,
6162          "PXG2BPFILX-SD"},
6163         {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILLX_SSID, PXG2BPFILLX,
6164          "PXG2BPFILLXSD"},
6165         {0x8086, 0x1010, SILICOM_SVID, SILICOM_PXGBPI_SSID, PXGBPI,
6166          "PXG2BPI-SD"},
6167         {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXGBPIG_SSID, PXGBPIG,
6168          "PXG2BPIG-SD"},
6169         {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2TBFI_SSID, PXG2TBFI,
6170          "PXG2TBFI-SD"},
6171         {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI,
6172          "PXG4BPI-SD"},
6173         {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI,
6174          "PXG4BPFI-SD"},
6175         {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFILX_SSID, PXG4BPFILX,
6176          "PXG4BPFILX-SD"},
6177         {0x8086, 0x1079, SILICOM_SVID, SILICOM_PEG4BPI_SSID, PEG4BPI,
6178          "PEXG4BPI-SD"},
6179         {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPI_SSID, PEG2BPI,
6180          "PEG2BPI-SD"},
6181         {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIN_SSID, PEG4BPIN,
6182          "PEG4BPI-SD"},
6183         {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFI_SSID, PEG2BPFI,
6184          "PEG2BPFI-SD"},
6185         {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFILX_SSID, PEG2BPFILX,
6186          "PEG2BPFILX-SD"},
6187         {0x8086, 0x107a, SILICOM_SVID, SILICOM_PMCXG2BPFI_SSID, PMCXG2BPFI,
6188          "PMCX2BPFI-SD"},
6189         {0x8086, 0x107a, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPFIN_SSID,
6190          PMCXG2BPFIN, "PMCX2BPFI-N"},
6191         {0x8086, INTEL_PEG4BPII_PID, 0x8086, INTEL_PEG4BPII_SSID, PEG4BPII,
6192          "PEG4BPII"},
6193         {0x8086, INTEL_PEG4BPIIO_PID, 0x8086, INTEL_PEG4BPIIO_SSID, PEG4BPIIO,
6194          "PEG4BPII0"},
6195         {0x8086, INTEL_PEG4BPFII_PID, 0x8086, INTEL_PEG4BPFII_SSID, PEG4BPFII,
6196          "PEG4BPFII"},
6197         {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN_SSID,
6198          PMCXG2BPIN, "PMCX2BPI-N"},
6199         {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN_SSID,
6200          PMCXG4BPIN, "PMCX4BPI-N"},
6201         {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1,
6202          "PXG2BISC1-SD"},
6203         {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2TBFI_SSID, PEG2TBFI,
6204          "PEG2TBFI-SD"},
6205         {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI,
6206          "PXG2TBI-SD"},
6207         {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFID_SSID, PXG4BPFID,
6208          "PXG4BPFID-SD"},
6209         {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI,
6210          "PEG4BPFI-SD"},
6211         {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIPT_SSID, PEG4BPIPT,
6212          "PEG4BPIPT-SD"},
6213         {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG6BPI_SSID, PXG6BPI,
6214          "PXG6BPI-SD"},
6215         {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
6216          SILICOM_PEG4BPIL_SSID /*PCI_ANY_ID */ , PEG4BPIL, "PEG4BPIL-SD"},
6217         {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN2_SSID,
6218          PMCXG2BPIN2, "PMCX2BPI-N2"},
6219         {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN2_SSID,
6220          PMCXG4BPIN2, "PMCX4BPI-N2"},
6221         {0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX2BPI_SSID, PMCX2BPI,
6222          "PMCX2BPI-SD"},
6223         {0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX4BPI_SSID, PMCX4BPI,
6224          "PMCX4BPI-SD"},
6225         {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFID_SSID, PEG2BPFID,
6226          "PEG2BPFID-SD"},
6227         {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFIDLX_SSID, PEG2BPFIDLX,
6228          "PEG2BPFIDLXSD"},
6229         {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILN_SSID, MEG2BPFILN,
6230          "MEG2BPFILN-SD"},
6231         {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFINX_SSID, MEG2BPFINX,
6232          "MEG2BPFINX-SD"},
6233         {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFILX_SSID, PEG4BPFILX,
6234          "PEG4BPFILX-SD"},
6235         {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPISR_SSID,
6236          PE10G2BPISR, "PE10G2BPISR"},
6237         {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPILR_SSID,
6238          PE10G2BPILR, "PE10G2BPILR"},
6239         {0x8086, 0x10a9, SILICOM_SVID, SILICOM_MHIO8AD_SSID, MHIO8AD,
6240          "MHIO8AD-SD"},
6241         {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPICX4_SSID,
6242          PE10G2BPISR, "PE10G2BPICX4"},
6243         {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
6244          SILICOM_PEG2BPI5_SSID /*PCI_ANY_ID */ , PEG2BPI5, "PEG2BPI5-SD"},
6245         {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
6246          SILICOM_PEG6BPI_SSID /*PCI_ANY_ID */ , PEG6BPI, "PEG6BPI5"},
6247         {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG4BPFI5_SSID,
6248          PEG4BPFI5, "PEG4BPFI5"},
6249         {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ ,
6250          SILICOM_PEG4BPFI5LX_SSID, PEG4BPFI5LX, "PEG4BPFI5LX"},
6251         {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXLN_SSID, MEG2BPFILXLN,
6252          "MEG2BPFILXLN"},
6253         {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPIX1_SSID, PEG2BPIX1,
6254          "PEG2BPIX1-SD"},
6255         {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXNX_SSID, MEG2BPFILXNX,
6256          "MEG2BPFILXNX"},
6257         {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPIT_SSID, XE10G2BPIT,
6258          "XE10G2BPIT"},
6259         {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPICX4_SSID,
6260          XE10G2BPICX4, "XE10G2BPICX4"},
6261         {0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPISR_SSID, XE10G2BPISR,
6262          "XE10G2BPISR"},
6263         {0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPILR_SSID, XE10G2BPILR,
6264          "XE10G2BPILR"},
6265         {0x8086, 0x10C6, NOKIA_XE10G2BPIXR_SVID, NOKIA_XE10G2BPIXR_SSID,
6266          XE10G2BPIXR, "XE10G2BPIXR"},
6267         {0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBISR_SSID, PE10GDBISR,
6268          "PE10G2DBISR"},
6269         {0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBILR_SSID, PE10GDBILR,
6270          "PE10G2DBILR"},
6271         {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
6272          SILICOM_PEG2BISC6_SSID /*PCI_ANY_ID */ , PEG2BISC6, "PEG2BI5SC6"},
6273         {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ ,
6274          SILICOM_PEG6BPIFC_SSID /*PCI_ANY_ID */ , PEG6BPIFC, "PEG6BPI5FC"},
6275
6276         {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
6277          SILICOM_PE10G2BPTCX4_SSID, PE10G2BPTCX4, "PE10G2BPTCX4"},
6278         {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
6279          SILICOM_PE10G2BPTSR_SSID, PE10G2BPTSR, "PE10G2BPTSR"},
6280         {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
6281          SILICOM_PE10G2BPTLR_SSID, PE10G2BPTLR, "PE10G2BPTLR"},
6282         {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
6283          SILICOM_PE10G2BPTT_SSID, PE10G2BPTT, "PE10G2BPTT"},
6284
6285         /* {BROADCOM_VID, BROADCOM_PE10G2_PID, PCI_ANY_ID, PCI_ANY_ID, PE10G2BPTCX4, "PE10G2BPTCX4"}, */
6286
6287         {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6288          SILICOM_PEG4BPI6_SSID /*PCI_ANY_ID */ , PEG4BPI6, "PEG4BPI6"},
6289         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6290          SILICOM_PEG4BPFI6_SSID /*PCI_ANY_ID */ , PEG4BPFI6, "PEG4BPFI6"},
6291         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6292          SILICOM_PEG4BPFI6LX_SSID /*PCI_ANY_ID */ , PEG4BPFI6LX, "PEG4BPFI6LX"},
6293         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6294          SILICOM_PEG4BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6ZX, "PEG4BPFI6ZX"},
6295         {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6296          SILICOM_PEG2BPI6_SSID /*PCI_ANY_ID */ , PEG2BPI6, "PEG2BPI6"},
6297         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6298          SILICOM_PEG2BPFI6_SSID /*PCI_ANY_ID */ , PEG2BPFI6, "PEG2BPFI6"},
6299         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6300          SILICOM_PEG2BPFI6LX_SSID /*PCI_ANY_ID */ , PEG2BPFI6LX, "PEG2BPFI6LX"},
6301         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6302          SILICOM_PEG2BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG2BPFI6ZX, "PEG2BPFI6ZX"},
6303         {0x8086, 0x10e7, SILICOM_SVID /*PCI_ANY_ID */ ,
6304          SILICOM_PEG2BPFI6FLXM_SSID /*PCI_ANY_ID */ , PEG2BPFI6FLXM,
6305          "PEG2BPFI6FLXM"},
6306         {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6307          SILICOM_PEG4BPI6FC_SSID /*PCI_ANY_ID */ , PEG4BPI6FC, "PEG4BPI6FC"},
6308         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6309          SILICOM_PEG4BPFI6FC_SSID /*PCI_ANY_ID */ , PEG4BPFI6FC, "PEG4BPFI6FC"},
6310         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6311          SILICOM_PEG4BPFI6FCLX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCLX,
6312          "PEG4BPFI6FCLX"},
6313         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6314          SILICOM_PEG4BPFI6FCZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCZX,
6315          "PEG4BPFI6FCZX"},
6316         {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6317          SILICOM_PEG6BPI6_SSID /*PCI_ANY_ID */ , PEG6BPI6, "PEG6BPI6"},
6318         {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6319          SILICOM_PEG2BPI6SC6_SSID /*PCI_ANY_ID */ , PEG2BPI6SC6,
6320          "PEG6BPI62SC6"},
6321         {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6322          SILICOM_MEG2BPI6_SSID /*PCI_ANY_ID */ , MEG2BPI6, "MEG2BPI6"},
6323         {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6324          SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID */ , XEG2BPI6, "XEG2BPI6"},
6325         {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6326          SILICOM_MEG4BPI6_SSID /*PCI_ANY_ID */ , MEG4BPI6, "MEG4BPI6"},
6327
6328         {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG2BPFI5_SSID,
6329          PEG2BPFI5, "PEG2BPFI5"},
6330         {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ ,
6331          SILICOM_PEG2BPFI5LX_SSID, PEG2BPFI5LX, "PEG2BPFI5LX"},
6332
6333         {0x8086, 0x105f, SILICOM_SVID, SILICOM_PXEG4BPFI_SSID, PXEG4BPFI,
6334          "PXEG4BPFI-SD"},
6335
6336         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6337          SILICOM_M1EG2BPI6_SSID /*PCI_ANY_ID */ , M1EG2BPI6, "MxEG2BPI6"},
6338
6339         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6340          SILICOM_M1EG2BPFI6_SSID /*PCI_ANY_ID */ , M1EG2BPFI6, "MxEG2BPFI6"},
6341         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6342          SILICOM_M1EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6LX,
6343          "MxEG2BPFI6LX"},
6344         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6345          SILICOM_M1EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6ZX,
6346          "MxEG2BPFI6ZX"},
6347
6348         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6349          SILICOM_M1EG4BPI6_SSID /*PCI_ANY_ID */ , M1EG4BPI6, "MxEG4BPI6"},
6350
6351         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6352          SILICOM_M1EG4BPFI6_SSID /*PCI_ANY_ID */ , M1EG4BPFI6, "MxEG4BPFI6"},
6353         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6354          SILICOM_M1EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6LX,
6355          "MxEG4BPFI6LX"},
6356         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6357          SILICOM_M1EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6ZX,
6358          "MxEG4BPFI6ZX"},
6359
6360         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6361          SILICOM_M1EG6BPI6_SSID /*PCI_ANY_ID */ , M1EG6BPI6, "MxEG6BPI6"},
6362
6363         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6364          SILICOM_M1E2G4BPi80_SSID /*PCI_ANY_ID */ , M1E2G4BPi80, "MxE2G4BPi80"},
6365         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6366          SILICOM_M1E2G4BPFi80_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80,
6367          "MxE2G4BPFi80"},
6368         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6369          SILICOM_M1E2G4BPFi80LX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80LX,
6370          "MxE2G4BPFi80LX"},
6371         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6372          SILICOM_M1E2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80ZX,
6373          "MxE2G4BPFi80ZX"},
6374
6375         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6376          SILICOM_M2EG2BPFI6_SSID /*PCI_ANY_ID */ , M2EG2BPFI6, "M2EG2BPFI6"},
6377         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6378          SILICOM_M2EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6LX,
6379          "M2EG2BPFI6LX"},
6380         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6381          SILICOM_M2EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6ZX,
6382          "M2EG2BPFI6ZX"},
6383
6384         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6385          SILICOM_M2EG4BPI6_SSID /*PCI_ANY_ID */ , M2EG4BPI6, "M2EG4BPI6"},
6386
6387         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6388          SILICOM_M2EG4BPFI6_SSID /*PCI_ANY_ID */ , M2EG4BPFI6, "M2EG4BPFI6"},
6389         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6390          SILICOM_M2EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6LX,
6391          "M2EG4BPFI6LX"},
6392         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6393          SILICOM_M2EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6ZX,
6394          "M2EG4BPFI6ZX"},
6395
6396         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6397          SILICOM_M2EG6BPI6_SSID /*PCI_ANY_ID */ , M2EG6BPI6, "M2EG6BPI6"},
6398
6399         {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6400          SILICOM_PEG2DBI6_SSID /*PCI_ANY_ID */ , PEG2DBI6, "PEG2DBI6"},
6401         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6402          SILICOM_PEG2DBFI6_SSID /*PCI_ANY_ID */ , PEG2DBFI6, "PEG2DBFI6"},
6403         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6404          SILICOM_PEG2DBFI6LX_SSID /*PCI_ANY_ID */ , PEG2DBFI6LX, "PEG2DBFI6LX"},
6405         {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ ,
6406          SILICOM_PEG2DBFI6ZX_SSID /*PCI_ANY_ID */ , PEG2DBFI6ZX, "PEG2DBFI6ZX"},
6407
6408         {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
6409          SILICOM_PE210G2DBi9SR_SSID, PE210G2DBi9SR, "PE210G2DBi9SR"},
6410         {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
6411          SILICOM_PE210G2DBi9LR_SSID, PE210G2DBi9LR, "PE210G2DBi9LR"},
6412         {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
6413          SILICOM_PE310G4DBi940SR_SSID, PE310G4DBi940SR, "PE310G4DBi9SR"},
6414
6415         {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6416          SILICOM_PE310G4BPi9T_SSID, PE310G4BPi9T, "PE310G4BPi9T"},
6417         {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6418          SILICOM_PE310G4BPi9SR_SSID, PE310G4BPi9SR, "PE310G4BPi9SR"},
6419         {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6420          SILICOM_PE310G4BPi9LR_SSID, PE310G4BPi9LR, "PE310G4BPi9LR"},
6421
6422         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6423          SILICOM_PE2G4BPi80_SSID /*PCI_ANY_ID */ , PE2G4BPi80, "PE2G4BPi80"},
6424         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6425          SILICOM_PE2G4BPFi80_SSID /*PCI_ANY_ID */ , PE2G4BPFi80, "PE2G4BPFi80"},
6426         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6427          SILICOM_PE2G4BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80LX,
6428          "PE2G4BPFi80LX"},
6429         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6430          SILICOM_PE2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80ZX,
6431          "PE2G4BPFi80ZX"},
6432
6433         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6434          SILICOM_PE2G4BPi80L_SSID /*PCI_ANY_ID */ , PE2G4BPi80L, "PE2G4BPi80L"},
6435
6436         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6437          SILICOM_M6E2G8BPi80A_SSID /*PCI_ANY_ID */ , M6E2G8BPi80A,
6438          "MxE2G8BPi80A"},
6439
6440         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6441          SILICOM_PE2G2BPi35_SSID /*PCI_ANY_ID */ , PE2G2BPi35, "PE2G2BPi35"},
6442         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6443          SILICOM_PAC1200BPi35_SSID /*PCI_ANY_ID */ , PAC1200BPi35,
6444          "PAC1200BPi35"},
6445
6446         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6447          SILICOM_PE2G2BPFi35_SSID /*PCI_ANY_ID */ , PE2G2BPFi35, "PE2G2BPFi35"},
6448         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6449          SILICOM_PE2G2BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35LX,
6450          "PE2G2BPFi35LX"},
6451         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6452          SILICOM_PE2G2BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35ZX,
6453          "PE2G2BPFi35ZX"},
6454
6455         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6456          SILICOM_PE2G4BPi35_SSID /*PCI_ANY_ID */ , PE2G4BPi35, "PE2G4BPi35"},
6457
6458         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6459          SILICOM_PE2G4BPi35L_SSID /*PCI_ANY_ID */ , PE2G4BPi35L, "PE2G4BPi35L"},
6460
6461         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6462          SILICOM_PE2G4BPFi35_SSID /*PCI_ANY_ID */ , PE2G4BPFi35, "PE2G4BPFi35"},
6463         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6464          SILICOM_PE2G4BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35LX,
6465          "PE2G4BPFi35LX"},
6466         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6467          SILICOM_PE2G4BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35ZX,
6468          "PE2G4BPFi35ZX"},
6469
6470         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6471          SILICOM_PE2G6BPi35_SSID /*PCI_ANY_ID */ , PE2G6BPi35, "PE2G6BPi35"},
6472
6473
6474         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa0, PE2G6BPi35CX,
6475          "PE2G6BPi35CX"},
6476         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa1, PE2G6BPi35CX,
6477          "PE2G6BPi35CX"},
6478         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa2, PE2G6BPi35CX,
6479          "PE2G6BPi35CX"},
6480         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa3, PE2G6BPi35CX,
6481          "PE2G6BPi35CX"},
6482         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa4, PE2G6BPi35CX,
6483          "PE2G6BPi35CX"},
6484         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa5, PE2G6BPi35CX,
6485          "PE2G6BPi35CX"},
6486         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa6, PE2G6BPi35CX,
6487          "PE2G6BPi35CX"},
6488         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa7, PE2G6BPi35CX,
6489          "PE2G6BPi35CX"},
6490         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa8, PE2G6BPi35CX,
6491          "PE2G6BPi35CX"},
6492         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa9, PE2G6BPi35CX,
6493          "PE2G6BPi35CX"},
6494         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaa, PE2G6BPi35CX,
6495          "PE2G6BPi35CX"},
6496         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaab, PE2G6BPi35CX,
6497          "PE2G6BPi35CX"},
6498         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaac, PE2G6BPi35CX,
6499          "PE2G6BPi35CX"},
6500         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaad, PE2G6BPi35CX,
6501          "PE2G6BPi35CX"},
6502         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaae, PE2G6BPi35CX,
6503          "PE2G6BPi35CX"},
6504         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaf, PE2G6BPi35CX,
6505          "PE2G6BPi35CX"},
6506         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab0, PE2G6BPi35CX,
6507          "PE2G6BPi35CX"},
6508         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab1, PE2G6BPi35CX,
6509          "PE2G6BPi35CX"},
6510         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab2, PE2G6BPi35CX,
6511          "PE2G6BPi35CX"},
6512         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab3, PE2G6BPi35CX,
6513          "PE2G6BPi35CX"},
6514         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab4, PE2G6BPi35CX,
6515          "PE2G6BPi35CX"},
6516         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab5, PE2G6BPi35CX,
6517          "PE2G6BPi35CX"},
6518         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab6, PE2G6BPi35CX,
6519          "PE2G6BPi35CX"},
6520         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab7, PE2G6BPi35CX,
6521          "PE2G6BPi35CX"},
6522         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab8, PE2G6BPi35CX,
6523          "PE2G6BPi35CX"},
6524         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab9, PE2G6BPi35CX,
6525          "PE2G6BPi35CX"},
6526         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaba, PE2G6BPi35CX,
6527          "PE2G6BPi35CX"},
6528         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabb, PE2G6BPi35CX,
6529          "PE2G6BPi35CX"},
6530         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabc, PE2G6BPi35CX,
6531          "PE2G6BPi35CX"},
6532         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabd, PE2G6BPi35CX,
6533          "PE2G6BPi35CX"},
6534         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabe, PE2G6BPi35CX,
6535          "PE2G6BPi35CX"},
6536         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabf, PE2G6BPi35CX,
6537          "PE2G6BPi35CX"},
6538
6539         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6540          SILICOM_PE2G2BPi80_SSID /*PCI_ANY_ID */ , PE2G2BPi80, "PE2G2BPi80"},
6541         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6542          SILICOM_PE2G2BPFi80_SSID /*PCI_ANY_ID */ , PE2G2BPFi80, "PE2G2BPFi80"},
6543         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6544          SILICOM_PE2G2BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi80LX,
6545          "PE2G2BPFi80LX"},
6546         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6547          SILICOM_PE2G2BPFi80ZX_SSID /*PCI_ANY_ID */ , PE2G2BPFi80ZX,
6548          "PE2G2BPFi80ZX"},
6549
6550         {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6551          SILICOM_MEG2BPI6_SSID /*PCI_ANY_ID */ , MEG2BPI6, "MEG2BPI6"},
6552         {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
6553          SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID */ , XEG2BPI6, "XEG2BPI6"},
6554
6555 #if 0
6556         {0x8086, 0x10fb, 0x8086, INTEL_PE210G2SPI9_SSID, PE210G2SPI9,
6557          "PE210G2SPI9"},
6558 #endif
6559         {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6560          SILICOM_M1E10G2BPI9CX4_SSID /*PCI_ANY_ID */ , M1E10G2BPI9CX4,
6561          "MxE210G2BPI9CX4"},
6562         {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6563          SILICOM_M1E10G2BPI9SR_SSID /*PCI_ANY_ID */ , M1E10G2BPI9SR,
6564          "MxE210G2BPI9SR"},
6565         {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6566          SILICOM_M1E10G2BPI9LR_SSID /*PCI_ANY_ID */ , M1E10G2BPI9LR,
6567          "MxE210G2BPI9LR"},
6568         {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6569          SILICOM_M1E10G2BPI9T_SSID /*PCI_ANY_ID */ , M1E10G2BPI9T,
6570          "MxE210G2BPI9T"},
6571
6572         {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6573          SILICOM_M2E10G2BPI9CX4_SSID /*PCI_ANY_ID */ , M2E10G2BPI9CX4,
6574          "M2E10G2BPI9CX4"},
6575         {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6576          SILICOM_M2E10G2BPI9SR_SSID /*PCI_ANY_ID */ , M2E10G2BPI9SR,
6577          "M2E10G2BPI9SR"},
6578         {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6579          SILICOM_M2E10G2BPI9LR_SSID /*PCI_ANY_ID */ , M2E10G2BPI9LR,
6580          "M2E10G2BPI9LR"},
6581         {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ ,
6582          SILICOM_M2E10G2BPI9T_SSID /*PCI_ANY_ID */ , M2E10G2BPI9T,
6583          "M2E10G2BPI9T"},
6584
6585         {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9CX4_SSID,
6586          PE210G2BPI9CX4, "PE210G2BPI9CX4"},
6587         {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9SR_SSID,
6588          PE210G2BPI9SR, "PE210G2BPI9SR"},
6589         {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9LR_SSID,
6590          PE210G2BPI9LR, "PE210G2BPI9LR"},
6591         {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9T_SSID, PE210G2BPI9T,
6592          "PE210G2BPI9T"},
6593
6594 #if 0
6595         {0x1374, 0x2c, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI,
6596          "PXG4BPI-SD"},
6597
6598         {0x1374, 0x2d, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI,
6599          "PXG4BPFI-SD"},
6600
6601         {0x1374, 0x3f, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI,
6602          "PXG2TBI-SD"},
6603
6604         {0x1374, 0x3d, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1,
6605          "PXG2BISC1-SD"},
6606
6607         {0x1374, 0x40, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI,
6608          "PEG4BPFI-SD"},
6609
6610 #ifdef BP_SELF_TEST
6611         {0x1374, 0x28, SILICOM_SVID, 0x28, PXGBPI, "PXG2BPI-SD"},
6612 #endif
6613 #endif
6614         {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
6615          SILICOM_M6E2G8BPi80_SSID /*PCI_ANY_ID */ , M6E2G8BPi80, "MxE2G8BPi80"},
6616         {0x8086, 0x1528, SILICOM_SVID /*PCI_ANY_ID */ ,
6617          SILICOM_PE210G2BPi40_SSID /*PCI_ANY_ID */ , PE210G2BPi40,
6618          "PE210G2BPi40T"},
6619
6620         /* required last entry */
6621         {0,}
6622 };
6623
6624 static void find_fw(struct bpctl_dev *dev)
6625 {
6626         unsigned long mmio_start, mmio_len;
6627         struct pci_dev *pdev1 = dev->pdev;
6628
6629         if ((OLD_IF_SERIES(dev->subdevice)) ||
6630             (INTEL_IF_SERIES(dev->subdevice)))
6631                 dev->bp_fw_ver = 0xff;
6632         else
6633                 dev->bp_fw_ver = bypass_fw_ver(dev);
6634
6635         if (dev->bp_10gb == 1 && dev->bp_fw_ver == 0xff) {
6636                 int cnt = 100;
6637                 while (cnt--) {
6638                         iounmap((void *)dev->mem_map);
6639                         mmio_start = pci_resource_start(pdev1, 0);
6640                         mmio_len = pci_resource_len(pdev1, 0);
6641
6642                         dev->mem_map = (unsigned long)
6643                             ioremap(mmio_start, mmio_len);
6644
6645                         dev->bp_fw_ver = bypass_fw_ver(dev);
6646                         if (dev->bp_fw_ver == 0xa8)
6647                                 break;
6648                 }
6649         }
6650         /* dev->bp_fw_ver=0xa8; */
6651         printk("firmware version: 0x%x\n", dev->bp_fw_ver);
6652 }
6653
6654 static int init_one(struct bpctl_dev *dev, struct bpmod_info *info, struct pci_dev *pdev1)
6655 {
6656         unsigned long mmio_start, mmio_len;
6657
6658         dev->pdev = pdev1;
6659         mmio_start = pci_resource_start(pdev1, 0);
6660         mmio_len = pci_resource_len(pdev1, 0);
6661
6662         dev->desc = dev_desc[info->index].name;
6663         dev->name = info->bp_name;
6664         dev->device = info->device;
6665         dev->vendor = info->vendor;
6666         dev->subdevice = info->subdevice;
6667         dev->subvendor = info->subvendor;
6668         dev->func = PCI_FUNC(pdev1->devfn);
6669         dev->slot = PCI_SLOT(pdev1->devfn);
6670         dev->bus = pdev1->bus->number;
6671         dev->mem_map = (unsigned long)ioremap(mmio_start, mmio_len);
6672 #ifdef BP_SYNC_FLAG
6673         spin_lock_init(&dev->bypass_wr_lock);
6674 #endif
6675         if (BP10G9_IF_SERIES(dev->subdevice))
6676                 dev->bp_10g9 = 1;
6677         if (BP10G_IF_SERIES(dev->subdevice))
6678                 dev->bp_10g = 1;
6679         if (PEG540_IF_SERIES(dev->subdevice))
6680                 dev->bp_540 = 1;
6681         if (PEGF5_IF_SERIES(dev->subdevice))
6682                 dev->bp_fiber5 = 1;
6683         if (PEG80_IF_SERIES(dev->subdevice))
6684                 dev->bp_i80 = 1;
6685         if (PEGF80_IF_SERIES(dev->subdevice))
6686                 dev->bp_i80 = 1;
6687         if ((dev->subdevice & 0xa00) == 0xa00)
6688                 dev->bp_i80 = 1;
6689         if (BP10GB_IF_SERIES(dev->subdevice)) {
6690                 if (dev->ifindex == 0) {
6691                         unregister_chrdev(major_num, DEVICE_NAME);
6692                         printk("Please load network driver for %s adapter!\n",
6693                              dev->name);
6694                         return -1;
6695                 }
6696
6697                 if (dev->ndev && !(dev->ndev->flags & IFF_UP)) {
6698                         unregister_chrdev(major_num, DEVICE_NAME);
6699                         printk("Please bring up network interfaces for %s adapter!\n",
6700                              dev->name);
6701                         return -1;
6702                 }
6703                 dev->bp_10gb = 1;
6704         }
6705
6706         if (!dev->bp_10g9) {
6707                 if (is_bypass_fn(dev)) {
6708                         printk(KERN_INFO "%s found, ",
6709                                dev->name);
6710                         find_fw(dev);
6711                 }
6712                 dev->wdt_status = WDT_STATUS_UNKNOWN;
6713                 dev->reset_time = 0;
6714                 atomic_set(&dev->wdt_busy, 0);
6715                 dev->bp_status_un = 1;
6716
6717                 bypass_caps_init(dev);
6718
6719                 init_bypass_wd_auto(dev);
6720                 init_bypass_tpl_auto(dev);
6721                 if (NOKIA_SERIES(dev->subdevice))
6722                         reset_cont(dev);
6723         }
6724 #ifdef BP_SELF_TEST
6725         dev->bp_tx_data = kzalloc(BPTEST_DATA_LEN, GFP_KERNEL);
6726         if (dev->bp_tx_data) {
6727                 memset(dev->bp_tx_data, 0xff, 6);
6728                 memset(dev->bp_tx_data + 6, 0x0, 1);
6729                 memset(dev->bp_tx_data + 7, 0xaa, 5);
6730                 *(__be16 *)(dev->bp_tx_data + 12) = htons(ETH_P_BPTEST);
6731         } else
6732                 printk("bp_ctl: Memory allocation error!\n");
6733 #endif
6734         return 0;
6735 }
6736
6737 /*
6738 * Initialize the module - Register the character device
6739 */
6740
6741 static int __init bypass_init_module(void)
6742 {
6743         int ret_val, idx, idx_dev = 0;
6744         struct pci_dev *pdev1 = NULL;
6745         struct bpctl_dev *dev;
6746
6747         printk(BP_MOD_DESCR " v" BP_MOD_VER "\n");
6748         ret_val = register_chrdev(major_num, DEVICE_NAME, &Fops);
6749         if (ret_val < 0) {
6750                 printk("%s failed with %d\n", DEVICE_NAME, ret_val);
6751                 return ret_val;
6752         }
6753         major_num = ret_val;    /* dynamic */
6754         for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) {
6755                 while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor,
6756                                                tx_ctl_pci_tbl[idx].device,
6757                                                tx_ctl_pci_tbl[idx].subvendor,
6758                                                tx_ctl_pci_tbl[idx].subdevice,
6759                                                pdev1))) {
6760
6761                         device_num++;
6762                 }
6763         }
6764         if (!device_num) {
6765                 printk("No such device\n");
6766                 unregister_chrdev(major_num, DEVICE_NAME);
6767                 return -1;
6768         }
6769
6770         bpctl_dev_arr = kmalloc((device_num) * sizeof(struct bpctl_dev), GFP_KERNEL);
6771
6772         if (!bpctl_dev_arr) {
6773                 printk("Allocation error\n");
6774                 unregister_chrdev(major_num, DEVICE_NAME);
6775                 return -1;
6776         }
6777         memset(bpctl_dev_arr, 0, ((device_num) * sizeof(struct bpctl_dev)));
6778
6779         pdev1 = NULL;
6780         dev = bpctl_dev_arr;
6781         for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) {
6782                 while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor,
6783                                                tx_ctl_pci_tbl[idx].device,
6784                                                tx_ctl_pci_tbl[idx].subvendor,
6785                                                tx_ctl_pci_tbl[idx].subdevice,
6786                                                pdev1))) {
6787                         if (init_one(dev, &tx_ctl_pci_tbl[idx], pdev1) < 0)
6788                                 return -1;
6789                         dev++;
6790                 }
6791         }
6792         if_scan_init();
6793
6794         sema_init(&bpctl_sema, 1);
6795         spin_lock_init(&bpvm_lock);
6796         {
6797
6798                 struct bpctl_dev *pbpctl_dev_c = NULL;
6799                 for (idx_dev = 0, dev = bpctl_dev_arr;
6800                      idx_dev < device_num && dev->pdev;
6801                      idx_dev++, dev++) {
6802                         if (dev->bp_10g9) {
6803                                 pbpctl_dev_c = get_status_port_fn(dev);
6804                                 if (is_bypass_fn(dev)) {
6805                                         printk(KERN_INFO "%s found, ",
6806                                                dev->name);
6807                                         dev->bp_fw_ver = bypass_fw_ver(dev);
6808                                         printk("firmware version: 0x%x\n",
6809                                                dev->bp_fw_ver);
6810                                 }
6811                                 dev->wdt_status = WDT_STATUS_UNKNOWN;
6812                                 dev->reset_time = 0;
6813                                 atomic_set(&dev->wdt_busy, 0);
6814                                 dev->bp_status_un = 1;
6815
6816                                 bypass_caps_init(dev);
6817
6818                                 init_bypass_wd_auto(dev);
6819                                 init_bypass_tpl_auto(dev);
6820
6821                         }
6822
6823                 }
6824         }
6825
6826         register_netdevice_notifier(&bp_notifier_block);
6827 #ifdef BP_PROC_SUPPORT
6828         {
6829                 int i = 0;
6830                 /* unsigned long flags; */
6831                 /* rcu_read_lock(); */
6832                 bp_proc_create();
6833                 for (i = 0; i < device_num; i++) {
6834                         if (bpctl_dev_arr[i].ifindex) {
6835                                 /* spin_lock_irqsave(&bpvm_lock, flags); */
6836                                 bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]);
6837                                 bypass_proc_create_dev_sd(&bpctl_dev_arr[i]);
6838                                 /* spin_unlock_irqrestore(&bpvm_lock, flags); */
6839                         }
6840
6841                 }
6842                 /* rcu_read_unlock(); */
6843         }
6844 #endif
6845
6846         return 0;
6847 }
6848
6849 /*
6850 * Cleanup - unregister the appropriate file from /proc
6851 */
6852 static void __exit bypass_cleanup_module(void)
6853 {
6854         int i;
6855         unregister_netdevice_notifier(&bp_notifier_block);
6856
6857         for (i = 0; i < device_num; i++) {
6858                 /* unsigned long flags; */
6859 #ifdef BP_PROC_SUPPORT
6860 /*      spin_lock_irqsave(&bpvm_lock, flags);
6861         rcu_read_lock(); */
6862                 bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]);
6863 /*      spin_unlock_irqrestore(&bpvm_lock, flags);
6864         rcu_read_unlock(); */
6865 #endif
6866                 remove_bypass_wd_auto(&bpctl_dev_arr[i]);
6867                 bpctl_dev_arr[i].reset_time = 0;
6868
6869                 remove_bypass_tpl_auto(&bpctl_dev_arr[i]);
6870         }
6871
6872         /* unmap all devices */
6873         for (i = 0; i < device_num; i++) {
6874 #ifdef BP_SELF_TEST
6875                 kfree(bpctl_dev_arr[i].bp_tx_data);
6876 #endif
6877                 iounmap((void *)(bpctl_dev_arr[i].mem_map));
6878         }
6879
6880         /* free all devices space */
6881         kfree(bpctl_dev_arr);
6882
6883 /*
6884 * Unregister the device
6885 */
6886         unregister_chrdev(major_num, DEVICE_NAME);
6887 }
6888
6889 module_init(bypass_init_module);
6890 module_exit(bypass_cleanup_module);
6891
6892 int is_bypass_sd(int ifindex)
6893 {
6894         return is_bypass(get_dev_idx_p(ifindex));
6895 }
6896 EXPORT_SYMBOL(is_bypass_sd);
6897
6898 int set_bypass_sd(int ifindex, int bypass_mode)
6899 {
6900
6901         return set_bypass_fn(get_dev_idx_p(ifindex), bypass_mode);
6902 }
6903 EXPORT_SYMBOL(set_bypass_sd);
6904
6905 int get_bypass_sd(int ifindex)
6906 {
6907
6908         return get_bypass_fn(get_dev_idx_p(ifindex));
6909 }
6910 EXPORT_SYMBOL(get_bypass_sd);
6911
6912 int get_bypass_change_sd(int ifindex)
6913 {
6914
6915         return get_bypass_change_fn(get_dev_idx_p(ifindex));
6916 }
6917 EXPORT_SYMBOL(get_bypass_change_sd);
6918
6919 int set_dis_bypass_sd(int ifindex, int dis_param)
6920 {
6921         return set_dis_bypass_fn(get_dev_idx_p(ifindex), dis_param);
6922 }
6923 EXPORT_SYMBOL(set_dis_bypass_sd);
6924
6925 int get_dis_bypass_sd(int ifindex)
6926 {
6927
6928         return get_dis_bypass_fn(get_dev_idx_p(ifindex));
6929 }
6930 EXPORT_SYMBOL(get_dis_bypass_sd);
6931
6932 int set_bypass_pwoff_sd(int ifindex, int bypass_mode)
6933 {
6934         return set_bypass_pwoff_fn(get_dev_idx_p(ifindex), bypass_mode);
6935
6936 }
6937 EXPORT_SYMBOL(set_bypass_pwoff_sd);
6938
6939 int get_bypass_pwoff_sd(int ifindex)
6940 {
6941         return get_bypass_pwoff_fn(get_dev_idx_p(ifindex));
6942
6943 }
6944 EXPORT_SYMBOL(get_bypass_pwoff_sd);
6945
6946 int set_bypass_pwup_sd(int ifindex, int bypass_mode)
6947 {
6948         return set_bypass_pwup_fn(get_dev_idx_p(ifindex), bypass_mode);
6949
6950 }
6951 EXPORT_SYMBOL(set_bypass_pwup_sd);
6952
6953 int get_bypass_pwup_sd(int ifindex)
6954 {
6955         return get_bypass_pwup_fn(get_dev_idx_p(ifindex));
6956
6957 }
6958 EXPORT_SYMBOL(get_bypass_pwup_sd);
6959
6960 int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set)
6961 {
6962         if ((is_bypass(get_dev_idx_p(if_index))) <= 0)
6963                 return BP_NOT_CAP;
6964         *ms_timeout_set = set_bypass_wd_fn(get_dev_idx_p(if_index), ms_timeout);
6965         return 0;
6966 }
6967 EXPORT_SYMBOL(set_bypass_wd_sd);
6968
6969 int get_bypass_wd_sd(int ifindex, int *timeout)
6970 {
6971         return get_bypass_wd_fn(get_dev_idx_p(ifindex), timeout);
6972
6973 }
6974 EXPORT_SYMBOL(get_bypass_wd_sd);
6975
6976 int get_wd_expire_time_sd(int ifindex, int *time_left)
6977 {
6978         return get_wd_expire_time_fn(get_dev_idx_p(ifindex), time_left);
6979 }
6980 EXPORT_SYMBOL(get_wd_expire_time_sd);
6981
6982 int reset_bypass_wd_timer_sd(int ifindex)
6983 {
6984         return reset_bypass_wd_timer_fn(get_dev_idx_p(ifindex));
6985
6986 }
6987 EXPORT_SYMBOL(reset_bypass_wd_timer_sd);
6988
6989 int get_wd_set_caps_sd(int ifindex)
6990 {
6991         return get_wd_set_caps_fn(get_dev_idx_p(ifindex));
6992
6993 }
6994 EXPORT_SYMBOL(get_wd_set_caps_sd);
6995
6996 int set_std_nic_sd(int ifindex, int nic_mode)
6997 {
6998         return set_std_nic_fn(get_dev_idx_p(ifindex), nic_mode);
6999
7000 }
7001 EXPORT_SYMBOL(set_std_nic_sd);
7002
7003 int get_std_nic_sd(int ifindex)
7004 {
7005         return get_std_nic_fn(get_dev_idx_p(ifindex));
7006
7007 }
7008 EXPORT_SYMBOL(get_std_nic_sd);
7009
7010 int set_tap_sd(int ifindex, int tap_mode)
7011 {
7012         return set_tap_fn(get_dev_idx_p(ifindex), tap_mode);
7013
7014 }
7015 EXPORT_SYMBOL(set_tap_sd);
7016
7017 int get_tap_sd(int ifindex)
7018 {
7019         return get_tap_fn(get_dev_idx_p(ifindex));
7020
7021 }
7022 EXPORT_SYMBOL(get_tap_sd);
7023
7024 int set_tap_pwup_sd(int ifindex, int tap_mode)
7025 {
7026         return set_tap_pwup_fn(get_dev_idx_p(ifindex), tap_mode);
7027
7028 }
7029 EXPORT_SYMBOL(set_tap_pwup_sd);
7030
7031 int get_tap_pwup_sd(int ifindex)
7032 {
7033         return get_tap_pwup_fn(get_dev_idx_p(ifindex));
7034
7035 }
7036 EXPORT_SYMBOL(get_tap_pwup_sd);
7037
7038 int get_tap_change_sd(int ifindex)
7039 {
7040         return get_tap_change_fn(get_dev_idx_p(ifindex));
7041
7042 }
7043 EXPORT_SYMBOL(get_tap_change_sd);
7044
7045 int set_dis_tap_sd(int ifindex, int dis_param)
7046 {
7047         return set_dis_tap_fn(get_dev_idx_p(ifindex), dis_param);
7048
7049 }
7050 EXPORT_SYMBOL(set_dis_tap_sd);
7051
7052 int get_dis_tap_sd(int ifindex)
7053 {
7054         return get_dis_tap_fn(get_dev_idx_p(ifindex));
7055
7056 }
7057 EXPORT_SYMBOL(get_dis_tap_sd);
7058
7059 int set_bp_disc_sd(int ifindex, int disc_mode)
7060 {
7061         return set_disc_fn(get_dev_idx_p(ifindex), disc_mode);
7062
7063 }
7064 EXPORT_SYMBOL(set_bp_disc_sd);
7065
7066 int get_bp_disc_sd(int ifindex)
7067 {
7068         return get_disc_fn(get_dev_idx_p(ifindex));
7069
7070 }
7071 EXPORT_SYMBOL(get_bp_disc_sd);
7072
7073 int set_bp_disc_pwup_sd(int ifindex, int disc_mode)
7074 {
7075         return set_disc_pwup_fn(get_dev_idx_p(ifindex), disc_mode);
7076
7077 }
7078 EXPORT_SYMBOL(set_bp_disc_pwup_sd);
7079
7080 int get_bp_disc_pwup_sd(int ifindex)
7081 {
7082         return get_disc_pwup_fn(get_dev_idx_p(ifindex));
7083
7084 }
7085 EXPORT_SYMBOL(get_bp_disc_pwup_sd);
7086
7087 int get_bp_disc_change_sd(int ifindex)
7088 {
7089         return get_disc_change_fn(get_dev_idx_p(ifindex));
7090
7091 }
7092 EXPORT_SYMBOL(get_bp_disc_change_sd);
7093
7094 int set_bp_dis_disc_sd(int ifindex, int dis_param)
7095 {
7096         return set_dis_disc_fn(get_dev_idx_p(ifindex), dis_param);
7097
7098 }
7099 EXPORT_SYMBOL(set_bp_dis_disc_sd);
7100
7101 int get_bp_dis_disc_sd(int ifindex)
7102 {
7103         return get_dis_disc_fn(get_dev_idx_p(ifindex));
7104
7105 }
7106 EXPORT_SYMBOL(get_bp_dis_disc_sd);
7107
7108 int get_wd_exp_mode_sd(int ifindex)
7109 {
7110         return get_wd_exp_mode_fn(get_dev_idx_p(ifindex));
7111 }
7112 EXPORT_SYMBOL(get_wd_exp_mode_sd);
7113
7114 int set_wd_exp_mode_sd(int ifindex, int param)
7115 {
7116         return set_wd_exp_mode_fn(get_dev_idx_p(ifindex), param);
7117
7118 }
7119 EXPORT_SYMBOL(set_wd_exp_mode_sd);
7120
7121 int reset_cont_sd(int ifindex)
7122 {
7123         return reset_cont_fn(get_dev_idx_p(ifindex));
7124
7125 }
7126
7127 int set_tx_sd(int ifindex, int tx_state)
7128 {
7129         return set_tx_fn(get_dev_idx_p(ifindex), tx_state);
7130
7131 }
7132 EXPORT_SYMBOL(set_tx_sd);
7133
7134 int set_tpl_sd(int ifindex, int tpl_state)
7135 {
7136         return set_tpl_fn(get_dev_idx_p(ifindex), tpl_state);
7137
7138 }
7139 EXPORT_SYMBOL(set_tpl_sd);
7140
7141 int set_bp_hw_reset_sd(int ifindex, int status)
7142 {
7143         return set_bp_hw_reset_fn(get_dev_idx_p(ifindex), status);
7144
7145 }
7146 EXPORT_SYMBOL(set_bp_hw_reset_sd);
7147
7148 int set_wd_autoreset_sd(int ifindex, int param)
7149 {
7150         return set_wd_autoreset_fn(get_dev_idx_p(ifindex), param);
7151
7152 }
7153 EXPORT_SYMBOL(set_wd_autoreset_sd);
7154
7155 int get_wd_autoreset_sd(int ifindex)
7156 {
7157         return get_wd_autoreset_fn(get_dev_idx_p(ifindex));
7158
7159 }
7160 EXPORT_SYMBOL(get_wd_autoreset_sd);
7161
7162 int get_bypass_caps_sd(int ifindex)
7163 {
7164         return get_bypass_caps_fn(get_dev_idx_p(ifindex));
7165 }
7166 EXPORT_SYMBOL(get_bypass_caps_sd);
7167
7168 int get_bypass_slave_sd(int ifindex)
7169 {
7170         struct bpctl_dev *pbpctl_dev_out;
7171         int ret = get_bypass_slave_fn(get_dev_idx_p(ifindex), &pbpctl_dev_out);
7172         if (ret == 1)
7173                 return pbpctl_dev_out->ifindex;
7174         return -1;
7175
7176 }
7177 EXPORT_SYMBOL(get_bypass_slave_sd);
7178
7179 int get_tx_sd(int ifindex)
7180 {
7181         return get_tx_fn(get_dev_idx_p(ifindex));
7182
7183 }
7184 EXPORT_SYMBOL(get_tx_sd);
7185
7186 int get_tpl_sd(int ifindex)
7187 {
7188         return get_tpl_fn(get_dev_idx_p(ifindex));
7189
7190 }
7191 EXPORT_SYMBOL(get_tpl_sd);
7192
7193 int get_bp_hw_reset_sd(int ifindex)
7194 {
7195         return get_bp_hw_reset_fn(get_dev_idx_p(ifindex));
7196
7197 }
7198 EXPORT_SYMBOL(get_bp_hw_reset_sd);
7199
7200 int get_bypass_info_sd(int ifindex, struct bp_info *bp_info)
7201 {
7202         return get_bypass_info_fn(get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver);
7203 }
7204 EXPORT_SYMBOL(get_bypass_info_sd);
7205
7206 int bp_if_scan_sd(void)
7207 {
7208         if_scan_init();
7209         return 0;
7210 }
7211 EXPORT_SYMBOL(bp_if_scan_sd);
7212
7213 #define BP_PROC_DIR "bypass"
7214
7215 static struct proc_dir_entry *bp_procfs_dir;
7216
7217 int bp_proc_create(void)
7218 {
7219         bp_procfs_dir = proc_mkdir(BP_PROC_DIR, init_net.proc_net);
7220         if (bp_procfs_dir == (struct proc_dir_entry *)0) {
7221                 printk(KERN_DEBUG
7222                        "Could not create procfs nicinfo directory %s\n",
7223                        BP_PROC_DIR);
7224                 return -1;
7225         }
7226         return 0;
7227 }
7228
7229 static int procfs_add(char *proc_name, const struct file_operations *fops,
7230                       struct bpctl_dev *dev)
7231 {
7232         struct bypass_pfs_sd *pfs = &dev->bypass_pfs_set;
7233         if (!proc_create_data(proc_name, 0644, pfs->bypass_entry, fops, dev))
7234                 return -1;
7235         return 0;
7236 }
7237
7238 #define RO_FOPS(name)   \
7239 static int name##_open(struct inode *inode, struct file *file)  \
7240 {                                                               \
7241         return single_open(file, show_##name, PDE_DATA(inode));\
7242 }                                                               \
7243 static const struct file_operations name##_ops = {              \
7244         .open = name##_open,                                    \
7245         .read = seq_read,                                       \
7246         .llseek = seq_lseek,                                    \
7247         .release = single_release,                              \
7248 };
7249
7250 #define RW_FOPS(name)   \
7251 static int name##_open(struct inode *inode, struct file *file)  \
7252 {                                                               \
7253         return single_open(file, show_##name, PDE_DATA(inode));\
7254 }                                                               \
7255 static const struct file_operations name##_ops = {              \
7256         .open = name##_open,                                    \
7257         .read = seq_read,                                       \
7258         .write = name##_write,                                  \
7259         .llseek = seq_lseek,                                    \
7260         .release = single_release,                              \
7261 };
7262
7263 static int show_bypass_info(struct seq_file *m, void *v)
7264 {
7265         struct bpctl_dev *dev = m->private;
7266
7267         seq_printf(m, "Name\t\t\t%s\n", dev->name);
7268         seq_printf(m, "Firmware version\t0x%x\n", dev->bp_fw_ver);
7269         return 0;
7270 }
7271 RO_FOPS(bypass_info)
7272
7273 static int show_bypass_slave(struct seq_file *m, void *v)
7274 {
7275         struct bpctl_dev *dev = m->private;
7276         struct bpctl_dev *slave = get_status_port_fn(dev);
7277         if (!slave)
7278                 slave = dev;
7279         if (!slave)
7280                 seq_puts(m, "fail\n");
7281         else if (slave->ndev)
7282                 seq_printf(m, "%s\n", slave->ndev->name);
7283         return 0;
7284 }
7285 RO_FOPS(bypass_slave)
7286
7287 static int show_bypass_caps(struct seq_file *m, void *v)
7288 {
7289         struct bpctl_dev *dev = m->private;
7290         int ret = get_bypass_caps_fn(dev);
7291         if (ret == BP_NOT_CAP)
7292                 seq_puts(m, "-1\n");
7293         else
7294                 seq_printf(m, "0x%x\n", ret);
7295         return 0;
7296 }
7297 RO_FOPS(bypass_caps)
7298
7299 static int show_wd_set_caps(struct seq_file *m, void *v)
7300 {
7301         struct bpctl_dev *dev = m->private;
7302         int ret = get_wd_set_caps_fn(dev);
7303         if (ret == BP_NOT_CAP)
7304                 seq_puts(m, "-1\n");
7305         else
7306                 seq_printf(m, "0x%x\n", ret);
7307         return 0;
7308 }
7309 RO_FOPS(wd_set_caps)
7310
7311 static int user_on_off(const void __user *buffer, size_t count)
7312 {
7313
7314         char kbuf[256];
7315         int length = 0;
7316
7317         if (count > (sizeof(kbuf) - 1))
7318                 return -1;
7319
7320         if (copy_from_user(&kbuf, buffer, count))
7321                 return -1;
7322
7323         kbuf[count] = '\0';
7324         length = strlen(kbuf);
7325         if (kbuf[length - 1] == '\n')
7326                 kbuf[--length] = '\0';
7327
7328         if (strcmp(kbuf, "on") == 0)
7329                 return 1;
7330         if (strcmp(kbuf, "off") == 0)
7331                 return 0;
7332         return 0;
7333 }
7334
7335 static ssize_t bypass_write(struct file *file, const char __user *buffer,
7336                                   size_t count, loff_t *pos)
7337 {
7338         int bypass_param = user_on_off(buffer, count);
7339         if (bypass_param < 0)
7340                 return -1;
7341
7342         set_bypass_fn(PDE_DATA(file_inode(file)), bypass_param);
7343         return count;
7344 }
7345 static int show_bypass(struct seq_file *m, void *v)
7346 {
7347         struct bpctl_dev *dev = m->private;
7348         int ret = get_bypass_fn(dev);
7349         if (ret == BP_NOT_CAP)
7350                 seq_puts(m, "fail\n");
7351         else if (ret == 1)
7352                 seq_puts(m, "on\n");
7353         else if (ret == 0)
7354                 seq_puts(m, "off\n");
7355         return 0;
7356 }
7357 RW_FOPS(bypass)
7358
7359 static ssize_t tap_write(struct file *file, const char __user *buffer,
7360                                   size_t count, loff_t *pos)
7361 {
7362         int tap_param = user_on_off(buffer, count);
7363         if (tap_param < 0)
7364                 return -1;
7365
7366         set_tap_fn(PDE_DATA(file_inode(file)), tap_param);
7367         return count;
7368 }
7369 static int show_tap(struct seq_file *m, void *v)
7370 {
7371         struct bpctl_dev *dev = m->private;
7372         int ret = get_tap_fn(dev);
7373         if (ret == BP_NOT_CAP)
7374                 seq_puts(m, "fail\n");
7375         else if (ret == 1)
7376                 seq_puts(m, "on\n");
7377         else if (ret == 0)
7378                 seq_puts(m, "off\n");
7379         return 0;
7380 }
7381 RW_FOPS(tap)
7382
7383 static ssize_t disc_write(struct file *file, const char __user *buffer,
7384                                   size_t count, loff_t *pos)
7385 {
7386         int tap_param = user_on_off(buffer, count);
7387         if (tap_param < 0)
7388                 return -1;
7389
7390         set_disc_fn(PDE_DATA(file_inode(file)), tap_param);
7391         return count;
7392 }
7393 static int show_disc(struct seq_file *m, void *v)
7394 {
7395         struct bpctl_dev *dev = m->private;
7396         int ret = get_disc_fn(dev);
7397         if (ret == BP_NOT_CAP)
7398                 seq_puts(m, "fail\n");
7399         else if (ret == 1)
7400                 seq_puts(m, "on\n");
7401         else if (ret == 0)
7402                 seq_puts(m, "off\n");
7403         return 0;
7404 }
7405 RW_FOPS(disc)
7406
7407 static int show_bypass_change(struct seq_file *m, void *v)
7408 {
7409         struct bpctl_dev *dev = m->private;
7410         int ret = get_bypass_change_fn(dev);
7411         if (ret == 1)
7412                 seq_puts(m, "on\n");
7413         else if (ret == 0)
7414                 seq_puts(m, "off\n");
7415         else
7416                 seq_puts(m, "fail\n");
7417         return 0;
7418 }
7419 RO_FOPS(bypass_change)
7420
7421 static int show_tap_change(struct seq_file *m, void *v)
7422 {
7423         struct bpctl_dev *dev = m->private;
7424         int ret = get_tap_change_fn(dev);
7425         if (ret == 1)
7426                 seq_puts(m, "on\n");
7427         else if (ret == 0)
7428                 seq_puts(m, "off\n");
7429         else
7430                 seq_puts(m, "fail\n");
7431         return 0;
7432 }
7433 RO_FOPS(tap_change)
7434
7435 static int show_disc_change(struct seq_file *m, void *v)
7436 {
7437         struct bpctl_dev *dev = m->private;
7438         int ret = get_disc_change_fn(dev);
7439         if (ret == 1)
7440                 seq_puts(m, "on\n");
7441         else if (ret == 0)
7442                 seq_puts(m, "off\n");
7443         else
7444                 seq_puts(m, "fail\n");
7445         return 0;
7446 }
7447 RO_FOPS(disc_change)
7448
7449 static ssize_t bypass_wd_write(struct file *file, const char __user *buffer,
7450                                   size_t count, loff_t *pos)
7451 {
7452         struct bpctl_dev *dev = PDE_DATA(file_inode(file));
7453         int timeout;
7454         int ret = kstrtoint_from_user(buffer, count, 10, &timeout);
7455         if (ret)
7456                 return ret;
7457         set_bypass_wd_fn(dev, timeout);
7458         return count;
7459 }
7460 static int show_bypass_wd(struct seq_file *m, void *v)
7461 {
7462         struct bpctl_dev *dev = m->private;
7463         int ret = 0, timeout = 0;
7464
7465         ret = get_bypass_wd_fn(dev, &timeout);
7466         if (ret == BP_NOT_CAP)
7467                 seq_puts(m,  "fail\n");
7468         else if (timeout == -1)
7469                 seq_puts(m,  "unknown\n");
7470         else if (timeout == 0)
7471                 seq_puts(m,  "disable\n");
7472         else
7473                 seq_printf(m, "%d\n", timeout);
7474         return 0;
7475 }
7476 RW_FOPS(bypass_wd)
7477
7478 static int show_wd_expire_time(struct seq_file *m, void *v)
7479 {
7480         struct bpctl_dev *dev = m->private;
7481         int ret = 0, timeout = 0;
7482         ret = get_wd_expire_time_fn(dev, &timeout);
7483         if (ret == BP_NOT_CAP)
7484                 seq_puts(m, "fail\n");
7485         else if (timeout == -1)
7486                 seq_puts(m, "expire\n");
7487         else if (timeout == 0)
7488                 seq_puts(m, "disable\n");
7489         else
7490                 seq_printf(m, "%d\n", timeout);
7491         return 0;
7492 }
7493 RO_FOPS(wd_expire_time)
7494
7495 static ssize_t tpl_write(struct file *file, const char __user *buffer,
7496                                   size_t count, loff_t *pos)
7497 {
7498         struct bpctl_dev *dev = PDE_DATA(file_inode(file));
7499         int tpl_param = user_on_off(buffer, count);
7500         if (tpl_param < 0)
7501                 return -1;
7502
7503         set_tpl_fn(dev, tpl_param);
7504         return count;
7505 }
7506 static int show_tpl(struct seq_file *m, void *v)
7507 {
7508         struct bpctl_dev *dev = m->private;
7509         int ret = get_tpl_fn(dev);
7510         if (ret == BP_NOT_CAP)
7511                 seq_puts(m, "fail\n");
7512         else if (ret == 1)
7513                 seq_puts(m, "on\n");
7514         else if (ret == 0)
7515                 seq_puts(m, "off\n");
7516         return 0;
7517 }
7518 RW_FOPS(tpl)
7519
7520 #ifdef PMC_FIX_FLAG
7521 static ssize_t wait_at_pwup_write(struct file *file, const char __user *buffer,
7522                                   size_t count, loff_t *pos)
7523 {
7524         struct bpctl_dev *dev = PDE_DATA(file_inode(file));
7525         int tpl_param = user_on_off(buffer, count);
7526         if (tpl_param < 0)
7527                 return -1;
7528
7529         set_bp_wait_at_pwup_fn(dev, tpl_param);
7530         return count;
7531 }
7532 static int show_wait_at_pwup(struct seq_file *m, void *v)
7533 {
7534         struct bpctl_dev *dev = m->private;
7535         int ret = get_bp_wait_at_pwup_fn(dev);
7536         if (ret == BP_NOT_CAP)
7537                 seq_puts(m, "fail\n");
7538         else if (ret == 1)
7539                 seq_puts(m, "on\n");
7540         else if (ret == 0)
7541                 seq_puts(m, "off\n");
7542         return 0;
7543 }
7544 RW_FOPS(wait_at_pwup)
7545
7546 static ssize_t hw_reset_write(struct file *file, const char __user *buffer,
7547                                   size_t count, loff_t *pos)
7548 {
7549         struct bpctl_dev *dev = PDE_DATA(file_inode(file));
7550         int tpl_param = user_on_off(buffer, count);
7551         if (tpl_param < 0)
7552                 return -1;
7553
7554         set_bp_hw_reset_fn(dev, tpl_param);
7555         return count;
7556 }
7557 static int show_hw_reset(struct seq_file *m, void *v)
7558 {
7559         struct bpctl_dev *dev = m->private;
7560         int ret = get_bp_hw_reset_fn(dev);
7561         if (ret == BP_NOT_CAP)
7562                 seq_puts(m, "fail\n");
7563         else if (ret == 1)
7564                 seq_puts(m, "on\n");
7565         else if (ret == 0)
7566                 seq_puts(m, "off\n");
7567         return 0;
7568 }
7569 RW_FOPS(hw_reset)
7570
7571 #endif                          /*PMC_WAIT_FLAG */
7572
7573 static int show_reset_bypass_wd(struct seq_file *m, void *v)
7574 {
7575         struct bpctl_dev *dev = m->private;
7576         int ret = reset_bypass_wd_timer_fn(dev);
7577         if (ret == BP_NOT_CAP)
7578                 seq_puts(m, "fail\n");
7579         else if (ret == 0)
7580                 seq_puts(m, "disable\n");
7581         else if (ret == 1)
7582                 seq_puts(m, "success\n");
7583         return 0;
7584 }
7585 RO_FOPS(reset_bypass_wd)
7586
7587 static ssize_t dis_bypass_write(struct file *file, const char __user *buffer,
7588                                   size_t count, loff_t *pos)
7589 {
7590         int bypass_param = user_on_off(buffer, count);
7591         if (bypass_param < 0)
7592                 return -EINVAL;
7593
7594         set_dis_bypass_fn(PDE_DATA(file_inode(file)), bypass_param);
7595         return count;
7596 }
7597 static int show_dis_bypass(struct seq_file *m, void *v)
7598 {
7599         struct bpctl_dev *dev = m->private;
7600         int ret = get_dis_bypass_fn(dev);
7601         if (ret == BP_NOT_CAP)
7602                 seq_puts(m, "fail\n");
7603         else if (ret == 0)
7604                 seq_puts(m, "off\n");
7605         else
7606                 seq_puts(m, "on\n");
7607         return 0;
7608 }
7609 RW_FOPS(dis_bypass)
7610
7611 static ssize_t dis_tap_write(struct file *file, const char __user *buffer,
7612                                   size_t count, loff_t *pos)
7613 {
7614         int tap_param = user_on_off(buffer, count);
7615         if (tap_param < 0)
7616                 return -EINVAL;
7617
7618         set_dis_tap_fn(PDE_DATA(file_inode(file)), tap_param);
7619         return count;
7620 }
7621 static int show_dis_tap(struct seq_file *m, void *v)
7622 {
7623         struct bpctl_dev *dev = m->private;
7624         int ret = get_dis_tap_fn(dev);
7625         if (ret == BP_NOT_CAP)
7626                 seq_puts(m, "fail\n");
7627         else if (ret == 0)
7628                 seq_puts(m, "off\n");
7629         else
7630                 seq_puts(m, "on\n");
7631         return 0;
7632 }
7633 RW_FOPS(dis_tap)
7634
7635 static ssize_t dis_disc_write(struct file *file, const char __user *buffer,
7636                                   size_t count, loff_t *pos)
7637 {
7638         int tap_param = user_on_off(buffer, count);
7639         if (tap_param < 0)
7640                 return -EINVAL;
7641
7642         set_dis_disc_fn(PDE_DATA(file_inode(file)), tap_param);
7643         return count;
7644 }
7645 static int show_dis_disc(struct seq_file *m, void *v)
7646 {
7647         struct bpctl_dev *dev = m->private;
7648         int ret = get_dis_disc_fn(dev);
7649         if (ret == BP_NOT_CAP)
7650                 seq_puts(m, "fail\n");
7651         else if (ret == 0)
7652                 seq_puts(m, "off\n");
7653         else
7654                 seq_puts(m, "on\n");
7655         return 0;
7656 }
7657 RW_FOPS(dis_disc)
7658
7659 static ssize_t bypass_pwup_write(struct file *file, const char __user *buffer,
7660                                   size_t count, loff_t *pos)
7661 {
7662         int bypass_param = user_on_off(buffer, count);
7663         if (bypass_param < 0)
7664                 return -EINVAL;
7665
7666         set_bypass_pwup_fn(PDE_DATA(file_inode(file)), bypass_param);
7667         return count;
7668 }
7669 static int show_bypass_pwup(struct seq_file *m, void *v)
7670 {
7671         struct bpctl_dev *dev = m->private;
7672         int ret = get_bypass_pwup_fn(dev);
7673         if (ret == BP_NOT_CAP)
7674                 seq_puts(m, "fail\n");
7675         else if (ret == 0)
7676                 seq_puts(m, "off\n");
7677         else
7678                 seq_puts(m, "on\n");
7679         return 0;
7680 }
7681 RW_FOPS(bypass_pwup)
7682
7683 static ssize_t bypass_pwoff_write(struct file *file, const char __user *buffer,
7684                                   size_t count, loff_t *pos)
7685 {
7686         int bypass_param = user_on_off(buffer, count);
7687         if (bypass_param < 0)
7688                 return -EINVAL;
7689
7690         set_bypass_pwoff_fn(PDE_DATA(file_inode(file)), bypass_param);
7691         return count;
7692 }
7693 static int show_bypass_pwoff(struct seq_file *m, void *v)
7694 {
7695         struct bpctl_dev *dev = m->private;
7696         int ret = get_bypass_pwoff_fn(dev);
7697         if (ret == BP_NOT_CAP)
7698                 seq_puts(m, "fail\n");
7699         else if (ret == 0)
7700                 seq_puts(m, "off\n");
7701         else
7702                 seq_puts(m, "on\n");
7703         return 0;
7704 }
7705 RW_FOPS(bypass_pwoff)
7706
7707 static ssize_t tap_pwup_write(struct file *file, const char __user *buffer,
7708                                   size_t count, loff_t *pos)
7709 {
7710         int tap_param = user_on_off(buffer, count);
7711         if (tap_param < 0)
7712                 return -EINVAL;
7713
7714         set_tap_pwup_fn(PDE_DATA(file_inode(file)), tap_param);
7715         return count;
7716 }
7717 static int show_tap_pwup(struct seq_file *m, void *v)
7718 {
7719         struct bpctl_dev *dev = m->private;
7720         int ret = get_tap_pwup_fn(dev);
7721         if (ret == BP_NOT_CAP)
7722                 seq_puts(m, "fail\n");
7723         else if (ret == 0)
7724                 seq_puts(m, "off\n");
7725         else
7726                 seq_puts(m, "on\n");
7727         return 0;
7728 }
7729 RW_FOPS(tap_pwup)
7730
7731 static ssize_t disc_pwup_write(struct file *file, const char __user *buffer,
7732                                   size_t count, loff_t *pos)
7733 {
7734         int tap_param = user_on_off(buffer, count);
7735         if (tap_param < 0)
7736                 return -EINVAL;
7737
7738         set_disc_pwup_fn(PDE_DATA(file_inode(file)), tap_param);
7739         return count;
7740 }
7741 static int show_disc_pwup(struct seq_file *m, void *v)
7742 {
7743         struct bpctl_dev *dev = m->private;
7744         int ret = get_disc_pwup_fn(dev);
7745         if (ret == BP_NOT_CAP)
7746                 seq_puts(m, "fail\n");
7747         else if (ret == 0)
7748                 seq_puts(m, "off\n");
7749         else
7750                 seq_puts(m, "on\n");
7751         return 0;
7752 }
7753 RW_FOPS(disc_pwup)
7754
7755 static ssize_t std_nic_write(struct file *file, const char __user *buffer,
7756                                   size_t count, loff_t *pos)
7757 {
7758         int bypass_param = user_on_off(buffer, count);
7759         if (bypass_param < 0)
7760                 return -EINVAL;
7761
7762         set_std_nic_fn(PDE_DATA(file_inode(file)), bypass_param);
7763         return count;
7764 }
7765 static int show_std_nic(struct seq_file *m, void *v)
7766 {
7767         struct bpctl_dev *dev = m->private;
7768         int ret = get_std_nic_fn(dev);
7769         if (ret == BP_NOT_CAP)
7770                 seq_puts(m, "fail\n");
7771         else if (ret == 0)
7772                 seq_puts(m, "off\n");
7773         else
7774                 seq_puts(m, "on\n");
7775         return 0;
7776 }
7777 RW_FOPS(std_nic)
7778
7779 static ssize_t wd_exp_mode_write(struct file *file, const char __user *buffer,
7780                                   size_t count, loff_t *pos)
7781 {
7782         char kbuf[256];
7783         int bypass_param = 0, length = 0;
7784
7785         if (count > (sizeof(kbuf) - 1))
7786                 return -1;
7787
7788         if (copy_from_user(&kbuf, buffer, count))
7789                 return -1;
7790
7791         kbuf[count] = '\0';
7792         length = strlen(kbuf);
7793         if (kbuf[length - 1] == '\n')
7794                 kbuf[--length] = '\0';
7795
7796         if (strcmp(kbuf, "tap") == 0)
7797                 bypass_param = 1;
7798         else if (strcmp(kbuf, "bypass") == 0)
7799                 bypass_param = 0;
7800         else if (strcmp(kbuf, "disc") == 0)
7801                 bypass_param = 2;
7802
7803         set_wd_exp_mode_fn(PDE_DATA(file_inode(file)), bypass_param);
7804
7805         return count;
7806 }
7807 static int show_wd_exp_mode(struct seq_file *m, void *v)
7808 {
7809         struct bpctl_dev *dev = m->private;
7810         int ret = get_wd_exp_mode_fn(dev);
7811         if (ret == 1)
7812                 seq_puts(m, "tap\n");
7813         else if (ret == 0)
7814                 seq_puts(m, "bypass\n");
7815         else if (ret == 2)
7816                 seq_puts(m, "disc\n");
7817         else
7818                 seq_puts(m, "fail\n");
7819         return 0;
7820 }
7821 RW_FOPS(wd_exp_mode)
7822
7823 static ssize_t wd_autoreset_write(struct file *file, const char __user *buffer,
7824                                   size_t count, loff_t *pos)
7825 {
7826         int timeout;
7827         int ret = kstrtoint_from_user(buffer, count, 10, &timeout);
7828         if (ret)
7829                 return ret;
7830         set_wd_autoreset_fn(PDE_DATA(file_inode(file)), timeout);
7831         return count;
7832 }
7833 static int show_wd_autoreset(struct seq_file *m, void *v)
7834 {
7835         struct bpctl_dev *dev = m->private;
7836         int ret = get_wd_autoreset_fn(dev);
7837         if (ret >= 0)
7838                 seq_printf(m, "%d\n", ret);
7839         else
7840                 seq_puts(m, "fail\n");
7841         return 0;
7842 }
7843 RW_FOPS(wd_autoreset)
7844
7845 int bypass_proc_create_dev_sd(struct bpctl_dev *pbp_device_block)
7846 {
7847         struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set);
7848         static struct proc_dir_entry *procfs_dir;
7849         int ret = 0;
7850
7851         if (!pbp_device_block->ndev)
7852                 return -1;
7853         sprintf(current_pfs->dir_name, "bypass_%s",
7854                 pbp_device_block->ndev->name);
7855
7856         if (!bp_procfs_dir)
7857                 return -1;
7858
7859         /* create device proc dir */
7860         procfs_dir = proc_mkdir(current_pfs->dir_name, bp_procfs_dir);
7861         if (!procfs_dir) {
7862                 printk(KERN_DEBUG "Could not create procfs directory %s\n",
7863                        current_pfs->dir_name);
7864                 return -1;
7865         }
7866         current_pfs->bypass_entry = procfs_dir;
7867
7868 #define ENTRY(x) (ret |= procfs_add(#x, &x##_ops, pbp_device_block))
7869
7870         ENTRY(bypass_info);
7871         if (pbp_device_block->bp_caps & SW_CTL_CAP) {
7872                 /* Create set param proc's */
7873                 ENTRY(bypass_slave);
7874                 ENTRY(bypass_caps);
7875                 ENTRY(wd_set_caps);
7876                 ENTRY(bypass_wd);
7877                 ENTRY(wd_expire_time);
7878                 ENTRY(reset_bypass_wd);
7879                 ENTRY(std_nic);
7880                 if (pbp_device_block->bp_caps & BP_CAP) {
7881                         ENTRY(bypass);
7882                         ENTRY(dis_bypass);
7883                         ENTRY(bypass_pwup);
7884                         ENTRY(bypass_pwoff);
7885                         ENTRY(bypass_change);
7886                 }
7887                 if (pbp_device_block->bp_caps & TAP_CAP) {
7888                         ENTRY(tap);
7889                         ENTRY(dis_tap);
7890                         ENTRY(tap_pwup);
7891                         ENTRY(tap_change);
7892                 }
7893                 if (pbp_device_block->bp_caps & DISC_CAP) {
7894                         ENTRY(disc);
7895                         ENTRY(dis_disc);
7896                         ENTRY(disc_pwup);
7897                         ENTRY(disc_change);
7898                 }
7899
7900                 ENTRY(wd_exp_mode);
7901                 ENTRY(wd_autoreset);
7902                 ENTRY(tpl);
7903 #ifdef PMC_FIX_FLAG
7904                 ENTRY(wait_at_pwup);
7905                 ENTRY(hw_reset);
7906 #endif
7907         }
7908 #undef ENTRY
7909         if (ret < 0)
7910                 printk(KERN_DEBUG "Create proc entry failed\n");
7911
7912         return ret;
7913 }
7914
7915 int bypass_proc_remove_dev_sd(struct bpctl_dev *pbp_device_block)
7916 {
7917
7918         struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set;
7919         remove_proc_subtree(current_pfs->dir_name, bp_procfs_dir);
7920         current_pfs->bypass_entry = NULL;
7921         return 0;
7922 }