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