]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/staging/silicom/bpctl_mod.c
staging: silicom : remove assignment in if condition
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / silicom / bpctl_mod.c
CommitLineData
7040e556
D
1/******************************************************************************/
2/* */
de2e487f 3/* Bypass Control utility, Copyright (c) 2005-2011 Silicom */
7040e556
D
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. */
de2e487f 8/* Copyright(c) 2007 - 2009, 2013 Intel Corporation. All rights reserved. */
7040e556
D
9/* */
10/* */
11/******************************************************************************/
7040e556
D
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
86bc9ebb 23#include <linux/uaccess.h> /* for get_user and put_user */
7040e556
D
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
f84b0751 38static int major_num;
7040e556
D
39
40MODULE_AUTHOR("Anna Lukin, annal@silicom.co.il");
41MODULE_LICENSE("GPL");
42MODULE_DESCRIPTION(BP_MOD_DESCR);
43MODULE_VERSION(BP_MOD_VER);
44spinlock_t bpvm_lock;
45
a7ce87e1 46#define unlock_bpctl() \
7040e556
D
47 up(&bpctl_sema);
48
49/* Media Types */
ff2e54cd 50enum bp_media_type {
ae0b9530
CW
51 BP_COPPER = 0,
52 BP_FIBER,
53 BP_CX4,
54 BP_NONE,
ff2e54cd 55};
7040e556 56
7040e556
D
57struct bypass_pfs_sd {
58 char dir_name[32];
59 struct proc_dir_entry *bypass_entry;
7040e556
D
60};
61
efb39e4e 62struct bpctl_dev {
7040e556
D
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;
ff2e54cd 87 enum bp_media_type media_type;
7040e556
D
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;
01448bbb
DC
97 int (*hard_start_xmit_save) (struct sk_buff *skb,
98 struct net_device *dev);
7040e556
D
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;
7040e556
D
103 struct bypass_pfs_sd bypass_pfs_set;
104
efb39e4e 105};
7040e556 106
efb39e4e 107static struct bpctl_dev *bpctl_dev_arr;
7040e556
D
108
109static struct semaphore bpctl_sema;
f84b0751 110static int device_num;
7040e556
D
111
112static int get_dev_idx(int ifindex);
efb39e4e
CW
113static struct bpctl_dev *get_master_port_fn(struct bpctl_dev *pbpctl_dev);
114static int disc_status(struct bpctl_dev *pbpctl_dev);
115static int bypass_status(struct bpctl_dev *pbpctl_dev);
116static int wdt_timer(struct bpctl_dev *pbpctl_dev, int *time_left);
117static struct bpctl_dev *get_status_port_fn(struct bpctl_dev *pbpctl_dev);
7040e556
D
118static void if_scan_init(void);
119
4624b543
SP
120static int bypass_proc_create_dev_sd(struct bpctl_dev *pbp_device_block);
121static int bypass_proc_remove_dev_sd(struct bpctl_dev *pbp_device_block);
122static int bp_proc_create(void);
7040e556 123
4624b543
SP
124static int is_bypass_fn(struct bpctl_dev *pbpctl_dev);
125static int get_dev_idx_bsf(int bus, int slot, int func);
7040e556 126
de2e487f
AS
127static 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
de2e487f
AS
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
7040e556
D
152static int bp_device_event(struct notifier_block *unused,
153 unsigned long event, void *ptr)
154{
351638e7 155 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
efb39e4e 156 static struct bpctl_dev *pbpctl_dev, *pbpctl_dev_m;
7040e556 157 int dev_num = 0, ret = 0, ret_d = 0, time_left = 0;
de2e487f 158
687bcca0
DC
159 /* printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); */
160 /* return NOTIFY_DONE; */
7040e556
D
161 if (!dev)
162 return NOTIFY_DONE;
7040e556 163
de2e487f
AS
164 if (event == NETDEV_REGISTER) {
165 int idx_dev;
7040e556 166
de2e487f
AS
167 if (bp_get_dev_idx_bsf(dev, &idx_dev))
168 return NOTIFY_DONE;
7040e556 169
de2e487f
AS
170 if (idx_dev == -1)
171 return NOTIFY_DONE;
7040e556 172
de2e487f
AS
173 bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
174 bpctl_dev_arr[idx_dev].ndev = dev;
7040e556 175
de2e487f
AS
176 bypass_proc_remove_dev_sd(&bpctl_dev_arr[idx_dev]);
177 bypass_proc_create_dev_sd(&bpctl_dev_arr[idx_dev]);
7040e556 178 return NOTIFY_DONE;
7040e556
D
179 }
180 if (event == NETDEV_UNREGISTER) {
181 int idx_dev = 0;
7040e556
D
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;
7040e556
D
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 }
7040e556
D
216
217 switch (event) {
218
219 case NETDEV_CHANGE:{
220 if (netif_carrier_ok(dev))
221 return NOTIFY_DONE;
222
7040e556
D
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
261static struct notifier_block bp_notifier_block = {
262 .notifier_call = bp_device_event,
263};
264
4624b543 265static int is_bypass_fn(struct bpctl_dev *pbpctl_dev);
efb39e4e 266int wdt_time_left(struct bpctl_dev *pbpctl_dev);
7040e556 267
efb39e4e 268static void write_pulse(struct bpctl_dev *pbpctl_dev,
7040e556
D
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;
efb39e4e 275 struct bpctl_dev *pbpctl_dev_c = NULL;
7040e556
D
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) {
3f3c1fc9
CW
283 pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
284 if (!pbpctl_dev_c)
7040e556
D
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
687bcca0 354 /* To start management : MCLK 1, MDIO 1, output*/
7040e556
D
355 BP10G_WRITE_REG(pbpctl_dev, EODSDP,
356 (ctrl_ext | BP10G_MCLK_DATA_OUT
357 | BP10G_MDIO_DATA_OUT));
7040e556
D
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
7040e556
D
424 BP10G_WRITE_REG(pbpctl_dev, EODSDP,
425 ((ctrl_ext |
426 BP10G_MDIO_DATA_OUT) &
427 ~(BP10G_MCLK_DATA_OUT)));
7040e556
D
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
7040e556
D
493 BP10G_WRITE_REG(pbpctl_dev, EODSDP,
494 ((ctrl_ext |
495 BP10G_MCLK_DATA_OUT) &
496 ~BP10G_MDIO_DATA_OUT));
7040e556
D
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
7040e556
D
559 BP10G_WRITE_REG(pbpctl_dev, EODSDP,
560 (ctrl_ext &
561 ~(BP10G_MCLK_DATA_OUT |
562 BP10G_MDIO_DATA_OUT)));
7040e556
D
563 }
564
565 usec_delay(PULSE_TIME);
566 }
567
568 }
569}
570
efb39e4e 571static int read_pulse(struct bpctl_dev *pbpctl_dev, unsigned int ctrl_ext,
7040e556
D
572 unsigned char len)
573{
574 unsigned char ctrl_val = 0;
575 unsigned int i = len;
576 unsigned int ctrl = 0;
efb39e4e 577 struct bpctl_dev *pbpctl_dev_c = NULL;
7040e556
D
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) {
3f3c1fc9
CW
584 pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
585 if (!pbpctl_dev_c)
7040e556
D
586 return -1;
587 ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
588 }
589
7040e556
D
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
7040e556 640 BP10G_WRITE_REG(pbpctl_dev, EODSDP, ((ctrl_ext | BP10G_MDIO_DATA_OUT) & ~BP10G_MCLK_DATA_OUT)); /* ? */
687bcca0 641 /* printk("0x28=0x%x\n",BP10G_READ_REG(pbpctl_dev,EODSDP);); */
7040e556
D
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
7040e556
D
694 BP10G_WRITE_REG(pbpctl_dev, EODSDP,
695 (ctrl_ext | BP10G_MCLK_DATA_OUT |
696 BP10G_MDIO_DATA_OUT));
7040e556
D
697
698 }
7040e556 699
ea675ee5
CW
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))
7040e556 703 ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL);
ea675ee5 704 else if (pbpctl_dev->bp_540)
7040e556 705 ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP);
ea675ee5 706 else if (pbpctl_dev->bp_10gb)
7040e556 707 ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
7040e556
D
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);
7040e556
D
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
efb39e4e 746static void write_reg(struct bpctl_dev *pbpctl_dev, unsigned char value,
7040e556
D
747 unsigned char addr)
748{
749 uint32_t ctrl_ext = 0, ctrl = 0;
efb39e4e 750 struct bpctl_dev *pbpctl_dev_c = NULL;
7040e556
D
751 unsigned long flags;
752 if (pbpctl_dev->bp_10g9) {
3f3c1fc9
CW
753 pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
754 if (!pbpctl_dev_c)
7040e556
D
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)));
7040e556
D
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)));
7040e556 899
7040e556
D
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
efb39e4e 915static void write_data(struct bpctl_dev *pbpctl_dev, unsigned char value)
7040e556
D
916{
917 write_reg(pbpctl_dev, value, CMND_REG_ADDR);
918}
919
efb39e4e 920static int read_reg(struct bpctl_dev *pbpctl_dev, unsigned char addr)
7040e556
D
921{
922 uint32_t ctrl_ext = 0, ctrl = 0, ctrl_value = 0;
efb39e4e 923 struct bpctl_dev *pbpctl_dev_c = NULL;
7040e556
D
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) {
3f3c1fc9
CW
932 pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
933 if (!pbpctl_dev_c)
7040e556
D
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
687bcca0 1006 printk("2reg=%x\n", ctrl_ext);
7040e556
D
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
7040e556
D
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)));
7040e556
D
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
7040e556
D
1104 BP10G_WRITE_REG(pbpctl_dev, EODSDP,
1105 (ctrl_ext | BP10G_MCLK_DATA_OUT |
1106 BP10G_MDIO_DATA_OUT));
1107
7040e556
D
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
7040e556
D
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)));
7040e556
D
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
efb39e4e 1189static int wdt_pulse(struct bpctl_dev *pbpctl_dev)
7040e556
D
1190{
1191 uint32_t ctrl_ext = 0, ctrl = 0;
efb39e4e 1192 struct bpctl_dev *pbpctl_dev_c = NULL;
7040e556
D
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) {
3f3c1fc9
CW
1204 pbpctl_dev_c = get_status_port_fn(pbpctl_dev);
1205 if (!pbpctl_dev_c)
7040e556
D
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
7040e556
D
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)));
7040e556
D
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
7040e556
D
1331 BP10G_WRITE_REG(pbpctl_dev, EODSDP,
1332 ((ctrl_ext | BP10G_MCLK_DATA_OUT) &
1333 ~BP10G_MDIO_DATA_OUT));
7040e556
D
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
7040e556
D
1391 BP10G_WRITE_REG(pbpctl_dev, EODSDP,
1392 (ctrl_ext &
1393 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
7040e556 1394 }
75177588
LH
1395 if ((pbpctl_dev->wdt_status == WDT_STATUS_EN))
1396 /*&& (pbpctl_dev->bp_ext_ver<PXG4BPFI_VER) */
7040e556
D
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
efb39e4e 1405static void data_pulse(struct bpctl_dev *pbpctl_dev, unsigned char value)
7040e556
D
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
efb39e4e 1471static int send_wdt_pulse(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd
RK
1505static void send_bypass_clear_pulse(struct bpctl_dev *pbpctl_dev,
1506 unsigned int value)
7040e556
D
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
efb39e4e 1532int pulse_set_fn(struct bpctl_dev *pbpctl_dev, unsigned int counter)
7040e556
D
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
efb39e4e 1560int zero_set_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 1585int pulse_get2_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 1600int pulse_get1_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 1617int gpio6_set_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 1628int gpio7_set_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 1639int gpio7_clear_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 1650int gpio6_clear_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 1662static struct bpctl_dev *lookup_port(struct bpctl_dev *dev)
7040e556 1663{
efb39e4e 1664 struct bpctl_dev *p;
fb8004d3
AV
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}
7040e556 1674
efb39e4e 1675static struct bpctl_dev *get_status_port_fn(struct bpctl_dev *pbpctl_dev)
fb8004d3
AV
1676{
1677 if (pbpctl_dev) {
1678 if (pbpctl_dev->func == 0 || pbpctl_dev->func == 2)
1679 return lookup_port(pbpctl_dev);
7040e556
D
1680 }
1681 return NULL;
1682}
1683
efb39e4e 1684static struct bpctl_dev *get_master_port_fn(struct bpctl_dev *pbpctl_dev)
7040e556 1685{
fb8004d3
AV
1686 if (pbpctl_dev) {
1687 if (pbpctl_dev->func == 1 || pbpctl_dev->func == 3)
1688 return lookup_port(pbpctl_dev);
7040e556
D
1689 }
1690 return NULL;
1691}
1692
1693/**************************************/
1694/**************INTEL API***************/
1695/**************************************/
1696
efb39e4e 1697static void write_data_port_int(struct bpctl_dev *pbpctl_dev,
7040e556
D
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
efb39e4e 1722static int write_data_int(struct bpctl_dev *pbpctl_dev, unsigned char value)
7040e556 1723{
efb39e4e 1724 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556 1725
3f3c1fc9
CW
1726 pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
1727 if (!pbpctl_dev_b)
7040e556
D
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
efb39e4e 1737static int wdt_pulse_int(struct bpctl_dev *pbpctl_dev)
7040e556
D
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)*/
19ca44bd 1761static int cmnd_on(struct bpctl_dev *pbpctl_dev)
7040e556
D
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)*/
19ca44bd 1778static int cmnd_off(struct bpctl_dev *pbpctl_dev)
7040e556
D
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;
c429df9d 1791 }
7040e556
D
1792 return ret;
1793}
1794
1795/* BYPASS_ON (0xa)*/
19ca44bd 1796static int bypass_on(struct bpctl_dev *pbpctl_dev)
7040e556
D
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;
c429df9d 1812 }
7040e556
D
1813 return ret;
1814}
1815
1816/* BYPASS_OFF (0x8 111)*/
19ca44bd 1817static int bypass_off(struct bpctl_dev *pbpctl_dev)
7040e556
D
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)*/
19ca44bd 1840static int tap_off(struct bpctl_dev *pbpctl_dev)
7040e556
D
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;
c429df9d 1848 }
7040e556
D
1849 return ret;
1850}
1851
1852/* TAP_ON (0xb)*/
19ca44bd 1853static int tap_on(struct bpctl_dev *pbpctl_dev)
7040e556
D
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;
c429df9d 1861 }
7040e556
D
1862 return ret;
1863}
1864
1865/* DISC_OFF (0x9)*/
19ca44bd 1866static int disc_off(struct bpctl_dev *pbpctl_dev)
7040e556
D
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)*/
19ca44bd 1878static int disc_on(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
7040e556 1889/*TWO_PORT_LINK_HW_EN (0xe)*/
19ca44bd 1890static int tpl_hw_on(struct bpctl_dev *pbpctl_dev)
7040e556
D
1891{
1892 int ret = 0, ctrl = 0;
efb39e4e 1893 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556 1894
3f3c1fc9
CW
1895 pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
1896 if (!pbpctl_dev_b)
7040e556
D
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)*/
19ca44bd 1918static int tpl_hw_off(struct bpctl_dev *pbpctl_dev)
7040e556
D
1919{
1920 int ret = 0, ctrl = 0;
efb39e4e 1921 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556 1922
3f3c1fc9
CW
1923 pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
1924 if (!pbpctl_dev_b)
7040e556
D
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)*/
19ca44bd 1944static int wdt_off(struct bpctl_dev *pbpctl_dev)
7040e556
D
1945{
1946 int ret = BP_NOT_CAP;
1947
1948 if (pbpctl_dev->bp_caps & WD_CTL_CAP) {
ea675ee5 1949 if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
7040e556 1950 bypass_off(pbpctl_dev);
ea675ee5 1951 else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER)
7040e556
D
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;
c429df9d 1957 }
7040e556
D
1958 return ret;
1959}
1960
1961/* WDT_ON (0x10)*/
1962
1963/***Global***/
1964static unsigned int
1965 wdt_val_array[] = { 1000, 1500, 2000, 3000, 4000, 8000, 16000, 32000, 0 };
1966
19ca44bd 1967static int wdt_on(struct bpctl_dev *pbpctl_dev, unsigned int timeout)
7040e556
D
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
19ca44bd 2019static void bp75_put_hw_semaphore_generic(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 2030static s32 bp75_get_hw_semaphore_generic(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 2078static void bp75_release_phy(struct bpctl_dev *pbpctl_dev)
7040e556
D
2079{
2080 u16 mask = BPCTLI_SWFW_PHY0_SM;
2081 u32 swfw_sync;
28352c3f 2082 s32 ret_val;
7040e556
D
2083
2084 if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3))
2085 mask = BPCTLI_SWFW_PHY1_SM;
2086
28352c3f
LH
2087 do
2088 ret_val = bp75_get_hw_semaphore_generic(pbpctl_dev);
2089 while (ret_val != 0);
7040e556
D
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
efb39e4e 2098static s32 bp75_acquire_phy(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd
RK
2144static s32 bp75_read_phy_reg_mdic(struct bpctl_dev *pbpctl_dev, u32 offset,
2145 u16 *data)
7040e556
D
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
19ca44bd
RK
2178static s32 bp75_write_phy_reg_mdic(struct bpctl_dev *pbpctl_dev, u32 offset,
2179 u16 data)
7040e556
D
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
efb39e4e 2212static s32 bp75_read_phy_reg(struct bpctl_dev *pbpctl_dev, u32 offset, u16 *data)
7040e556
D
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
efb39e4e 2238static s32 bp75_write_phy_reg(struct bpctl_dev *pbpctl_dev, u32 offset, u16 data)
7040e556
D
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 :)) */
efb39e4e 2266static int set_tx(struct bpctl_dev *pbpctl_dev, int tx_state)
7040e556
D
2267{
2268 int ret = 0, ctrl = 0;
efb39e4e 2269 struct bpctl_dev *pbpctl_dev_m;
7040e556
D
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;
338d1ad1
HS
2309 ret = bp75_read_phy_reg(pbpctl_dev,
2310 BPCTLI_PHY_CONTROL,
2311 &mii_reg);
2312 if (!ret) {
7040e556
D
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;
338d1ad1
HS
2324 ret = bp75_read_phy_reg(pbpctl_dev,
2325 BPCTLI_PHY_CONTROL,
2326 &mii_reg);
2327 if (!ret) {
7040e556
D
2328
2329 mii_reg |= BPCTLI_MII_CR_POWER_DOWN;
338d1ad1
HS
2330 ret = bp75_write_phy_reg(pbpctl_dev,
2331 BPCTLI_PHY_CONTROL,
2332 mii_reg);
7040e556
D
2333 }
2334 }
2335
2336 }
ea675ee5 2337 if (pbpctl_dev->bp_fiber5)
7040e556 2338 ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
ea675ee5 2339 else if (pbpctl_dev->bp_10gb)
7040e556 2340 ctrl = BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO);
7040e556
D
2341 else if (!pbpctl_dev->bp_10g)
2342 ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
2343 else
7040e556
D
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
7040e556
D
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
7040e556
D
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 :)) */
efb39e4e 2463static int set_bp_force_link(struct bpctl_dev *pbpctl_dev, int tx_state)
7040e556
D
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 */
19ca44bd 2487static int reset_cont(struct bpctl_dev *pbpctl_dev)
7040e556
D
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;
c429df9d 2499 }
7040e556
D
2500 return ret;
2501}
2502
2503/*DIS_BYPASS_CAP 0x22 */
19ca44bd 2504static int dis_bypass_cap(struct bpctl_dev *pbpctl_dev)
7040e556
D
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 */
19ca44bd 2523static int en_bypass_cap(struct bpctl_dev *pbpctl_dev)
7040e556
D
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*/
19ca44bd 2539static int bypass_state_pwron(struct bpctl_dev *pbpctl_dev)
7040e556
D
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*/
19ca44bd 2553static int normal_state_pwron(struct bpctl_dev *pbpctl_dev)
7040e556
D
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*/
19ca44bd 2568static int bypass_state_pwroff(struct bpctl_dev *pbpctl_dev)
7040e556
D
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*/
19ca44bd 2579static int normal_state_pwroff(struct bpctl_dev *pbpctl_dev)
7040e556
D
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*/
19ca44bd 2590static int tap_state_pwron(struct bpctl_dev *pbpctl_dev)
7040e556
D
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*/
19ca44bd 2601static int dis_tap_cap(struct bpctl_dev *pbpctl_dev)
7040e556
D
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*/
19ca44bd 2612static int en_tap_cap(struct bpctl_dev *pbpctl_dev)
7040e556
D
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*/
19ca44bd 2623static int disc_state_pwron(struct bpctl_dev *pbpctl_dev)
7040e556
D
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*/
19ca44bd 2636static int dis_disc_cap(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
7040e556 2648/*EN_TAP_CAP 0x2e*/
19ca44bd 2649static int en_disc_cap(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 2661static int std_nic_on(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 2715static int std_nic_off(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 2767int wdt_time_left(struct bpctl_dev *pbpctl_dev)
7040e556
D
2768{
2769
687bcca0 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; */
7040e556
D
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
efb39e4e 2799static int wdt_timer(struct bpctl_dev *pbpctl_dev, int *time_left)
7040e556
D
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
efb39e4e 2815static int wdt_timer_reload(struct bpctl_dev *pbpctl_dev)
7040e556
D
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);
687bcca0
DC
2830 /* if (ret==-1)
2831 mod_timer(&pbpctl_dev->bp_timer, jiffies+1);*/
7040e556
D
2832 return 1;
2833 }
2834 return BP_NOT_CAP;
2835}
2836
2837static void wd_reset_timer(unsigned long param)
2838{
efb39e4e 2839 struct bpctl_dev *pbpctl_dev = (struct bpctl_dev *) param;
7040e556
D
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
7040e556 2877/*WAIT_AT_PWRUP 0x80 */
19ca44bd 2878static int bp_wait_at_pwup_en(struct bpctl_dev *pbpctl_dev)
7040e556
D
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 */
19ca44bd 2893static int bp_wait_at_pwup_dis(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 2910static int bp_hw_reset_en(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 2926static int bp_hw_reset_dis(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
7040e556 2940
19ca44bd 2941static int wdt_exp_mode(struct bpctl_dev *pbpctl_dev, int mode)
7040e556
D
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
19ca44bd 2992static int bypass_fw_ver(struct bpctl_dev *pbpctl_dev)
7040e556
D
2993{
2994 if (is_bypass_fn(pbpctl_dev))
7935c80c 2995 return read_reg(pbpctl_dev, VER_REG_ADDR);
7040e556
D
2996 else
2997 return BP_NOT_CAP;
2998}
2999
19ca44bd 3000static int bypass_sign_check(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 3010static int tx_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
3011{
3012 uint32_t ctrl = 0;
efb39e4e 3013 struct bpctl_dev *pbpctl_dev_m;
7040e556
D
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
efb39e4e 3097static int bp_force_link_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3111static int bypass_from_last_read(struct bpctl_dev *pbpctl_dev)
7040e556
D
3112{
3113 uint32_t ctrl_ext = 0;
efb39e4e 3114 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556 3115
3f3c1fc9
CW
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;
7040e556
D
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
19ca44bd 3131static int bypass_status_clear(struct bpctl_dev *pbpctl_dev)
7040e556 3132{
efb39e4e 3133 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556 3134
3f3c1fc9
CW
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;
7040e556
D
3139 send_bypass_clear_pulse(pbpctl_dev_b, 1);
3140 return 0;
3141 } else
3142 return BP_NOT_CAP;
3143}
3144
19ca44bd 3145static int bypass_flag_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3158static int bypass_flag_status_clear(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3173static int bypass_change_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 3192static int bypass_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
3193{
3194 u32 ctrl_ext = 0;
3195 if (pbpctl_dev->bp_caps & BP_CAP) {
3196
efb39e4e 3197 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556 3198
3f3c1fc9
CW
3199 pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
3200 if (!pbpctl_dev_b)
7040e556
D
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
7040e556
D
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));
7040e556
D
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));
7040e556
D
3258 return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) &
3259 BP10G_SDP7_DATA_IN) != 0 ? 0 : 1);
3260 }
3261
ae0b9530 3262 } else if (pbpctl_dev->media_type == BP_COPPER) {
7040e556
D
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)
7935c80c 3268 return bypass_from_last_read(pbpctl_dev);
7040e556
D
3269 }
3270
3271 }
3272 return BP_NOT_CAP;
3273}
3274
19ca44bd 3275static int default_pwron_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 3293static int default_pwroff_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3307static int dis_bypass_cap_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3320static int wdt_programmed(struct bpctl_dev *pbpctl_dev, int *timeout)
7040e556
D
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;
c429df9d 3340 }
7040e556
D
3341 } else
3342 ret = BP_NOT_CAP;
3343 return ret;
3344}
3345
19ca44bd 3346static int normal_support(struct bpctl_dev *pbpctl_dev)
7040e556
D
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;
c429df9d 3358 }
7040e556
D
3359 return ret;
3360}
3361
19ca44bd 3362static int get_bp_prod_caps(struct bpctl_dev *pbpctl_dev)
7040e556
D
3363{
3364 if ((pbpctl_dev->bp_caps & SW_CTL_CAP) &&
3365 (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER))
7935c80c 3366 return read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR);
7040e556
D
3367 return BP_NOT_CAP;
3368
3369}
3370
19ca44bd 3371static int tap_flag_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3383static int tap_flag_status_clear(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3397static int tap_change_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3414static int tap_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
3415{
3416 u32 ctrl_ext = 0;
3417
3418 if (pbpctl_dev->bp_caps & TAP_CAP) {
efb39e4e 3419 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556 3420
3f3c1fc9
CW
3421 pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
3422 if (!pbpctl_dev_b)
7040e556
D
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));
7040e556
D
3437 return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) &
3438 BP10G_SDP6_DATA_IN) != 0 ? 0 : 1);
3439 }
3440
ae0b9530 3441 } else if (pbpctl_dev->media_type == BP_COPPER)
7040e556
D
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)
7935c80c 3446 return bypass_from_last_read(pbpctl_dev);
7040e556
D
3447 }
3448
3449 }
3450 return BP_NOT_CAP;
3451}
3452
19ca44bd 3453static int default_pwron_tap_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3464static int dis_tap_cap_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3475static int disc_flag_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3487static int disc_flag_status_clear(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3501static int disc_change_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3512static int disc_off_status(struct bpctl_dev *pbpctl_dev)
7040e556 3513{
efb39e4e 3514 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556
D
3515 u32 ctrl_ext = 0;
3516
3517 if (pbpctl_dev->bp_caps & DISC_CAP) {
3f3c1fc9
CW
3518 pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
3519 if (!pbpctl_dev_b)
7040e556
D
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) {
7040e556
D
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);
7040e556
D
3532 return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) &
3533 BP10G_SDP2_DATA) != 0 ? 1 : 0);
3534
3535 }
ae0b9530 3536 if (pbpctl_dev->media_type == BP_COPPER) {
7040e556
D
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
7040e556
D
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));
7040e556
D
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));
7040e556
D
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
efb39e4e 3596static int disc_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
3597{
3598 int ctrl = 0;
3599 if (pbpctl_dev->bp_caps & DISC_CAP) {
3f3c1fc9
CW
3600 ctrl = disc_off_status(pbpctl_dev);
3601 if (ctrl < 0)
7040e556
D
3602 return ctrl;
3603 return ((ctrl == 0) ? 1 : 0);
7040e556
D
3604 }
3605 return BP_NOT_CAP;
3606}
3607
19ca44bd 3608static int default_pwron_disc_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3619static int dis_disc_cap_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3630static int wdt_exp_mode_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3653static int tpl2_flag_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3664static int bp_wait_at_pwup_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 3675static int bp_hw_reset_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
7040e556 3688
19ca44bd 3689static int std_nic_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
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/******************************************************/
19ca44bd 3737static void bypass_caps_init(struct bpctl_dev *pbpctl_dev)
7040e556
D
3738{
3739 u_int32_t ctrl_ext = 0;
efb39e4e 3740 struct bpctl_dev *pbpctl_dev_m = NULL;
7040e556
D
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)) {
ae0b9530 3764 pbpctl_dev->media_type = BP_FIBER;
7040e556
D
3765 } else if (pbpctl_dev->bp_10gb) {
3766 if (BP10GB_CX4_SERIES(pbpctl_dev->subdevice))
ae0b9530 3767 pbpctl_dev->media_type = BP_CX4;
7040e556 3768 else
ae0b9530 3769 pbpctl_dev->media_type = BP_FIBER;
7040e556
D
3770
3771 }
3772
3773 else if (pbpctl_dev->bp_540)
ae0b9530 3774 pbpctl_dev->media_type = BP_NONE;
7040e556
D
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)
ae0b9530 3779 pbpctl_dev->media_type = BP_COPPER;
7040e556 3780 else
ae0b9530 3781 pbpctl_dev->media_type = BP_FIBER;
7040e556 3782
687bcca0 3783 } else {
7040e556 3784 if (BP10G_CX4_SERIES(pbpctl_dev->subdevice))
ae0b9530 3785 pbpctl_dev->media_type = BP_CX4;
7040e556 3786 else
ae0b9530 3787 pbpctl_dev->media_type = BP_FIBER;
7040e556
D
3788 }
3789
7040e556
D
3790 if (is_bypass_fn(pbpctl_dev)) {
3791
3792 pbpctl_dev->bp_caps |= BP_PWOFF_ON_CAP;
ae0b9530 3793 if (pbpctl_dev->media_type == BP_FIBER)
7040e556
D
3794 pbpctl_dev->bp_caps |=
3795 (TX_CTL_CAP | TX_STATUS_CAP | TPL_CAP);
3796
ea675ee5 3797 if (TPL_IF_SERIES(pbpctl_dev->subdevice))
7040e556 3798 pbpctl_dev->bp_caps |= TPL_CAP;
7040e556
D
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
ea675ee5 3938 if (BP10GB_IF_SERIES(pbpctl_dev->subdevice))
7040e556 3939 pbpctl_dev->bp_caps &= ~(TX_CTL_CAP | TX_STATUS_CAP);
ea675ee5 3940
7040e556
D
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
19ca44bd 3955static void remove_bypass_wd_auto(struct bpctl_dev *pbpctl_dev)
7040e556
D
3956{
3957#ifdef BP_SELF_TEST
efb39e4e 3958 struct bpctl_dev *pbpctl_dev_sl = NULL;
7040e556
D
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);
7040e556
D
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 }
7040e556
D
3979#endif
3980 }
3981
3982}
3983
19ca44bd 3984static int init_bypass_wd_auto(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
3996int bp_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
3997{
efb39e4e 3998 struct bpctl_dev *pbpctl_dev = NULL, *pbpctl_dev_m = NULL;
7040e556
D
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 }
7935c80c 4027 return pbpctl_dev->hard_start_xmit_save(skb, dev);
7040e556
D
4028}
4029#endif
4030
19ca44bd 4031static int set_bypass_wd_auto(struct bpctl_dev *pbpctl_dev, unsigned int param)
7040e556
D
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
19ca44bd 4050static int get_bypass_wd_auto(struct bpctl_dev *pbpctl_dev)
7040e556 4051{
ea675ee5 4052 if (pbpctl_dev->bp_caps & WD_CTL_CAP)
7040e556 4053 return pbpctl_dev->reset_time;
ea675ee5 4054
7040e556
D
4055 return BP_NOT_CAP;
4056}
4057
a0069a41 4058#ifdef BP_SELF_TEST
7040e556 4059
efb39e4e 4060int set_bp_self_test(struct bpctl_dev *pbpctl_dev, unsigned int param)
7040e556 4061{
efb39e4e 4062 struct bpctl_dev *pbpctl_dev_sl = NULL;
7040e556
D
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);
7040e556 4067
7040e556
D
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 }
7040e556
D
4088
4089 set_bypass_wd_auto(pbpctl_dev, param);
4090 return 0;
4091 }
4092 return BP_NOT_CAP;
4093}
4094
efb39e4e 4095int get_bp_self_test(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
efb39e4e 4113int is_bypass_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4114{
4115 if (!pbpctl_dev)
4116 return -1;
4117
4118 return (((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) ? 1 : 0);
4119}
4120
19ca44bd 4121static int set_bypass_fn(struct bpctl_dev *pbpctl_dev, int bypass_mode)
7040e556
D
4122{
4123 int ret = 0;
4124
4125 if (!(pbpctl_dev->bp_caps & BP_CAP))
4126 return BP_NOT_CAP;
d0941b1e
CW
4127 ret = cmnd_on(pbpctl_dev);
4128 if (ret < 0)
7040e556
D
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
19ca44bd 4139static int get_bypass_fn(struct bpctl_dev *pbpctl_dev)
7040e556 4140{
7935c80c 4141 return bypass_status(pbpctl_dev);
7040e556
D
4142}
4143
19ca44bd 4144static int get_bypass_change_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4145{
4146 if (!pbpctl_dev)
4147 return -1;
4148
7935c80c 4149 return bypass_change_status(pbpctl_dev);
7040e556
D
4150}
4151
19ca44bd 4152static int set_dis_bypass_fn(struct bpctl_dev *pbpctl_dev, int dis_param)
7040e556
D
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;
d0941b1e
CW
4160 ret = cmnd_on(pbpctl_dev);
4161 if (ret < 0)
7040e556
D
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
19ca44bd 4171static int get_dis_bypass_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4172{
4173 if (!pbpctl_dev)
4174 return -1;
4175
7935c80c 4176 return dis_bypass_cap_status(pbpctl_dev);
7040e556
D
4177}
4178
19ca44bd 4179static int set_bypass_pwoff_fn(struct bpctl_dev *pbpctl_dev, int bypass_mode)
7040e556
D
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;
d0941b1e
CW
4187 ret = cmnd_on(pbpctl_dev);
4188 if (ret < 0)
7040e556
D
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
19ca44bd 4198static int get_bypass_pwoff_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4199{
4200 if (!pbpctl_dev)
4201 return -1;
4202
7935c80c 4203 return default_pwroff_status(pbpctl_dev);
7040e556
D
4204}
4205
19ca44bd 4206static int set_bypass_pwup_fn(struct bpctl_dev *pbpctl_dev, int bypass_mode)
7040e556
D
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;
d0941b1e
CW
4214 ret = cmnd_on(pbpctl_dev);
4215 if (ret < 0)
7040e556
D
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
19ca44bd 4225static int get_bypass_pwup_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4226{
4227 if (!pbpctl_dev)
4228 return -1;
4229
7935c80c 4230 return default_pwron_status(pbpctl_dev);
7040e556
D
4231}
4232
19ca44bd 4233static int set_bypass_wd_fn(struct bpctl_dev *pbpctl_dev, int timeout)
7040e556
D
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
d0941b1e
CW
4242 ret = cmnd_on(pbpctl_dev);
4243 if (ret < 0)
7040e556
D
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
19ca44bd 4255static int get_bypass_wd_fn(struct bpctl_dev *pbpctl_dev, int *timeout)
7040e556
D
4256{
4257 if (!pbpctl_dev)
4258 return -1;
4259
4260 return wdt_programmed(pbpctl_dev, timeout);
4261}
4262
19ca44bd 4263static int get_wd_expire_time_fn(struct bpctl_dev *pbpctl_dev, int *time_left)
7040e556
D
4264{
4265 if (!pbpctl_dev)
4266 return -1;
4267
7935c80c 4268 return wdt_timer(pbpctl_dev, time_left);
7040e556
D
4269}
4270
19ca44bd 4271static int reset_bypass_wd_timer_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4272{
4273 if (!pbpctl_dev)
4274 return -1;
4275
7935c80c 4276 return wdt_timer_reload(pbpctl_dev);
7040e556
D
4277}
4278
19ca44bd 4279static int get_wd_set_caps_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 4303static int set_std_nic_fn(struct bpctl_dev *pbpctl_dev, int nic_mode)
7040e556
D
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
d0941b1e
CW
4312 ret = cmnd_on(pbpctl_dev);
4313 if (ret < 0)
7040e556
D
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
19ca44bd 4323static int get_std_nic_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4324{
4325 if (!pbpctl_dev)
4326 return -1;
4327
7935c80c 4328 return std_nic_status(pbpctl_dev);
7040e556
D
4329}
4330
19ca44bd 4331static int set_tap_fn(struct bpctl_dev *pbpctl_dev, int tap_mode)
7040e556
D
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
19ca44bd 4347static int get_tap_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4348{
4349 if (!pbpctl_dev)
4350 return -1;
4351
7935c80c 4352 return tap_status(pbpctl_dev);
7040e556
D
4353}
4354
19ca44bd 4355static int set_tap_pwup_fn(struct bpctl_dev *pbpctl_dev, int tap_mode)
7040e556
D
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
19ca44bd 4373static int get_tap_pwup_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4374{
4375 int ret = 0;
4376 if (!pbpctl_dev)
4377 return -1;
4378
d0941b1e
CW
4379 ret = default_pwron_tap_status(pbpctl_dev);
4380 if (ret < 0)
7040e556
D
4381 return ret;
4382 return ((ret == 0) ? 1 : 0);
4383}
4384
19ca44bd 4385static int get_tap_change_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4386{
4387 if (!pbpctl_dev)
4388 return -1;
4389
7935c80c 4390 return tap_change_status(pbpctl_dev);
7040e556
D
4391}
4392
19ca44bd 4393static int set_dis_tap_fn(struct bpctl_dev *pbpctl_dev, int dis_param)
7040e556
D
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
19ca44bd 4410static int get_dis_tap_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4411{
4412 if (!pbpctl_dev)
4413 return -1;
4414
7935c80c 4415 return dis_tap_cap_status(pbpctl_dev);
7040e556
D
4416}
4417
19ca44bd 4418static int set_disc_fn(struct bpctl_dev *pbpctl_dev, int disc_mode)
7040e556
D
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
19ca44bd 4435static int get_disc_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 4446static int set_disc_pwup_fn(struct bpctl_dev *pbpctl_dev, int disc_mode)
7040e556
D
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
19ca44bd 4464static int get_disc_pwup_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 4474static int get_disc_change_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 4484static int set_dis_disc_fn(struct bpctl_dev *pbpctl_dev, int dis_param)
7040e556
D
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
19ca44bd 4502static int get_dis_disc_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 4513static int get_wd_exp_mode_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4514{
4515 if (!pbpctl_dev)
4516 return -1;
4517
7935c80c 4518 return wdt_exp_mode_status(pbpctl_dev);
7040e556
D
4519}
4520
19ca44bd 4521static int set_wd_exp_mode_fn(struct bpctl_dev *pbpctl_dev, int param)
7040e556
D
4522{
4523 if (!pbpctl_dev)
4524 return -1;
4525
7935c80c 4526 return wdt_exp_mode(pbpctl_dev, param);
7040e556
D
4527}
4528
19ca44bd 4529static int set_tx_fn(struct bpctl_dev *pbpctl_dev, int tx_state)
7040e556
D
4530{
4531
efb39e4e 4532 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556
D
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;
d0941b1e
CW
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) &&
7040e556
D
4544 (pbpctl_dev_b->bp_tpl_flag))
4545 return BP_NOT_CAP;
4546 }
7935c80c 4547 return set_tx(pbpctl_dev, tx_state);
7040e556
D
4548}
4549
19ca44bd 4550static int set_bp_force_link_fn(int dev_num, int tx_state)
7040e556 4551{
efb39e4e 4552 static struct bpctl_dev *bpctl_dev_curr;
7040e556
D
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
7935c80c 4559 return set_bp_force_link(bpctl_dev_curr, tx_state);
7040e556
D
4560}
4561
19ca44bd 4562static int set_wd_autoreset_fn(struct bpctl_dev *pbpctl_dev, int param)
7040e556
D
4563{
4564 if (!pbpctl_dev)
4565 return -1;
4566
7935c80c 4567 return set_bypass_wd_auto(pbpctl_dev, param);
7040e556
D
4568}
4569
19ca44bd 4570static int get_wd_autoreset_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4571{
4572 if (!pbpctl_dev)
4573 return -1;
4574
7935c80c 4575 return get_bypass_wd_auto(pbpctl_dev);
7040e556
D
4576}
4577
4578#ifdef BP_SELF_TEST
efb39e4e 4579int set_bp_self_test_fn(struct bpctl_dev *pbpctl_dev, int param)
7040e556
D
4580{
4581 if (!pbpctl_dev)
4582 return -1;
4583
7935c80c 4584 return set_bp_self_test(pbpctl_dev, param);
7040e556
D
4585}
4586
efb39e4e 4587int get_bp_self_test_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4588{
4589 if (!pbpctl_dev)
4590 return -1;
4591
7935c80c 4592 return get_bp_self_test(pbpctl_dev);
7040e556
D
4593}
4594
4595#endif
4596
19ca44bd 4597static int get_bypass_caps_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4598{
4599 if (!pbpctl_dev)
4600 return -1;
4601
7935c80c 4602 return pbpctl_dev->bp_caps;
7040e556
D
4603
4604}
4605
19ca44bd
RK
4606static int get_bypass_slave_fn(struct bpctl_dev *pbpctl_dev,
4607 struct bpctl_dev **pbpctl_dev_out)
7040e556
D
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
19ca44bd 4639static int is_bypass(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 4650static int get_tx_fn(struct bpctl_dev *pbpctl_dev)
7040e556 4651{
efb39e4e 4652 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556
D
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;
d0941b1e
CW
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) &&
7040e556
D
4664 (pbpctl_dev_b->bp_tpl_flag))
4665 return BP_NOT_CAP;
4666 }
7935c80c 4667 return tx_status(pbpctl_dev);
7040e556
D
4668}
4669
19ca44bd 4670static int get_bp_force_link_fn(int dev_num)
7040e556 4671{
efb39e4e 4672 static struct bpctl_dev *bpctl_dev_curr;
7040e556
D
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
7935c80c 4679 return bp_force_link_status(bpctl_dev_curr);
7040e556
D
4680}
4681
efb39e4e 4682static int get_bypass_link_status(struct bpctl_dev *pbpctl_dev)
7040e556
D
4683{
4684 if (!pbpctl_dev)
4685 return -1;
4686
ae0b9530 4687 if (pbpctl_dev->media_type == BP_FIBER)
7040e556
D
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
4696static void bp_tpl_timer_fn(unsigned long param)
4697{
efb39e4e 4698 struct bpctl_dev *pbpctl_dev = (struct bpctl_dev *) param;
7040e556 4699 uint32_t link1, link2;
efb39e4e 4700 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556 4701
d0941b1e
CW
4702 pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
4703 if (!pbpctl_dev_b)
7040e556
D
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))) {
ea675ee5 4715 if ((!link2) && (tx_status(pbpctl_dev_b)))
7040e556 4716 set_tx(pbpctl_dev, 0);
ea675ee5 4717 else if (!tx_status(pbpctl_dev_b))
7040e556 4718 set_tx(pbpctl_dev_b, 1);
7040e556 4719 } else if ((!link1) && (tx_status(pbpctl_dev))) {
ea675ee5 4720 if ((link2) && (tx_status(pbpctl_dev_b)))
7040e556 4721 set_tx(pbpctl_dev_b, 0);
7040e556 4722 } else if ((link1) && (!tx_status(pbpctl_dev))) {
ea675ee5 4723 if ((link2) && (tx_status(pbpctl_dev_b)))
7040e556 4724 set_tx(pbpctl_dev, 1);
7040e556 4725 } else if ((!link1) && (!tx_status(pbpctl_dev))) {
ea675ee5 4726 if ((link2) && (tx_status(pbpctl_dev_b)))
7040e556 4727 set_tx(pbpctl_dev, 1);
7040e556
D
4728 }
4729
4730 mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies + BP_LINK_MON_DELAY * HZ);
4731}
4732
19ca44bd 4733static void remove_bypass_tpl_auto(struct bpctl_dev *pbpctl_dev)
7040e556 4734{
efb39e4e 4735 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556
D
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
19ca44bd 4751static int init_bypass_tpl_auto(struct bpctl_dev *pbpctl_dev)
7040e556
D
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
19ca44bd 4764static int set_bypass_tpl_auto(struct bpctl_dev *pbpctl_dev, unsigned int param)
7040e556
D
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;
c429df9d 4773 }
7040e556
D
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
19ca44bd 4782static int set_tpl_fn(struct bpctl_dev *pbpctl_dev, int tpl_mode)
7040e556
D
4783{
4784
efb39e4e 4785 struct bpctl_dev *pbpctl_dev_b = NULL;
7040e556
D
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) {
d0941b1e
CW
4793 pbpctl_dev_b = get_status_port_fn(pbpctl_dev);
4794 if (pbpctl_dev_b)
7040e556
D
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
19ca44bd 4812static int get_tpl_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
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)
7935c80c 4820 return tpl2_flag_status(pbpctl_dev);
7040e556
D
4821 ret = pbpctl_dev->bp_tpl_flag;
4822 }
4823 return ret;
4824}
4825
19ca44bd 4826static int set_bp_wait_at_pwup_fn(struct bpctl_dev *pbpctl_dev, int tap_mode)
7040e556
D
4827{
4828 if (!pbpctl_dev)
4829 return -1;
4830
4831 if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
687bcca0 4832 /* bp_lock(pbp_device_block); */
7040e556
D
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
687bcca0 4840 /* bp_unlock(pbp_device_block); */
7040e556
D
4841 return BP_OK;
4842 }
4843 return BP_NOT_CAP;
4844}
4845
19ca44bd 4846static int get_bp_wait_at_pwup_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4847{
4848 int ret = 0;
4849 if (!pbpctl_dev)
4850 return -1;
4851
687bcca0 4852 /* bp_lock(pbp_device_block); */
7040e556 4853 ret = bp_wait_at_pwup_status(pbpctl_dev);
687bcca0 4854 /* bp_unlock(pbp_device_block); */
7040e556
D
4855
4856 return ret;
4857}
4858
19ca44bd 4859static int set_bp_hw_reset_fn(struct bpctl_dev *pbpctl_dev, int tap_mode)
7040e556
D
4860{
4861 if (!pbpctl_dev)
4862 return -1;
4863
4864 if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
687bcca0 4865 /* bp_lock(pbp_device_block); */
7040e556
D
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);
687bcca0 4873 /* bp_unlock(pbp_device_block); */
7040e556
D
4874 return BP_OK;
4875 }
4876 return BP_NOT_CAP;
4877}
4878
19ca44bd 4879static int get_bp_hw_reset_fn(struct bpctl_dev *pbpctl_dev)
7040e556
D
4880{
4881 int ret = 0;
4882 if (!pbpctl_dev)
4883 return -1;
4884
687bcca0 4885 /* bp_lock(pbp_device_block); */
7040e556
D
4886 ret = bp_hw_reset_status(pbpctl_dev);
4887
687bcca0 4888 /* bp_unlock(pbp_device_block); */
7040e556
D
4889
4890 return ret;
4891}
4892
7040e556 4893
19ca44bd 4894static int get_bypass_info_fn(struct bpctl_dev *pbpctl_dev, char *dev_name,
7040e556
D
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
4624b543 4906static int get_dev_idx_bsf(int bus, int slot, int func)
7040e556
D
4907{
4908 int idx_dev = 0;
7040e556
D
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
7040e556
D
4921static 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
efb39e4e 4935static struct bpctl_dev *get_dev_idx_p(int ifindex)
7040e556
D
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
4949static void if_scan_init(void)
4950{
7040e556 4951 struct net_device *dev;
de2e487f 4952
687bcca0
DC
4953 /* rcu_read_lock(); */
4954 /* rtnl_lock(); */
4955 /* rcu_read_lock(); */
3e4cce9d
CW
4956
4957 for_each_netdev(&init_net, dev) {
de2e487f 4958 int idx_dev;
7040e556 4959
de2e487f 4960 if (bp_get_dev_idx_bsf(dev, &idx_dev))
7040e556 4961 continue;
7040e556 4962
de2e487f
AS
4963 if (idx_dev == -1)
4964 continue;
7040e556 4965
de2e487f
AS
4966 bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
4967 bpctl_dev_arr[idx_dev].ndev = dev;
7040e556 4968 }
687bcca0
DC
4969 /* rtnl_unlock(); */
4970 /* rcu_read_unlock(); */
7040e556
D
4971}
4972
3e4cce9d 4973static long device_ioctl(struct file *file, /* see include/linux/fs.h */
7040e556
D
4974 unsigned int ioctl_num, /* number and param for ioctl */
4975 unsigned long ioctl_param)
7040e556
D
4976{
4977 struct bpctl_cmd bpctl_cmd;
4978 int dev_idx = 0;
efb39e4e 4979 struct bpctl_dev *pbpctl_dev_out;
7040e556
D
4980 void __user *argp = (void __user *)ioctl_param;
4981 int ret = 0;
4982 unsigned long flags;
4983
efb39e4e 4984 static struct bpctl_dev *pbpctl_dev;
7040e556 4985
687bcca0 4986 /* lock_kernel(); */
27a9095a
LH
4987 if (down_interruptible(&bpctl_sema))
4988 return -ERESTARTSYS;
687bcca0
DC
4989 /* local_irq_save(flags); */
4990 /* if(!spin_trylock_irqsave(&bpvm_lock)){
7040e556 4991 local_irq_restore(flags);
687bcca0
DC
4992 unlock_bpctl();
4993 unlock_kernel();
7040e556
D
4994 return -1;
4995 } */
687bcca0 4996 /* spin_lock_irqsave(&bpvm_lock, flags); */
7040e556
D
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 }
687bcca0
DC
5023 /* lock_bpctl(); */
5024 /* preempt_disable(); */
7040e556
D
5025 local_irq_save(flags);
5026 if (!spin_trylock(&bpvm_lock)) {
5027 local_irq_restore(flags);
5028 unlock_bpctl();
7040e556
D
5029 return -1;
5030 }
687bcca0 5031
a7ce87e1 5032/* preempt_disable();
687bcca0 5033 rcu_read_lock();
a7ce87e1 5034 spin_lock_irqsave(&bpvm_lock, flags);
687bcca0 5035*/
7040e556
D
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) {
687bcca0
DC
5047 /* unlock_bpctl();
5048 preempt_enable(); */
7040e556 5049 ret = -EOPNOTSUPP;
687bcca0
DC
5050 /* preempt_enable();
5051 rcu_read_unlock(); */
7040e556
D
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;
687bcca0
DC
5067 /* preempt_enable(); */
5068 /* rcu_read_unlock(); */
7040e556
D
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;
687bcca0
DC
5081 /* preempt_enable(); */
5082 /* rcu_read_unlock(); */
7040e556
D
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(); */
687bcca0 5215 /*rcu_read_unlock();*/
7040e556
D
5216 spin_unlock_irqrestore(&bpvm_lock, flags);
5217 if (copy_to_user
5218 (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) {
687bcca0
DC
5219 /*unlock_bpctl(); */
5220 /*preempt_enable(); */
7040e556
D
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;
7040e556
D
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;
7040e556
D
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:
687bcca0 5351 /* unlock_bpctl(); */
7040e556
D
5352
5353 ret = -EOPNOTSUPP;
687bcca0
DC
5354 /* preempt_enable(); */
5355 /* rcu_read_unlock();*/
7040e556
D
5356 spin_unlock_irqrestore(&bpvm_lock, flags);
5357 goto bp_exit;
5358 }
687bcca0
DC
5359 /* unlock_bpctl(); */
5360 /* preempt_enable(); */
7040e556 5361 bpcmd_exit:
687bcca0 5362 /* rcu_read_unlock(); */
7040e556
D
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:
687bcca0 5368 /* unlock_kernel(); */
687bcca0 5369 /* spin_unlock_irqrestore(&bpvm_lock, flags); */
7040e556 5370 unlock_bpctl();
687bcca0 5371 /* unlock_kernel(); */
7040e556
D
5372 return ret;
5373}
5374
75ef9de1 5375static const struct file_operations Fops = {
7040e556 5376 .owner = THIS_MODULE,
7040e556 5377 .unlocked_ioctl = device_ioctl,
7040e556
D
5378};
5379
5380#ifndef PCI_DEVICE
001bd4b4 5381#define PCI_DEVICE(vend, dev) \
7040e556
D
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
bbeebecc 5389enum board_type {
7040e556
D
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,
bbeebecc 5547};
7040e556 5548
c0141859 5549struct bpmod_info {
7040e556
D
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
c0141859 5557};
7040e556 5558
11c920b0 5559struct {
7040e556 5560 char *name;
11c920b0 5561} dev_desc[] = {
7040e556
D
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
c0141859 5731static struct bpmod_info tx_ctl_pci_tbl[] = {
7040e556
D
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
687bcca0 5860 /* {BROADCOM_VID, BROADCOM_PE10G2_PID, PCI_ANY_ID, PCI_ANY_ID, PE10G2BPTCX4, "PE10G2BPTCX4"}, */
7040e556
D
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"},
7040e556
D
5985 {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
5986 SILICOM_PE210G2DBi9LR_SSID, PE210G2DBi9LR, "PE210G2DBi9LR"},
7040e556
D
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
7040e556
D
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
efb39e4e 6199static void find_fw(struct bpctl_dev *dev)
bdcecec3
AV
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);
75177588 6221 if (dev->bp_fw_ver == 0xa8)
bdcecec3
AV
6222 break;
6223 }
6224 }
6225 /* dev->bp_fw_ver=0xa8; */
6226 printk("firmware version: 0x%x\n", dev->bp_fw_ver);
6227}
6228
c0141859 6229static int init_one(struct bpctl_dev *dev, struct bpmod_info *info, struct pci_dev *pdev1)
bdcecec3
AV
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
d0941b1e
CW
6300 dev->bp_tx_data = kzalloc(BPTEST_DATA_LEN, GFP_KERNEL);
6301 if (dev->bp_tx_data) {
bdcecec3
AV
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
7040e556
D
6312/*
6313* Initialize the module - Register the character device
6314*/
6315
6316static int __init bypass_init_module(void)
6317{
6318 int ret_val, idx, idx_dev = 0;
6319 struct pci_dev *pdev1 = NULL;
efb39e4e 6320 struct bpctl_dev *dev;
7040e556
D
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
efb39e4e 6345 bpctl_dev_arr = kmalloc((device_num) * sizeof(struct bpctl_dev), GFP_KERNEL);
7040e556
D
6346
6347 if (!bpctl_dev_arr) {
6348 printk("Allocation error\n");
6349 unregister_chrdev(major_num, DEVICE_NAME);
6350 return -1;
6351 }
efb39e4e 6352 memset(bpctl_dev_arr, 0, ((device_num) * sizeof(struct bpctl_dev)));
7040e556
D
6353
6354 pdev1 = NULL;
bdcecec3 6355 dev = bpctl_dev_arr;
7040e556
D
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))) {
bdcecec3
AV
6362 if (init_one(dev, &tx_ctl_pci_tbl[idx], pdev1) < 0)
6363 return -1;
6364 dev++;
7040e556
D
6365 }
6366 }
6367 if_scan_init();
6368
6369 sema_init(&bpctl_sema, 1);
6370 spin_lock_init(&bpvm_lock);
6371 {
6372
efb39e4e 6373 struct bpctl_dev *pbpctl_dev_c = NULL;
bdcecec3
AV
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)) {
7040e556 6380 printk(KERN_INFO "%s found, ",
bdcecec3
AV
6381 dev->name);
6382 dev->bp_fw_ver = bypass_fw_ver(dev);
7040e556 6383 printk("firmware version: 0x%x\n",
bdcecec3 6384 dev->bp_fw_ver);
7040e556 6385 }
bdcecec3
AV
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;
7040e556 6390
bdcecec3 6391 bypass_caps_init(dev);
7040e556 6392
bdcecec3
AV
6393 init_bypass_wd_auto(dev);
6394 init_bypass_tpl_auto(dev);
7040e556
D
6395
6396 }
6397
6398 }
6399 }
6400
7040e556
D
6401 register_netdevice_notifier(&bp_notifier_block);
6402#ifdef BP_PROC_SUPPORT
6403 {
6404 int i = 0;
687bcca0
DC
6405 /* unsigned long flags; */
6406 /* rcu_read_lock(); */
7040e556
D
6407 bp_proc_create();
6408 for (i = 0; i < device_num; i++) {
6409 if (bpctl_dev_arr[i].ifindex) {
687bcca0 6410 /* spin_lock_irqsave(&bpvm_lock, flags); */
7040e556
D
6411 bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]);
6412 bypass_proc_create_dev_sd(&bpctl_dev_arr[i]);
687bcca0 6413 /* spin_unlock_irqrestore(&bpvm_lock, flags); */
7040e556
D
6414 }
6415
6416 }
687bcca0 6417 /* rcu_read_unlock(); */
7040e556
D
6418 }
6419#endif
6420
7040e556
D
6421 return 0;
6422}
6423
6424/*
6425* Cleanup - unregister the appropriate file from /proc
6426*/
6427static void __exit bypass_cleanup_module(void)
6428{
6429 int i;
7040e556
D
6430 unregister_netdevice_notifier(&bp_notifier_block);
6431
7040e556 6432 for (i = 0; i < device_num; i++) {
687bcca0 6433 /* unsigned long flags; */
7040e556 6434#ifdef BP_PROC_SUPPORT
687bcca0
DC
6435/* spin_lock_irqsave(&bpvm_lock, flags);
6436 rcu_read_lock(); */
7040e556 6437 bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]);
f54ab7d9 6438/* spin_unlock_irqrestore(&bpvm_lock, flags);
687bcca0 6439 rcu_read_unlock(); */
7040e556
D
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
d39625c4 6450 kfree(bpctl_dev_arr[i].bp_tx_data);
7040e556
D
6451#endif
6452 iounmap((void *)(bpctl_dev_arr[i].mem_map));
6453 }
6454
6455 /* free all devices space */
d39625c4 6456 kfree(bpctl_dev_arr);
7040e556
D
6457
6458/*
f54ab7d9 6459* Unregister the device
7040e556 6460*/
7040e556 6461 unregister_chrdev(major_num, DEVICE_NAME);
7040e556
D
6462}
6463
6464module_init(bypass_init_module);
6465module_exit(bypass_cleanup_module);
6466
6467int is_bypass_sd(int ifindex)
6468{
7935c80c 6469 return is_bypass(get_dev_idx_p(ifindex));
7040e556 6470}
cadf87a0 6471EXPORT_SYMBOL(is_bypass_sd);
7040e556
D
6472
6473int set_bypass_sd(int ifindex, int bypass_mode)
6474{
6475
7935c80c 6476 return set_bypass_fn(get_dev_idx_p(ifindex), bypass_mode);
7040e556 6477}
cadf87a0 6478EXPORT_SYMBOL(set_bypass_sd);
7040e556
D
6479
6480int get_bypass_sd(int ifindex)
6481{
6482
7935c80c 6483 return get_bypass_fn(get_dev_idx_p(ifindex));
7040e556 6484}
cadf87a0 6485EXPORT_SYMBOL(get_bypass_sd);
7040e556
D
6486
6487int get_bypass_change_sd(int ifindex)
6488{
6489
7935c80c 6490 return get_bypass_change_fn(get_dev_idx_p(ifindex));
7040e556 6491}
cadf87a0 6492EXPORT_SYMBOL(get_bypass_change_sd);
7040e556
D
6493
6494int set_dis_bypass_sd(int ifindex, int dis_param)
6495{
7935c80c 6496 return set_dis_bypass_fn(get_dev_idx_p(ifindex), dis_param);
7040e556 6497}
cadf87a0 6498EXPORT_SYMBOL(set_dis_bypass_sd);
7040e556
D
6499
6500int get_dis_bypass_sd(int ifindex)
6501{
6502
7935c80c 6503 return get_dis_bypass_fn(get_dev_idx_p(ifindex));
7040e556 6504}
cadf87a0 6505EXPORT_SYMBOL(get_dis_bypass_sd);
7040e556
D
6506
6507int set_bypass_pwoff_sd(int ifindex, int bypass_mode)
6508{
7935c80c 6509 return set_bypass_pwoff_fn(get_dev_idx_p(ifindex), bypass_mode);
7040e556
D
6510
6511}
cadf87a0 6512EXPORT_SYMBOL(set_bypass_pwoff_sd);
7040e556
D
6513
6514int get_bypass_pwoff_sd(int ifindex)
6515{
7935c80c 6516 return get_bypass_pwoff_fn(get_dev_idx_p(ifindex));
7040e556
D
6517
6518}
cadf87a0 6519EXPORT_SYMBOL(get_bypass_pwoff_sd);
7040e556
D
6520
6521int set_bypass_pwup_sd(int ifindex, int bypass_mode)
6522{
7935c80c 6523 return set_bypass_pwup_fn(get_dev_idx_p(ifindex), bypass_mode);
7040e556
D
6524
6525}
cadf87a0 6526EXPORT_SYMBOL(set_bypass_pwup_sd);
7040e556
D
6527
6528int get_bypass_pwup_sd(int ifindex)
6529{
7935c80c 6530 return get_bypass_pwup_fn(get_dev_idx_p(ifindex));
7040e556
D
6531
6532}
cadf87a0 6533EXPORT_SYMBOL(get_bypass_pwup_sd);
7040e556
D
6534
6535int 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}
cadf87a0 6542EXPORT_SYMBOL(set_bypass_wd_sd);
7040e556
D
6543
6544int get_bypass_wd_sd(int ifindex, int *timeout)
6545{
7935c80c 6546 return get_bypass_wd_fn(get_dev_idx_p(ifindex), timeout);
7040e556
D
6547
6548}
cadf87a0 6549EXPORT_SYMBOL(get_bypass_wd_sd);
7040e556
D
6550
6551int get_wd_expire_time_sd(int ifindex, int *time_left)
6552{
7935c80c 6553 return get_wd_expire_time_fn(get_dev_idx_p(ifindex), time_left);
7040e556 6554}
cadf87a0 6555EXPORT_SYMBOL(get_wd_expire_time_sd);
7040e556
D
6556
6557int reset_bypass_wd_timer_sd(int ifindex)
6558{
7935c80c 6559 return reset_bypass_wd_timer_fn(get_dev_idx_p(ifindex));
7040e556
D
6560
6561}
cadf87a0 6562EXPORT_SYMBOL(reset_bypass_wd_timer_sd);
7040e556
D
6563
6564int get_wd_set_caps_sd(int ifindex)
6565{
7935c80c 6566 return get_wd_set_caps_fn(get_dev_idx_p(ifindex));
7040e556
D
6567
6568}
cadf87a0 6569EXPORT_SYMBOL(get_wd_set_caps_sd);
7040e556
D
6570
6571int set_std_nic_sd(int ifindex, int nic_mode)
6572{
7935c80c 6573 return set_std_nic_fn(get_dev_idx_p(ifindex), nic_mode);
7040e556
D
6574
6575}
cadf87a0 6576EXPORT_SYMBOL(set_std_nic_sd);
7040e556
D
6577
6578int get_std_nic_sd(int ifindex)
6579{
7935c80c 6580 return get_std_nic_fn(get_dev_idx_p(ifindex));
7040e556
D
6581
6582}
cadf87a0 6583EXPORT_SYMBOL(get_std_nic_sd);
7040e556
D
6584
6585int set_tap_sd(int ifindex, int tap_mode)
6586{
7935c80c 6587 return set_tap_fn(get_dev_idx_p(ifindex), tap_mode);
7040e556
D
6588
6589}
cadf87a0 6590EXPORT_SYMBOL(set_tap_sd);
7040e556
D
6591
6592int get_tap_sd(int ifindex)
6593{
7935c80c 6594 return get_tap_fn(get_dev_idx_p(ifindex));
7040e556
D
6595
6596}
cadf87a0 6597EXPORT_SYMBOL(get_tap_sd);
7040e556
D
6598
6599int set_tap_pwup_sd(int ifindex, int tap_mode)
6600{
7935c80c 6601 return set_tap_pwup_fn(get_dev_idx_p(ifindex), tap_mode);
7040e556
D
6602
6603}
cadf87a0 6604EXPORT_SYMBOL(set_tap_pwup_sd);
7040e556
D
6605
6606int get_tap_pwup_sd(int ifindex)
6607{
7935c80c 6608 return get_tap_pwup_fn(get_dev_idx_p(ifindex));
7040e556
D
6609
6610}
cadf87a0 6611EXPORT_SYMBOL(get_tap_pwup_sd);
7040e556
D
6612
6613int get_tap_change_sd(int ifindex)
6614{
7935c80c 6615 return get_tap_change_fn(get_dev_idx_p(ifindex));
7040e556
D
6616
6617}
cadf87a0 6618EXPORT_SYMBOL(get_tap_change_sd);
7040e556
D
6619
6620int set_dis_tap_sd(int ifindex, int dis_param)
6621{
7935c80c 6622 return set_dis_tap_fn(get_dev_idx_p(ifindex), dis_param);
7040e556
D
6623
6624}
cadf87a0 6625EXPORT_SYMBOL(set_dis_tap_sd);
7040e556
D
6626
6627int get_dis_tap_sd(int ifindex)
6628{
7935c80c 6629 return get_dis_tap_fn(get_dev_idx_p(ifindex));
7040e556
D
6630
6631}
cadf87a0 6632EXPORT_SYMBOL(get_dis_tap_sd);
7040e556
D
6633
6634int set_bp_disc_sd(int ifindex, int disc_mode)
6635{
7935c80c 6636 return set_disc_fn(get_dev_idx_p(ifindex), disc_mode);
7040e556
D
6637
6638}
cadf87a0 6639EXPORT_SYMBOL(set_bp_disc_sd);
7040e556
D
6640
6641int get_bp_disc_sd(int ifindex)
6642{
7935c80c 6643 return get_disc_fn(get_dev_idx_p(ifindex));
7040e556
D
6644
6645}
cadf87a0 6646EXPORT_SYMBOL(get_bp_disc_sd);
7040e556
D
6647
6648int set_bp_disc_pwup_sd(int ifindex, int disc_mode)
6649{
7935c80c 6650 return set_disc_pwup_fn(get_dev_idx_p(ifindex), disc_mode);
7040e556
D
6651
6652}
cadf87a0 6653EXPORT_SYMBOL(set_bp_disc_pwup_sd);
7040e556
D
6654
6655int get_bp_disc_pwup_sd(int ifindex)
6656{
7935c80c 6657 return get_disc_pwup_fn(get_dev_idx_p(ifindex));
7040e556
D
6658
6659}
cadf87a0 6660EXPORT_SYMBOL(get_bp_disc_pwup_sd);
7040e556
D
6661
6662int get_bp_disc_change_sd(int ifindex)
6663{
7935c80c 6664 return get_disc_change_fn(get_dev_idx_p(ifindex));
7040e556
D
6665
6666}
cadf87a0 6667EXPORT_SYMBOL(get_bp_disc_change_sd);
7040e556
D
6668
6669int set_bp_dis_disc_sd(int ifindex, int dis_param)
6670{
7935c80c 6671 return set_dis_disc_fn(get_dev_idx_p(ifindex), dis_param);
7040e556
D
6672
6673}
cadf87a0 6674EXPORT_SYMBOL(set_bp_dis_disc_sd);
7040e556
D
6675
6676int get_bp_dis_disc_sd(int ifindex)
6677{
7935c80c 6678 return get_dis_disc_fn(get_dev_idx_p(ifindex));
7040e556
D
6679
6680}
cadf87a0 6681EXPORT_SYMBOL(get_bp_dis_disc_sd);
7040e556
D
6682
6683int get_wd_exp_mode_sd(int ifindex)
6684{
7935c80c 6685 return get_wd_exp_mode_fn(get_dev_idx_p(ifindex));
7040e556 6686}
cadf87a0 6687EXPORT_SYMBOL(get_wd_exp_mode_sd);
7040e556
D
6688
6689int set_wd_exp_mode_sd(int ifindex, int param)
6690{
7935c80c 6691 return set_wd_exp_mode_fn(get_dev_idx_p(ifindex), param);
7040e556
D
6692
6693}
cadf87a0 6694EXPORT_SYMBOL(set_wd_exp_mode_sd);
7040e556 6695
7040e556
D
6696int set_tx_sd(int ifindex, int tx_state)
6697{
7935c80c 6698 return set_tx_fn(get_dev_idx_p(ifindex), tx_state);
7040e556
D
6699
6700}
cadf87a0 6701EXPORT_SYMBOL(set_tx_sd);
7040e556
D
6702
6703int set_tpl_sd(int ifindex, int tpl_state)
6704{
7935c80c 6705 return set_tpl_fn(get_dev_idx_p(ifindex), tpl_state);
7040e556
D
6706
6707}
cadf87a0 6708EXPORT_SYMBOL(set_tpl_sd);
7040e556
D
6709
6710int set_bp_hw_reset_sd(int ifindex, int status)
6711{
7935c80c 6712 return set_bp_hw_reset_fn(get_dev_idx_p(ifindex), status);
7040e556
D
6713
6714}
cadf87a0 6715EXPORT_SYMBOL(set_bp_hw_reset_sd);
7040e556
D
6716
6717int set_wd_autoreset_sd(int ifindex, int param)
6718{
7935c80c 6719 return set_wd_autoreset_fn(get_dev_idx_p(ifindex), param);
7040e556
D
6720
6721}
cadf87a0 6722EXPORT_SYMBOL(set_wd_autoreset_sd);
7040e556
D
6723
6724int get_wd_autoreset_sd(int ifindex)
6725{
7935c80c 6726 return get_wd_autoreset_fn(get_dev_idx_p(ifindex));
7040e556
D
6727
6728}
cadf87a0 6729EXPORT_SYMBOL(get_wd_autoreset_sd);
7040e556
D
6730
6731int get_bypass_caps_sd(int ifindex)
6732{
7935c80c 6733 return get_bypass_caps_fn(get_dev_idx_p(ifindex));
7040e556 6734}
cadf87a0 6735EXPORT_SYMBOL(get_bypass_caps_sd);
7040e556
D
6736
6737int get_bypass_slave_sd(int ifindex)
6738{
efb39e4e 6739 struct bpctl_dev *pbpctl_dev_out;
7040e556
D
6740 int ret = get_bypass_slave_fn(get_dev_idx_p(ifindex), &pbpctl_dev_out);
6741 if (ret == 1)
7935c80c 6742 return pbpctl_dev_out->ifindex;
7040e556
D
6743 return -1;
6744
6745}
cadf87a0 6746EXPORT_SYMBOL(get_bypass_slave_sd);
7040e556
D
6747
6748int get_tx_sd(int ifindex)
6749{
7935c80c 6750 return get_tx_fn(get_dev_idx_p(ifindex));
7040e556
D
6751
6752}
cadf87a0 6753EXPORT_SYMBOL(get_tx_sd);
7040e556
D
6754
6755int get_tpl_sd(int ifindex)
6756{
7935c80c 6757 return get_tpl_fn(get_dev_idx_p(ifindex));
7040e556
D
6758
6759}
cadf87a0 6760EXPORT_SYMBOL(get_tpl_sd);
7040e556
D
6761
6762int get_bp_hw_reset_sd(int ifindex)
6763{
7935c80c 6764 return get_bp_hw_reset_fn(get_dev_idx_p(ifindex));
7040e556
D
6765
6766}
cadf87a0 6767EXPORT_SYMBOL(get_bp_hw_reset_sd);
7040e556
D
6768
6769int get_bypass_info_sd(int ifindex, struct bp_info *bp_info)
6770{
7935c80c 6771 return get_bypass_info_fn(get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver);
7040e556 6772}
cadf87a0 6773EXPORT_SYMBOL(get_bypass_info_sd);
7040e556
D
6774
6775int bp_if_scan_sd(void)
6776{
6777 if_scan_init();
6778 return 0;
6779}
cadf87a0 6780EXPORT_SYMBOL(bp_if_scan_sd);
7040e556
D
6781
6782#define BP_PROC_DIR "bypass"
6783
7040e556
D
6784static struct proc_dir_entry *bp_procfs_dir;
6785
4624b543 6786static int bp_proc_create(void)
7040e556 6787{
a01b0c57 6788 bp_procfs_dir = proc_mkdir(BP_PROC_DIR, init_net.proc_net);
7040e556
D
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
a01b0c57 6798static int procfs_add(char *proc_name, const struct file_operations *fops,
efb39e4e 6799 struct bpctl_dev *dev)
7040e556 6800{
a01b0c57
AV
6801 struct bypass_pfs_sd *pfs = &dev->bypass_pfs_set;
6802 if (!proc_create_data(proc_name, 0644, pfs->bypass_entry, fops, dev))
7040e556 6803 return -1;
7040e556 6804 return 0;
7040e556
D
6805}
6806
a01b0c57
AV
6807#define RO_FOPS(name) \
6808static int name##_open(struct inode *inode, struct file *file) \
6809{ \
d9dda78b 6810 return single_open(file, show_##name, PDE_DATA(inode));\
a01b0c57
AV
6811} \
6812static const struct file_operations name##_ops = { \
6813 .open = name##_open, \
6814 .read = seq_read, \
6815 .llseek = seq_lseek, \
6816 .release = single_release, \
6817};
7040e556 6818
a01b0c57
AV
6819#define RW_FOPS(name) \
6820static int name##_open(struct inode *inode, struct file *file) \
6821{ \
d9dda78b 6822 return single_open(file, show_##name, PDE_DATA(inode));\
a01b0c57
AV
6823} \
6824static 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};
7040e556 6831
a01b0c57 6832static int show_bypass_info(struct seq_file *m, void *v)
7040e556 6833{
efb39e4e 6834 struct bpctl_dev *dev = m->private;
7040e556 6835
a01b0c57
AV
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;
7040e556 6839}
a01b0c57 6840RO_FOPS(bypass_info)
7040e556 6841
a01b0c57 6842static int show_bypass_slave(struct seq_file *m, void *v)
7040e556 6843{
efb39e4e
CW
6844 struct bpctl_dev *dev = m->private;
6845 struct bpctl_dev *slave = get_status_port_fn(dev);
a01b0c57
AV
6846 if (!slave)
6847 slave = dev;
6848 if (!slave)
0f1be195 6849 seq_puts(m, "fail\n");
a01b0c57
AV
6850 else if (slave->ndev)
6851 seq_printf(m, "%s\n", slave->ndev->name);
6852 return 0;
6853}
6854RO_FOPS(bypass_slave)
7040e556 6855
a01b0c57
AV
6856static int show_bypass_caps(struct seq_file *m, void *v)
6857{
efb39e4e 6858 struct bpctl_dev *dev = m->private;
a01b0c57 6859 int ret = get_bypass_caps_fn(dev);
7040e556 6860 if (ret == BP_NOT_CAP)
0f1be195 6861 seq_puts(m, "-1\n");
7040e556 6862 else
a01b0c57
AV
6863 seq_printf(m, "0x%x\n", ret);
6864 return 0;
7040e556 6865}
a01b0c57 6866RO_FOPS(bypass_caps)
7040e556 6867
a01b0c57 6868static int show_wd_set_caps(struct seq_file *m, void *v)
7040e556 6869{
efb39e4e 6870 struct bpctl_dev *dev = m->private;
a01b0c57 6871 int ret = get_wd_set_caps_fn(dev);
7040e556 6872 if (ret == BP_NOT_CAP)
0f1be195 6873 seq_puts(m, "-1\n");
7040e556 6874 else
a01b0c57
AV
6875 seq_printf(m, "0x%x\n", ret);
6876 return 0;
7040e556 6877}
a01b0c57 6878RO_FOPS(wd_set_caps)
7040e556 6879
7e1be8a5 6880static int user_on_off(const void __user *buffer, size_t count)
7040e556
D
6881{
6882
6883 char kbuf[256];
7e1be8a5 6884 int length = 0;
7040e556
D
6885
6886 if (count > (sizeof(kbuf) - 1))
6887 return -1;
6888
7e1be8a5 6889 if (copy_from_user(&kbuf, buffer, count))
7040e556 6890 return -1;
7040e556
D
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)
7e1be8a5
AV
6898 return 1;
6899 if (strcmp(kbuf, "off") == 0)
6900 return 0;
6901 return 0;
7040e556
D
6902}
6903
a01b0c57
AV
6904static ssize_t bypass_write(struct file *file, const char __user *buffer,
6905 size_t count, loff_t *pos)
7040e556 6906{
7e1be8a5
AV
6907 int bypass_param = user_on_off(buffer, count);
6908 if (bypass_param < 0)
7040e556 6909 return -1;
7040e556 6910
d9dda78b 6911 set_bypass_fn(PDE_DATA(file_inode(file)), bypass_param);
7040e556
D
6912 return count;
6913}
a01b0c57 6914static int show_bypass(struct seq_file *m, void *v)
7040e556 6915{
efb39e4e 6916 struct bpctl_dev *dev = m->private;
a01b0c57
AV
6917 int ret = get_bypass_fn(dev);
6918 if (ret == BP_NOT_CAP)
0f1be195 6919 seq_puts(m, "fail\n");
a01b0c57 6920 else if (ret == 1)
0f1be195 6921 seq_puts(m, "on\n");
a01b0c57 6922 else if (ret == 0)
0f1be195 6923 seq_puts(m, "off\n");
a01b0c57 6924 return 0;
7040e556 6925}
a01b0c57 6926RW_FOPS(bypass)
7040e556 6927
a01b0c57
AV
6928static ssize_t tap_write(struct file *file, const char __user *buffer,
6929 size_t count, loff_t *pos)
7040e556 6930{
7e1be8a5
AV
6931 int tap_param = user_on_off(buffer, count);
6932 if (tap_param < 0)
7040e556 6933 return -1;
7040e556 6934
d9dda78b 6935 set_tap_fn(PDE_DATA(file_inode(file)), tap_param);
7040e556
D
6936 return count;
6937}
a01b0c57 6938static int show_tap(struct seq_file *m, void *v)
7040e556 6939{
efb39e4e 6940 struct bpctl_dev *dev = m->private;
a01b0c57 6941 int ret = get_tap_fn(dev);
7040e556 6942 if (ret == BP_NOT_CAP)
0f1be195 6943 seq_puts(m, "fail\n");
7040e556 6944 else if (ret == 1)
0f1be195 6945 seq_puts(m, "on\n");
7040e556 6946 else if (ret == 0)
0f1be195 6947 seq_puts(m, "off\n");
a01b0c57 6948 return 0;
7040e556 6949}
a01b0c57 6950RW_FOPS(tap)
7040e556 6951
a01b0c57
AV
6952static ssize_t disc_write(struct file *file, const char __user *buffer,
6953 size_t count, loff_t *pos)
7040e556 6954{
a01b0c57
AV
6955 int tap_param = user_on_off(buffer, count);
6956 if (tap_param < 0)
6957 return -1;
7040e556 6958
d9dda78b 6959 set_disc_fn(PDE_DATA(file_inode(file)), tap_param);
a01b0c57 6960 return count;
7040e556 6961}
a01b0c57 6962static int show_disc(struct seq_file *m, void *v)
7040e556 6963{
efb39e4e 6964 struct bpctl_dev *dev = m->private;
a01b0c57 6965 int ret = get_disc_fn(dev);
7040e556 6966 if (ret == BP_NOT_CAP)
0f1be195 6967 seq_puts(m, "fail\n");
7040e556 6968 else if (ret == 1)
0f1be195 6969 seq_puts(m, "on\n");
7040e556 6970 else if (ret == 0)
0f1be195 6971 seq_puts(m, "off\n");
a01b0c57 6972 return 0;
7040e556 6973}
a01b0c57 6974RW_FOPS(disc)
7040e556 6975
a01b0c57 6976static int show_bypass_change(struct seq_file *m, void *v)
7040e556 6977{
efb39e4e 6978 struct bpctl_dev *dev = m->private;
a01b0c57 6979 int ret = get_bypass_change_fn(dev);
7040e556 6980 if (ret == 1)
0f1be195 6981 seq_puts(m, "on\n");
7040e556 6982 else if (ret == 0)
0f1be195 6983 seq_puts(m, "off\n");
7040e556 6984 else
0f1be195 6985 seq_puts(m, "fail\n");
a01b0c57 6986 return 0;
7040e556 6987}
a01b0c57 6988RO_FOPS(bypass_change)
7040e556 6989
a01b0c57 6990static int show_tap_change(struct seq_file *m, void *v)
7040e556 6991{
efb39e4e 6992 struct bpctl_dev *dev = m->private;
a01b0c57 6993 int ret = get_tap_change_fn(dev);
7040e556 6994 if (ret == 1)
0f1be195 6995 seq_puts(m, "on\n");
7040e556 6996 else if (ret == 0)
0f1be195 6997 seq_puts(m, "off\n");
7040e556 6998 else
0f1be195 6999 seq_puts(m, "fail\n");
a01b0c57 7000 return 0;
7040e556 7001}
a01b0c57 7002RO_FOPS(tap_change)
7040e556 7003
a01b0c57 7004static int show_disc_change(struct seq_file *m, void *v)
7040e556 7005{
efb39e4e 7006 struct bpctl_dev *dev = m->private;
a01b0c57 7007 int ret = get_disc_change_fn(dev);
7040e556 7008 if (ret == 1)
0f1be195 7009 seq_puts(m, "on\n");
7040e556 7010 else if (ret == 0)
0f1be195 7011 seq_puts(m, "off\n");
7040e556 7012 else
0f1be195 7013 seq_puts(m, "fail\n");
a01b0c57 7014 return 0;
7040e556 7015}
a01b0c57 7016RO_FOPS(disc_change)
7040e556 7017
a01b0c57
AV
7018static ssize_t bypass_wd_write(struct file *file, const char __user *buffer,
7019 size_t count, loff_t *pos)
7040e556 7020{
efb39e4e 7021 struct bpctl_dev *dev = PDE_DATA(file_inode(file));
82e6bb03 7022 int timeout;
a01b0c57 7023 int ret = kstrtoint_from_user(buffer, count, 10, &timeout);
82e6bb03
DC
7024 if (ret)
7025 return ret;
a01b0c57 7026 set_bypass_wd_fn(dev, timeout);
7040e556
D
7027 return count;
7028}
a01b0c57 7029static int show_bypass_wd(struct seq_file *m, void *v)
7040e556 7030{
efb39e4e 7031 struct bpctl_dev *dev = m->private;
a01b0c57 7032 int ret = 0, timeout = 0;
7040e556 7033
a01b0c57 7034 ret = get_bypass_wd_fn(dev, &timeout);
7040e556 7035 if (ret == BP_NOT_CAP)
0f1be195 7036 seq_puts(m, "fail\n");
7040e556 7037 else if (timeout == -1)
0f1be195 7038 seq_puts(m, "unknown\n");
7040e556 7039 else if (timeout == 0)
0f1be195 7040 seq_puts(m, "disable\n");
7040e556 7041 else
a01b0c57
AV
7042 seq_printf(m, "%d\n", timeout);
7043 return 0;
7040e556 7044}
a01b0c57 7045RW_FOPS(bypass_wd)
7040e556 7046
a01b0c57 7047static int show_wd_expire_time(struct seq_file *m, void *v)
7040e556 7048{
efb39e4e 7049 struct bpctl_dev *dev = m->private;
a01b0c57
AV
7050 int ret = 0, timeout = 0;
7051 ret = get_wd_expire_time_fn(dev, &timeout);
7040e556 7052 if (ret == BP_NOT_CAP)
0f1be195 7053 seq_puts(m, "fail\n");
7040e556 7054 else if (timeout == -1)
0f1be195 7055 seq_puts(m, "expire\n");
7040e556 7056 else if (timeout == 0)
0f1be195 7057 seq_puts(m, "disable\n");
7040e556 7058 else
a01b0c57
AV
7059 seq_printf(m, "%d\n", timeout);
7060 return 0;
7040e556 7061}
a01b0c57 7062RO_FOPS(wd_expire_time)
7040e556 7063
a01b0c57
AV
7064static ssize_t tpl_write(struct file *file, const char __user *buffer,
7065 size_t count, loff_t *pos)
7040e556 7066{
efb39e4e 7067 struct bpctl_dev *dev = PDE_DATA(file_inode(file));
a01b0c57
AV
7068 int tpl_param = user_on_off(buffer, count);
7069 if (tpl_param < 0)
7070 return -1;
7040e556 7071
a01b0c57
AV
7072 set_tpl_fn(dev, tpl_param);
7073 return count;
7074}
7075static int show_tpl(struct seq_file *m, void *v)
7076{
efb39e4e 7077 struct bpctl_dev *dev = m->private;
a01b0c57 7078 int ret = get_tpl_fn(dev);
7040e556 7079 if (ret == BP_NOT_CAP)
0f1be195 7080 seq_puts(m, "fail\n");
7040e556 7081 else if (ret == 1)
0f1be195 7082 seq_puts(m, "on\n");
7040e556 7083 else if (ret == 0)
0f1be195 7084 seq_puts(m, "off\n");
a01b0c57 7085 return 0;
7040e556 7086}
a01b0c57 7087RW_FOPS(tpl)
7040e556
D
7088
7089#ifdef PMC_FIX_FLAG
a01b0c57
AV
7090static ssize_t wait_at_pwup_write(struct file *file, const char __user *buffer,
7091 size_t count, loff_t *pos)
7040e556 7092{
efb39e4e 7093 struct bpctl_dev *dev = PDE_DATA(file_inode(file));
a01b0c57
AV
7094 int tpl_param = user_on_off(buffer, count);
7095 if (tpl_param < 0)
7096 return -1;
7040e556 7097
a01b0c57
AV
7098 set_bp_wait_at_pwup_fn(dev, tpl_param);
7099 return count;
7100}
7101static int show_wait_at_pwup(struct seq_file *m, void *v)
7102{
efb39e4e 7103 struct bpctl_dev *dev = m->private;
a01b0c57 7104 int ret = get_bp_wait_at_pwup_fn(dev);
7040e556 7105 if (ret == BP_NOT_CAP)
0f1be195 7106 seq_puts(m, "fail\n");
7040e556 7107 else if (ret == 1)
0f1be195 7108 seq_puts(m, "on\n");
7040e556 7109 else if (ret == 0)
0f1be195 7110 seq_puts(m, "off\n");
a01b0c57 7111 return 0;
7040e556 7112}
a01b0c57 7113RW_FOPS(wait_at_pwup)
7040e556 7114
a01b0c57
AV
7115static ssize_t hw_reset_write(struct file *file, const char __user *buffer,
7116 size_t count, loff_t *pos)
7040e556 7117{
efb39e4e 7118 struct bpctl_dev *dev = PDE_DATA(file_inode(file));
a01b0c57
AV
7119 int tpl_param = user_on_off(buffer, count);
7120 if (tpl_param < 0)
7121 return -1;
7040e556 7122
a01b0c57
AV
7123 set_bp_hw_reset_fn(dev, tpl_param);
7124 return count;
7125}
7126static int show_hw_reset(struct seq_file *m, void *v)
7127{
efb39e4e 7128 struct bpctl_dev *dev = m->private;
a01b0c57 7129 int ret = get_bp_hw_reset_fn(dev);
7040e556 7130 if (ret == BP_NOT_CAP)
0f1be195 7131 seq_puts(m, "fail\n");
7040e556 7132 else if (ret == 1)
0f1be195 7133 seq_puts(m, "on\n");
7040e556 7134 else if (ret == 0)
0f1be195 7135 seq_puts(m, "off\n");
a01b0c57 7136 return 0;
7040e556 7137}
a01b0c57 7138RW_FOPS(hw_reset)
7040e556
D
7139
7140#endif /*PMC_WAIT_FLAG */
7141
a01b0c57 7142static int show_reset_bypass_wd(struct seq_file *m, void *v)
7040e556 7143{
efb39e4e 7144 struct bpctl_dev *dev = m->private;
a01b0c57 7145 int ret = reset_bypass_wd_timer_fn(dev);
7040e556 7146 if (ret == BP_NOT_CAP)
0f1be195 7147 seq_puts(m, "fail\n");
7040e556 7148 else if (ret == 0)
0f1be195 7149 seq_puts(m, "disable\n");
7040e556 7150 else if (ret == 1)
0f1be195 7151 seq_puts(m, "success\n");
a01b0c57 7152 return 0;
7040e556 7153}
a01b0c57 7154RO_FOPS(reset_bypass_wd)
7040e556 7155
a01b0c57
AV
7156static ssize_t dis_bypass_write(struct file *file, const char __user *buffer,
7157 size_t count, loff_t *pos)
7040e556 7158{
7e1be8a5
AV
7159 int bypass_param = user_on_off(buffer, count);
7160 if (bypass_param < 0)
e4c536b7
DC
7161 return -EINVAL;
7162
d9dda78b 7163 set_dis_bypass_fn(PDE_DATA(file_inode(file)), bypass_param);
7040e556
D
7164 return count;
7165}
a01b0c57 7166static int show_dis_bypass(struct seq_file *m, void *v)
7040e556 7167{
efb39e4e 7168 struct bpctl_dev *dev = m->private;
a01b0c57
AV
7169 int ret = get_dis_bypass_fn(dev);
7170 if (ret == BP_NOT_CAP)
0f1be195 7171 seq_puts(m, "fail\n");
a01b0c57 7172 else if (ret == 0)
0f1be195 7173 seq_puts(m, "off\n");
a01b0c57 7174 else
0f1be195 7175 seq_puts(m, "on\n");
a01b0c57 7176 return 0;
7040e556 7177}
a01b0c57 7178RW_FOPS(dis_bypass)
7040e556 7179
a01b0c57
AV
7180static ssize_t dis_tap_write(struct file *file, const char __user *buffer,
7181 size_t count, loff_t *pos)
7040e556 7182{
7e1be8a5
AV
7183 int tap_param = user_on_off(buffer, count);
7184 if (tap_param < 0)
e4c536b7
DC
7185 return -EINVAL;
7186
d9dda78b 7187 set_dis_tap_fn(PDE_DATA(file_inode(file)), tap_param);
7040e556
D
7188 return count;
7189}
a01b0c57 7190static int show_dis_tap(struct seq_file *m, void *v)
7040e556 7191{
efb39e4e 7192 struct bpctl_dev *dev = m->private;
a01b0c57 7193 int ret = get_dis_tap_fn(dev);
7040e556 7194 if (ret == BP_NOT_CAP)
0f1be195 7195 seq_puts(m, "fail\n");
7040e556 7196 else if (ret == 0)
0f1be195 7197 seq_puts(m, "off\n");
7040e556 7198 else
0f1be195 7199 seq_puts(m, "on\n");
a01b0c57 7200 return 0;
7040e556 7201}
a01b0c57 7202RW_FOPS(dis_tap)
7040e556 7203
a01b0c57
AV
7204static ssize_t dis_disc_write(struct file *file, const char __user *buffer,
7205 size_t count, loff_t *pos)
7040e556 7206{
a01b0c57
AV
7207 int tap_param = user_on_off(buffer, count);
7208 if (tap_param < 0)
7209 return -EINVAL;
7040e556 7210
d9dda78b 7211 set_dis_disc_fn(PDE_DATA(file_inode(file)), tap_param);
a01b0c57 7212 return count;
7040e556 7213}
a01b0c57 7214static int show_dis_disc(struct seq_file *m, void *v)
7040e556 7215{
efb39e4e 7216 struct bpctl_dev *dev = m->private;
a01b0c57 7217 int ret = get_dis_disc_fn(dev);
7040e556 7218 if (ret == BP_NOT_CAP)
0f1be195 7219 seq_puts(m, "fail\n");
7040e556 7220 else if (ret == 0)
0f1be195 7221 seq_puts(m, "off\n");
7040e556 7222 else
0f1be195 7223 seq_puts(m, "on\n");
a01b0c57 7224 return 0;
7040e556 7225}
a01b0c57 7226RW_FOPS(dis_disc)
7040e556 7227
a01b0c57
AV
7228static ssize_t bypass_pwup_write(struct file *file, const char __user *buffer,
7229 size_t count, loff_t *pos)
7040e556 7230{
7e1be8a5
AV
7231 int bypass_param = user_on_off(buffer, count);
7232 if (bypass_param < 0)
e4c536b7
DC
7233 return -EINVAL;
7234
d9dda78b 7235 set_bypass_pwup_fn(PDE_DATA(file_inode(file)), bypass_param);
7040e556
D
7236 return count;
7237}
a01b0c57 7238static int show_bypass_pwup(struct seq_file *m, void *v)
7040e556 7239{
efb39e4e 7240 struct bpctl_dev *dev = m->private;
a01b0c57
AV
7241 int ret = get_bypass_pwup_fn(dev);
7242 if (ret == BP_NOT_CAP)
0f1be195 7243 seq_puts(m, "fail\n");
a01b0c57 7244 else if (ret == 0)
0f1be195 7245 seq_puts(m, "off\n");
a01b0c57 7246 else
0f1be195 7247 seq_puts(m, "on\n");
a01b0c57 7248 return 0;
7040e556 7249}
a01b0c57 7250RW_FOPS(bypass_pwup)
7040e556 7251
a01b0c57
AV
7252static ssize_t bypass_pwoff_write(struct file *file, const char __user *buffer,
7253 size_t count, loff_t *pos)
7040e556 7254{
7e1be8a5
AV
7255 int bypass_param = user_on_off(buffer, count);
7256 if (bypass_param < 0)
e4c536b7
DC
7257 return -EINVAL;
7258
d9dda78b 7259 set_bypass_pwoff_fn(PDE_DATA(file_inode(file)), bypass_param);
7040e556
D
7260 return count;
7261}
a01b0c57 7262static int show_bypass_pwoff(struct seq_file *m, void *v)
7040e556 7263{
efb39e4e 7264 struct bpctl_dev *dev = m->private;
a01b0c57 7265 int ret = get_bypass_pwoff_fn(dev);
7040e556 7266 if (ret == BP_NOT_CAP)
0f1be195 7267 seq_puts(m, "fail\n");
7040e556 7268 else if (ret == 0)
0f1be195 7269 seq_puts(m, "off\n");
7040e556 7270 else
0f1be195 7271 seq_puts(m, "on\n");
a01b0c57 7272 return 0;
7040e556 7273}
a01b0c57 7274RW_FOPS(bypass_pwoff)
7040e556 7275
a01b0c57
AV
7276static ssize_t tap_pwup_write(struct file *file, const char __user *buffer,
7277 size_t count, loff_t *pos)
7040e556 7278{
7e1be8a5
AV
7279 int tap_param = user_on_off(buffer, count);
7280 if (tap_param < 0)
e4c536b7 7281 return -EINVAL;
7040e556 7282
d9dda78b 7283 set_tap_pwup_fn(PDE_DATA(file_inode(file)), tap_param);
7040e556 7284 return count;
7040e556 7285}
a01b0c57 7286static int show_tap_pwup(struct seq_file *m, void *v)
7040e556 7287{
efb39e4e 7288 struct bpctl_dev *dev = m->private;
a01b0c57 7289 int ret = get_tap_pwup_fn(dev);
7040e556 7290 if (ret == BP_NOT_CAP)
0f1be195 7291 seq_puts(m, "fail\n");
7040e556 7292 else if (ret == 0)
0f1be195 7293 seq_puts(m, "off\n");
7040e556 7294 else
0f1be195 7295 seq_puts(m, "on\n");
a01b0c57 7296 return 0;
7040e556 7297}
a01b0c57 7298RW_FOPS(tap_pwup)
7040e556 7299
a01b0c57
AV
7300static ssize_t disc_pwup_write(struct file *file, const char __user *buffer,
7301 size_t count, loff_t *pos)
7040e556 7302{
a01b0c57
AV
7303 int tap_param = user_on_off(buffer, count);
7304 if (tap_param < 0)
7305 return -EINVAL;
7040e556 7306
d9dda78b 7307 set_disc_pwup_fn(PDE_DATA(file_inode(file)), tap_param);
a01b0c57 7308 return count;
7040e556 7309}
a01b0c57 7310static int show_disc_pwup(struct seq_file *m, void *v)
7040e556 7311{
efb39e4e 7312 struct bpctl_dev *dev = m->private;
a01b0c57 7313 int ret = get_disc_pwup_fn(dev);
7040e556 7314 if (ret == BP_NOT_CAP)
0f1be195 7315 seq_puts(m, "fail\n");
7040e556 7316 else if (ret == 0)
0f1be195 7317 seq_puts(m, "off\n");
7040e556 7318 else
0f1be195 7319 seq_puts(m, "on\n");
a01b0c57 7320 return 0;
7040e556 7321}
a01b0c57 7322RW_FOPS(disc_pwup)
7040e556 7323
a01b0c57
AV
7324static ssize_t std_nic_write(struct file *file, const char __user *buffer,
7325 size_t count, loff_t *pos)
7040e556 7326{
7e1be8a5
AV
7327 int bypass_param = user_on_off(buffer, count);
7328 if (bypass_param < 0)
e4c536b7
DC
7329 return -EINVAL;
7330
d9dda78b 7331 set_std_nic_fn(PDE_DATA(file_inode(file)), bypass_param);
7040e556
D
7332 return count;
7333}
a01b0c57 7334static int show_std_nic(struct seq_file *m, void *v)
7040e556 7335{
efb39e4e 7336 struct bpctl_dev *dev = m->private;
a01b0c57 7337 int ret = get_std_nic_fn(dev);
7040e556 7338 if (ret == BP_NOT_CAP)
0f1be195 7339 seq_puts(m, "fail\n");
7040e556 7340 else if (ret == 0)
0f1be195 7341 seq_puts(m, "off\n");
7040e556 7342 else
0f1be195 7343 seq_puts(m, "on\n");
a01b0c57 7344 return 0;
7040e556 7345}
a01b0c57 7346RW_FOPS(std_nic)
7040e556 7347
a01b0c57
AV
7348static ssize_t wd_exp_mode_write(struct file *file, const char __user *buffer,
7349 size_t count, loff_t *pos)
7040e556 7350{
7040e556 7351 char kbuf[256];
7040e556
D
7352 int bypass_param = 0, length = 0;
7353
7354 if (count > (sizeof(kbuf) - 1))
7355 return -1;
7356
a01b0c57 7357 if (copy_from_user(&kbuf, buffer, count))
7040e556 7358 return -1;
7040e556
D
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
d9dda78b 7372 set_wd_exp_mode_fn(PDE_DATA(file_inode(file)), bypass_param);
7040e556
D
7373
7374 return count;
7375}
a01b0c57 7376static int show_wd_exp_mode(struct seq_file *m, void *v)
7040e556 7377{
efb39e4e 7378 struct bpctl_dev *dev = m->private;
a01b0c57
AV
7379 int ret = get_wd_exp_mode_fn(dev);
7380 if (ret == 1)
0f1be195 7381 seq_puts(m, "tap\n");
a01b0c57 7382 else if (ret == 0)
0f1be195 7383 seq_puts(m, "bypass\n");
a01b0c57 7384 else if (ret == 2)
0f1be195 7385 seq_puts(m, "disc\n");
7040e556 7386 else
0f1be195 7387 seq_puts(m, "fail\n");
a01b0c57 7388 return 0;
7040e556 7389}
a01b0c57 7390RW_FOPS(wd_exp_mode)
7040e556 7391
a01b0c57
AV
7392static ssize_t wd_autoreset_write(struct file *file, const char __user *buffer,
7393 size_t count, loff_t *pos)
7040e556 7394{
82e6bb03 7395 int timeout;
a01b0c57 7396 int ret = kstrtoint_from_user(buffer, count, 10, &timeout);
82e6bb03
DC
7397 if (ret)
7398 return ret;
d9dda78b 7399 set_wd_autoreset_fn(PDE_DATA(file_inode(file)), timeout);
7040e556
D
7400 return count;
7401}
a01b0c57 7402static int show_wd_autoreset(struct seq_file *m, void *v)
7040e556 7403{
efb39e4e 7404 struct bpctl_dev *dev = m->private;
a01b0c57
AV
7405 int ret = get_wd_autoreset_fn(dev);
7406 if (ret >= 0)
7407 seq_printf(m, "%d\n", ret);
7408 else
0f1be195 7409 seq_puts(m, "fail\n");
a01b0c57 7410 return 0;
7040e556 7411}
a01b0c57 7412RW_FOPS(wd_autoreset)
7040e556 7413
4624b543 7414static int bypass_proc_create_dev_sd(struct bpctl_dev *pbp_device_block)
7040e556
D
7415{
7416 struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set);
f84b0751 7417 static struct proc_dir_entry *procfs_dir;
7040e556
D
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 */
a01b0c57
AV
7429 procfs_dir = proc_mkdir(current_pfs->dir_name, bp_procfs_dir);
7430 if (!procfs_dir) {
7040e556
D
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
27a9095a
LH
7437#define ENTRY(x) (ret |= procfs_add(#x, &x##_ops, pbp_device_block))
7438
a01b0c57 7439 ENTRY(bypass_info);
7040e556 7440 if (pbp_device_block->bp_caps & SW_CTL_CAP) {
7040e556 7441 /* Create set param proc's */
a01b0c57
AV
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);
7040e556 7449 if (pbp_device_block->bp_caps & BP_CAP) {
a01b0c57
AV
7450 ENTRY(bypass);
7451 ENTRY(dis_bypass);
7452 ENTRY(bypass_pwup);
7453 ENTRY(bypass_pwoff);
7454 ENTRY(bypass_change);
7040e556 7455 }
7040e556 7456 if (pbp_device_block->bp_caps & TAP_CAP) {
a01b0c57
AV
7457 ENTRY(tap);
7458 ENTRY(dis_tap);
7459 ENTRY(tap_pwup);
7460 ENTRY(tap_change);
7040e556
D
7461 }
7462 if (pbp_device_block->bp_caps & DISC_CAP) {
a01b0c57
AV
7463 ENTRY(disc);
7464 ENTRY(dis_disc);
7465 ENTRY(disc_pwup);
7466 ENTRY(disc_change);
7040e556
D
7467 }
7468
a01b0c57
AV
7469 ENTRY(wd_exp_mode);
7470 ENTRY(wd_autoreset);
7471 ENTRY(tpl);
7040e556 7472#ifdef PMC_FIX_FLAG
a01b0c57
AV
7473 ENTRY(wait_at_pwup);
7474 ENTRY(hw_reset);
7040e556 7475#endif
7040e556 7476 }
a01b0c57 7477#undef ENTRY
7040e556
D
7478 if (ret < 0)
7479 printk(KERN_DEBUG "Create proc entry failed\n");
7480
7481 return ret;
7482}
7483
4624b543 7484static int bypass_proc_remove_dev_sd(struct bpctl_dev *pbp_device_block)
7040e556
D
7485{
7486
7487 struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set;
a01b0c57 7488 remove_proc_subtree(current_pfs->dir_name, bp_procfs_dir);
7040e556 7489 current_pfs->bypass_entry = NULL;
7040e556
D
7490 return 0;
7491}