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