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