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