| /******************************************************************************/ |
| /* */ |
| /* Bypass Control utility, Copyright (c) 2005-20011 Silicom */ |
| /* */ |
| /* This program is free software; you can redistribute it and/or modify */ |
| /* it under the terms of the GNU General Public License as published by */ |
| /* the Free Software Foundation, located in the file LICENSE. */ |
| /* Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. */ |
| /* */ |
| /* */ |
| /******************************************************************************/ |
| |
| #include <linux/kernel.h> /* We're doing kernel work */ |
| #include <linux/module.h> /* Specifically, a module */ |
| #include <linux/fs.h> |
| #include <linux/pci.h> |
| #include <linux/delay.h> |
| #include <linux/netdevice.h> |
| #include <linux/rtnetlink.h> |
| #include <linux/rcupdate.h> |
| #include <linux/etherdevice.h> |
| |
| #include <linux/uaccess.h> /* for get_user and put_user */ |
| #include <linux/sched.h> |
| #include <linux/ethtool.h> |
| #include <linux/proc_fs.h> |
| |
| #include "bp_ioctl.h" |
| #include "bp_mod.h" |
| #include "bypass.h" |
| #include "libbp_sd.h" |
| |
| #define SUCCESS 0 |
| #define BP_MOD_VER "9.0.4" |
| #define BP_MOD_DESCR "Silicom Bypass-SD Control driver" |
| #define BP_SYNC_FLAG 1 |
| |
| static int major_num = 0; |
| |
| MODULE_AUTHOR("Anna Lukin, annal@silicom.co.il"); |
| MODULE_LICENSE("GPL"); |
| MODULE_DESCRIPTION(BP_MOD_DESCR); |
| MODULE_VERSION(BP_MOD_VER); |
| spinlock_t bpvm_lock; |
| |
| #define lock_bpctl() \ |
| if (down_interruptible(&bpctl_sema)) { \ |
| return -ERESTARTSYS; \ |
| } \ |
| |
| #define unlock_bpctl() \ |
| up(&bpctl_sema); |
| |
| /* Media Types */ |
| typedef enum { |
| bp_copper = 0, |
| bp_fiber, |
| bp_cx4, |
| bp_none, |
| } bp_media_type; |
| |
| struct bypass_pfs_sd { |
| char dir_name[32]; |
| struct proc_dir_entry *bypass_entry; |
| }; |
| |
| typedef struct _bpctl_dev { |
| char *name; |
| char *desc; |
| struct pci_dev *pdev; /* PCI device */ |
| struct net_device *ndev; /* net device */ |
| unsigned long mem_map; |
| uint8_t bus; |
| uint8_t slot; |
| uint8_t func; |
| u_int32_t device; |
| u_int32_t vendor; |
| u_int32_t subvendor; |
| u_int32_t subdevice; |
| int ifindex; |
| uint32_t bp_caps; |
| uint32_t bp_caps_ex; |
| uint8_t bp_fw_ver; |
| int bp_ext_ver; |
| int wdt_status; |
| unsigned long bypass_wdt_on_time; |
| uint32_t bypass_timer_interval; |
| struct timer_list bp_timer; |
| uint32_t reset_time; |
| uint8_t bp_status_un; |
| atomic_t wdt_busy; |
| bp_media_type media_type; |
| int bp_tpl_flag; |
| struct timer_list bp_tpl_timer; |
| spinlock_t bypass_wr_lock; |
| int bp_10g; |
| int bp_10gb; |
| int bp_fiber5; |
| int bp_10g9; |
| int bp_i80; |
| int bp_540; |
| int (*hard_start_xmit_save) (struct sk_buff *skb, |
| struct net_device *dev); |
| const struct net_device_ops *old_ops; |
| struct net_device_ops new_ops; |
| int bp_self_test_flag; |
| char *bp_tx_data; |
| struct bypass_pfs_sd bypass_pfs_set; |
| |
| } bpctl_dev_t; |
| |
| static bpctl_dev_t *bpctl_dev_arr; |
| |
| static struct semaphore bpctl_sema; |
| static int device_num = 0; |
| |
| static int get_dev_idx(int ifindex); |
| static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev); |
| static int disc_status(bpctl_dev_t *pbpctl_dev); |
| static int bypass_status(bpctl_dev_t *pbpctl_dev); |
| static int wdt_timer(bpctl_dev_t *pbpctl_dev, int *time_left); |
| static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev); |
| static void if_scan_init(void); |
| |
| int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block); |
| int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block); |
| int bp_proc_create(void); |
| |
| int is_bypass_fn(bpctl_dev_t *pbpctl_dev); |
| int get_dev_idx_bsf(int bus, int slot, int func); |
| |
| static unsigned long str_to_hex(char *p); |
| static int bp_device_event(struct notifier_block *unused, |
| unsigned long event, void *ptr) |
| { |
| struct net_device *dev = ptr; |
| static bpctl_dev_t *pbpctl_dev = NULL, *pbpctl_dev_m = NULL; |
| int dev_num = 0, ret = 0, ret_d = 0, time_left = 0; |
| /* printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); */ |
| /* return NOTIFY_DONE; */ |
| if (!dev) |
| return NOTIFY_DONE; |
| if (event == NETDEV_REGISTER) { |
| { |
| struct ethtool_drvinfo drvinfo; |
| char cbuf[32]; |
| char *buf = NULL; |
| char res[10]; |
| int i = 0, ifindex, idx_dev = 0; |
| int bus = 0, slot = 0, func = 0; |
| ifindex = dev->ifindex; |
| |
| memset(res, 0, 10); |
| memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo)); |
| |
| if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) { |
| memset(&drvinfo, 0, sizeof(drvinfo)); |
| dev->ethtool_ops->get_drvinfo(dev, &drvinfo); |
| } else |
| return NOTIFY_DONE; |
| if (!drvinfo.bus_info) |
| return NOTIFY_DONE; |
| if (!strcmp(drvinfo.bus_info, "N/A")) |
| return NOTIFY_DONE; |
| memcpy(&cbuf, drvinfo.bus_info, 32); |
| buf = &cbuf[0]; |
| |
| while (*buf++ != ':') ; |
| for (i = 0; i < 10; i++, buf++) { |
| if (*buf == ':') |
| break; |
| res[i] = *buf; |
| |
| } |
| buf++; |
| bus = str_to_hex(res); |
| memset(res, 0, 10); |
| |
| for (i = 0; i < 10; i++, buf++) { |
| if (*buf == '.') |
| break; |
| res[i] = *buf; |
| |
| } |
| buf++; |
| slot = str_to_hex(res); |
| func = str_to_hex(buf); |
| idx_dev = get_dev_idx_bsf(bus, slot, func); |
| |
| if (idx_dev != -1) { |
| |
| bpctl_dev_arr[idx_dev].ifindex = ifindex; |
| bpctl_dev_arr[idx_dev].ndev = dev; |
| |
| bypass_proc_remove_dev_sd(&bpctl_dev_arr |
| [idx_dev]); |
| bypass_proc_create_dev_sd(&bpctl_dev_arr |
| [idx_dev]); |
| |
| } |
| |
| } |
| return NOTIFY_DONE; |
| |
| } |
| if (event == NETDEV_UNREGISTER) { |
| int idx_dev = 0; |
| for (idx_dev = 0; |
| ((bpctl_dev_arr[idx_dev].pdev != NULL) |
| && (idx_dev < device_num)); idx_dev++) { |
| if (bpctl_dev_arr[idx_dev].ndev == dev) { |
| bypass_proc_remove_dev_sd(&bpctl_dev_arr |
| [idx_dev]); |
| bpctl_dev_arr[idx_dev].ndev = NULL; |
| |
| return NOTIFY_DONE; |
| |
| } |
| |
| } |
| return NOTIFY_DONE; |
| } |
| if (event == NETDEV_CHANGENAME) { |
| int idx_dev = 0; |
| for (idx_dev = 0; |
| ((bpctl_dev_arr[idx_dev].pdev != NULL) |
| && (idx_dev < device_num)); idx_dev++) { |
| if (bpctl_dev_arr[idx_dev].ndev == dev) { |
| bypass_proc_remove_dev_sd(&bpctl_dev_arr |
| [idx_dev]); |
| bypass_proc_create_dev_sd(&bpctl_dev_arr |
| [idx_dev]); |
| |
| return NOTIFY_DONE; |
| |
| } |
| |
| } |
| return NOTIFY_DONE; |
| |
| } |
| |
| switch (event) { |
| |
| case NETDEV_CHANGE:{ |
| if (netif_carrier_ok(dev)) |
| return NOTIFY_DONE; |
| |
| if (((dev_num = get_dev_idx(dev->ifindex)) == -1) || |
| (!(pbpctl_dev = &bpctl_dev_arr[dev_num]))) |
| return NOTIFY_DONE; |
| |
| if ((is_bypass_fn(pbpctl_dev)) == 1) |
| pbpctl_dev_m = pbpctl_dev; |
| else |
| pbpctl_dev_m = get_master_port_fn(pbpctl_dev); |
| if (!pbpctl_dev_m) |
| return NOTIFY_DONE; |
| ret = bypass_status(pbpctl_dev_m); |
| if (ret == 1) |
| printk("bpmod: %s is in the Bypass mode now", |
| dev->name); |
| ret_d = disc_status(pbpctl_dev_m); |
| if (ret_d == 1) |
| printk |
| ("bpmod: %s is in the Disconnect mode now", |
| dev->name); |
| if (ret || ret_d) { |
| wdt_timer(pbpctl_dev_m, &time_left); |
| if (time_left == -1) |
| printk("; WDT has expired"); |
| printk(".\n"); |
| |
| } |
| return NOTIFY_DONE; |
| |
| } |
| |
| default: |
| return NOTIFY_DONE; |
| |
| } |
| return NOTIFY_DONE; |
| |
| } |
| |
| static struct notifier_block bp_notifier_block = { |
| .notifier_call = bp_device_event, |
| }; |
| |
| int is_bypass_fn(bpctl_dev_t *pbpctl_dev); |
| int wdt_time_left(bpctl_dev_t *pbpctl_dev); |
| |
| static void write_pulse(bpctl_dev_t *pbpctl_dev, |
| unsigned int ctrl_ext, |
| unsigned char value, unsigned char len) |
| { |
| unsigned char ctrl_val = 0; |
| unsigned int i = len; |
| unsigned int ctrl = 0; |
| bpctl_dev_t *pbpctl_dev_c = NULL; |
| |
| if (pbpctl_dev->bp_i80) |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| if (pbpctl_dev->bp_540) |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| |
| if (pbpctl_dev->bp_10g9) { |
| if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev))) |
| return; |
| ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); |
| } |
| |
| while (i--) { |
| ctrl_val = (value >> i) & 0x1; |
| if (ctrl_val) { |
| if (pbpctl_dev->bp_10g9) { |
| |
| /* To start management : MCLK 1, MDIO 1, output */ |
| /* DATA 1 CLK 1 */ |
| /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| ctrl_ext | |
| BP10G_MDIO_DATA_OUT9); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| (ctrl | BP10G_MCLK_DATA_OUT9 | |
| BP10G_MCLK_DIR_OUT9)); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DATA5 |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA5)); |
| |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext | |
| BPCTLI_CTRL_EXT_MDIO_DIR80 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DATA80)); |
| |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, (ctrl | |
| BPCTLI_CTRL_EXT_MCLK_DIR80 |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA80)); |
| |
| } else if (pbpctl_dev->bp_540) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl | |
| BP540_MDIO_DIR |
| | |
| BP540_MDIO_DATA |
| | |
| BP540_MCLK_DIR |
| | |
| BP540_MCLK_DATA)); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_SET | |
| BP10GB_MCLK_SET) & |
| ~(BP10GB_MCLK_DIR | |
| BP10GB_MDIO_DIR | |
| BP10GB_MDIO_CLR | |
| BP10GB_MCLK_CLR)); |
| |
| } else if (!pbpctl_dev->bp_10g) |
| /* To start management : MCLK 1, MDIO 1, output */ |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| (ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR | |
| BPCTLI_CTRL_EXT_MDIO_DIR | |
| BPCTLI_CTRL_EXT_MDIO_DATA | |
| BPCTLI_CTRL_EXT_MCLK_DATA)); |
| else { |
| |
| /* To start management : MCLK 1, MDIO 1, output*/ |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| (ctrl_ext | BP10G_MCLK_DATA_OUT |
| | BP10G_MDIO_DATA_OUT)); |
| |
| } |
| |
| usec_delay(PULSE_TIME); |
| if (pbpctl_dev->bp_10g9) { |
| |
| /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MDIO_DATA_OUT9)&~(BP10G_MCLK_DATA_OUT9))); */ |
| /* DATA 1 CLK 0 */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| ctrl_ext | |
| BP10G_MDIO_DATA_OUT9); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| (ctrl | BP10G_MCLK_DIR_OUT9) & |
| ~BP10G_MCLK_DATA_OUT9); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 | |
| BPCTLI_CTRL_EXT_MDIO_DIR5 | |
| BPCTLI_CTRL_EXT_MDIO_DATA5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MCLK_DATA5))); |
| |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, (ctrl_ext | |
| BPCTLI_CTRL_EXT_MDIO_DIR80 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DATA80)); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl | |
| BPCTLI_CTRL_EXT_MCLK_DIR80) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MCLK_DATA80))); |
| |
| } else if (pbpctl_dev->bp_540) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| (ctrl | BP540_MDIO_DIR | |
| BP540_MDIO_DATA | |
| BP540_MCLK_DIR) & |
| ~(BP540_MCLK_DATA)); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_SET | |
| BP10GB_MCLK_CLR) & |
| ~(BP10GB_MCLK_DIR | |
| BP10GB_MDIO_DIR | |
| BP10GB_MDIO_CLR | |
| BP10GB_MCLK_SET)); |
| |
| } else if (!pbpctl_dev->bp_10g) |
| |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR | |
| BPCTLI_CTRL_EXT_MDIO_DIR | |
| BPCTLI_CTRL_EXT_MDIO_DATA) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MCLK_DATA))); |
| else { |
| |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| ((ctrl_ext | |
| BP10G_MDIO_DATA_OUT) & |
| ~(BP10G_MCLK_DATA_OUT))); |
| } |
| |
| usec_delay(PULSE_TIME); |
| |
| } else { |
| if (pbpctl_dev->bp_10g9) { |
| /* DATA 0 CLK 1 */ |
| /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MCLK_DATA_OUT9)&~BP10G_MDIO_DATA_OUT9)); */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| (ctrl_ext & |
| ~BP10G_MDIO_DATA_OUT9)); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| (ctrl | BP10G_MCLK_DATA_OUT9 | |
| BP10G_MCLK_DIR_OUT9)); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 | |
| BPCTLI_CTRL_EXT_MDIO_DIR5 | |
| BPCTLI_CTRL_EXT_MCLK_DATA5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA5))); |
| |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MDIO_DIR80) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA80))); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| (ctrl | |
| BPCTLI_CTRL_EXT_MCLK_DIR80 | |
| BPCTLI_CTRL_EXT_MCLK_DATA80)); |
| |
| } else if (pbpctl_dev->bp_540) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| ((ctrl | BP540_MCLK_DIR | |
| BP540_MCLK_DATA | |
| BP540_MDIO_DIR) & |
| ~(BP540_MDIO_DATA))); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_CLR | |
| BP10GB_MCLK_SET) & |
| ~(BP10GB_MCLK_DIR | |
| BP10GB_MDIO_DIR | |
| BP10GB_MDIO_SET | |
| BP10GB_MCLK_CLR)); |
| |
| } else if (!pbpctl_dev->bp_10g) |
| |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR | |
| BPCTLI_CTRL_EXT_MDIO_DIR | |
| BPCTLI_CTRL_EXT_MCLK_DATA) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA))); |
| else { |
| |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| ((ctrl_ext | |
| BP10G_MCLK_DATA_OUT) & |
| ~BP10G_MDIO_DATA_OUT)); |
| |
| } |
| usec_delay(PULSE_TIME); |
| if (pbpctl_dev->bp_10g9) { |
| /* DATA 0 CLK 0 */ |
| /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| (ctrl_ext & |
| ~BP10G_MDIO_DATA_OUT9)); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| ((ctrl | BP10G_MCLK_DIR_OUT9) & |
| ~(BP10G_MCLK_DATA_OUT9))); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 | |
| BPCTLI_CTRL_EXT_MDIO_DIR5) |
| & |
| ~(BPCTLI_CTRL_EXT_MCLK_DATA5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DATA5))); |
| |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MDIO_DIR80) |
| & |
| ~BPCTLI_CTRL_EXT_MDIO_DATA80)); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl | |
| BPCTLI_CTRL_EXT_MCLK_DIR80) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MCLK_DATA80))); |
| |
| } else if (pbpctl_dev->bp_540) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| ((ctrl | BP540_MCLK_DIR | |
| BP540_MDIO_DIR) & |
| ~(BP540_MDIO_DATA | |
| BP540_MCLK_DATA))); |
| } else if (pbpctl_dev->bp_10gb) { |
| |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_CLR | |
| BP10GB_MCLK_CLR) & |
| ~(BP10GB_MCLK_DIR | |
| BP10GB_MDIO_DIR | |
| BP10GB_MDIO_SET | |
| BP10GB_MCLK_SET)); |
| |
| } else if (!pbpctl_dev->bp_10g) |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR | |
| BPCTLI_CTRL_EXT_MDIO_DIR) & |
| ~(BPCTLI_CTRL_EXT_MCLK_DATA |
| | |
| BPCTLI_CTRL_EXT_MDIO_DATA))); |
| else { |
| |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| (ctrl_ext & |
| ~(BP10G_MCLK_DATA_OUT | |
| BP10G_MDIO_DATA_OUT))); |
| } |
| |
| usec_delay(PULSE_TIME); |
| } |
| |
| } |
| } |
| |
| static int read_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext, |
| unsigned char len) |
| { |
| unsigned char ctrl_val = 0; |
| unsigned int i = len; |
| unsigned int ctrl = 0; |
| bpctl_dev_t *pbpctl_dev_c = NULL; |
| |
| if (pbpctl_dev->bp_i80) |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| if (pbpctl_dev->bp_540) |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| if (pbpctl_dev->bp_10g9) { |
| if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev))) |
| return -1; |
| ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); |
| } |
| |
| |
| while (i--) { |
| if (pbpctl_dev->bp_10g9) { |
| /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MDIO_DATA_OUT9)&~BP10G_MCLK_DATA_OUT9)); */ |
| /* DATA ? CLK 0 */ |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| ((ctrl | BP10G_MCLK_DIR_OUT9) & |
| ~(BP10G_MCLK_DATA_OUT9))); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA5))); |
| |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| (ctrl_ext & |
| ~BPCTLI_CTRL_EXT_MDIO_DIR80)); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) |
| & ~(BPCTLI_CTRL_EXT_MCLK_DATA80))); |
| |
| } else if (pbpctl_dev->bp_540) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| ((ctrl | BP540_MCLK_DIR) & |
| ~(BP540_MDIO_DIR | BP540_MCLK_DATA))); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_DIR | |
| BP10GB_MCLK_CLR) & ~(BP10GB_MCLK_DIR | |
| BP10GB_MDIO_CLR | |
| BP10GB_MDIO_SET | |
| BP10GB_MCLK_SET)); |
| |
| } else if (!pbpctl_dev->bp_10g) |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DIR |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA))); |
| else { |
| |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, ((ctrl_ext | BP10G_MDIO_DATA_OUT) & ~BP10G_MCLK_DATA_OUT)); /* ? */ |
| /* printk("0x28=0x%x\n",BP10G_READ_REG(pbpctl_dev,EODSDP);); */ |
| |
| } |
| |
| usec_delay(PULSE_TIME); |
| if (pbpctl_dev->bp_10g9) { |
| /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */ |
| /* DATA ? CLK 1 */ |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| (ctrl | BP10G_MCLK_DATA_OUT9 | |
| BP10G_MCLK_DIR_OUT9)); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DIR5))); |
| |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| (ctrl_ext & |
| ~(BPCTLI_CTRL_EXT_MDIO_DIR80))); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 | |
| BPCTLI_CTRL_EXT_MCLK_DATA80)); |
| |
| } else if (pbpctl_dev->bp_540) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| ((ctrl | BP540_MCLK_DIR | |
| BP540_MCLK_DATA) & |
| ~(BP540_MDIO_DIR))); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_DIR | |
| BP10GB_MCLK_SET) & ~(BP10GB_MCLK_DIR | |
| BP10GB_MDIO_CLR | |
| BP10GB_MDIO_SET | |
| BP10GB_MCLK_CLR)); |
| |
| } else if (!pbpctl_dev->bp_10g) |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DIR))); |
| else { |
| |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| (ctrl_ext | BP10G_MCLK_DATA_OUT | |
| BP10G_MDIO_DATA_OUT)); |
| |
| } |
| if (pbpctl_dev->bp_10g9) { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL); |
| |
| } else if ((pbpctl_dev->bp_fiber5) || (pbpctl_dev->bp_i80)) { |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| } else if (pbpctl_dev->bp_540) { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP); |
| } else if (pbpctl_dev->bp_10gb) |
| ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); |
| |
| else if (!pbpctl_dev->bp_10g) |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| else |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); |
| |
| usec_delay(PULSE_TIME); |
| if (pbpctl_dev->bp_10g9) { |
| if (ctrl_ext & BP10G_MDIO_DATA_IN9) |
| ctrl_val |= 1 << i; |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA5) |
| ctrl_val |= 1 << i; |
| } else if (pbpctl_dev->bp_i80) { |
| if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA80) |
| ctrl_val |= 1 << i; |
| } else if (pbpctl_dev->bp_540) { |
| if (ctrl_ext & BP540_MDIO_DATA) |
| ctrl_val |= 1 << i; |
| } else if (pbpctl_dev->bp_10gb) { |
| if (ctrl_ext & BP10GB_MDIO_DATA) |
| ctrl_val |= 1 << i; |
| |
| } else if (!pbpctl_dev->bp_10g) { |
| |
| if (ctrl_ext & BPCTLI_CTRL_EXT_MDIO_DATA) |
| ctrl_val |= 1 << i; |
| } else { |
| |
| if (ctrl_ext & BP10G_MDIO_DATA_IN) |
| ctrl_val |= 1 << i; |
| } |
| |
| } |
| |
| return ctrl_val; |
| } |
| |
| static void write_reg(bpctl_dev_t *pbpctl_dev, unsigned char value, |
| unsigned char addr) |
| { |
| uint32_t ctrl_ext = 0, ctrl = 0; |
| bpctl_dev_t *pbpctl_dev_c = NULL; |
| unsigned long flags; |
| if (pbpctl_dev->bp_10g9) { |
| if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev))) |
| return; |
| } |
| if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) && |
| (pbpctl_dev->bp_ext_ver < PXG4BPFI_VER)) |
| wdt_time_left(pbpctl_dev); |
| |
| #ifdef BP_SYNC_FLAG |
| spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); |
| #else |
| atomic_set(&pbpctl_dev->wdt_busy, 1); |
| #endif |
| if (pbpctl_dev->bp_10g9) { |
| |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL); |
| ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); |
| /* DATA 0 CLK 0 */ |
| /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| ((ctrl | BP10G_MCLK_DIR_OUT9) & |
| ~(BP10G_MCLK_DATA_OUT9))); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA5 |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA5))); |
| } else if (pbpctl_dev->bp_i80) { |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MDIO_DIR80) |
| & |
| ~BPCTLI_CTRL_EXT_MDIO_DATA80)); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & |
| ~BPCTLI_CTRL_EXT_MCLK_DATA80)); |
| |
| } else if (pbpctl_dev->bp_540) { |
| ctrl = ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP); |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | |
| BP540_MDIO_DIR | |
| BP540_MCLK_DIR) & |
| ~(BP540_MDIO_DATA | |
| BP540_MCLK_DATA))); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); |
| |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) |
| & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | |
| BP10GB_MDIO_SET | BP10GB_MCLK_SET)); |
| |
| } else if (!pbpctl_dev->bp_10g) { |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA))); |
| } else { |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| (ctrl_ext & |
| ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); |
| } |
| usec_delay(CMND_INTERVAL); |
| |
| /*send sync cmd */ |
| write_pulse(pbpctl_dev, ctrl_ext, SYNC_CMD_VAL, SYNC_CMD_LEN); |
| /*send wr cmd */ |
| write_pulse(pbpctl_dev, ctrl_ext, WR_CMD_VAL, WR_CMD_LEN); |
| write_pulse(pbpctl_dev, ctrl_ext, addr, ADDR_CMD_LEN); |
| |
| /*write data */ |
| write_pulse(pbpctl_dev, ctrl_ext, value, WR_DATA_LEN); |
| if (pbpctl_dev->bp_10g9) { |
| /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ |
| /* DATA 0 CLK 0 */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| ((ctrl | BP10G_MCLK_DIR_OUT9) & |
| ~(BP10G_MCLK_DATA_OUT9))); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA5 |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA5))); |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MDIO_DIR80) |
| & |
| ~BPCTLI_CTRL_EXT_MDIO_DATA80)); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & |
| ~BPCTLI_CTRL_EXT_MCLK_DATA80)); |
| } else if (pbpctl_dev->bp_540) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | |
| BP540_MDIO_DIR | |
| BP540_MCLK_DIR) & |
| ~(BP540_MDIO_DATA | |
| BP540_MCLK_DATA))); |
| } else if (pbpctl_dev->bp_10gb) { |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) |
| & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | |
| BP10GB_MDIO_SET | BP10GB_MCLK_SET)); |
| |
| } else if (!pbpctl_dev->bp_10g) |
| |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA))); |
| else { |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| (ctrl_ext & |
| ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); |
| |
| } |
| |
| usec_delay(CMND_INTERVAL * 4); |
| |
| if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) && |
| (pbpctl_dev->bp_ext_ver < PXG4BPFI_VER) && (addr == CMND_REG_ADDR)) |
| pbpctl_dev->bypass_wdt_on_time = jiffies; |
| #ifdef BP_SYNC_FLAG |
| spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); |
| #else |
| atomic_set(&pbpctl_dev->wdt_busy, 0); |
| #endif |
| |
| } |
| |
| static void write_data(bpctl_dev_t *pbpctl_dev, unsigned char value) |
| { |
| write_reg(pbpctl_dev, value, CMND_REG_ADDR); |
| } |
| |
| static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr) |
| { |
| uint32_t ctrl_ext = 0, ctrl = 0, ctrl_value = 0; |
| bpctl_dev_t *pbpctl_dev_c = NULL; |
| |
| #ifdef BP_SYNC_FLAG |
| unsigned long flags; |
| spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); |
| #else |
| atomic_set(&pbpctl_dev->wdt_busy, 1); |
| #endif |
| if (pbpctl_dev->bp_10g9) { |
| if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev))) |
| return -1; |
| } |
| |
| if (pbpctl_dev->bp_10g9) { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL); |
| ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); |
| |
| /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ |
| /* DATA 0 CLK 0 */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| ((ctrl | BP10G_MCLK_DIR_OUT9) & |
| ~(BP10G_MCLK_DATA_OUT9))); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA5 |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA5))); |
| } else if (pbpctl_dev->bp_i80) { |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MDIO_DIR80) |
| & |
| ~BPCTLI_CTRL_EXT_MDIO_DATA80)); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & |
| ~BPCTLI_CTRL_EXT_MCLK_DATA80)); |
| } else if (pbpctl_dev->bp_540) { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, ESDP); |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR | |
| BP540_MDIO_DIR) & |
| ~(BP540_MDIO_DATA | |
| BP540_MCLK_DATA))); |
| } else if (pbpctl_dev->bp_10gb) { |
| ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); |
| |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) |
| & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | |
| BP10GB_MDIO_SET | BP10GB_MCLK_SET)); |
| #if 0 |
| |
| /*BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, (ctrl_ext | BP10GB_MCLK_DIR | BP10GB_MDIO_DIR| |
| BP10GB_MCLK_CLR|BP10GB_MDIO_CLR)); |
| ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); |
| printk("1reg=%x\n", ctrl_ext); */ |
| |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, ((ctrl_ext | |
| BP10GB_MCLK_SET | |
| BP10GB_MDIO_CLR)) |
| & ~(BP10GB_MCLK_CLR | BP10GB_MDIO_SET | |
| BP10GB_MCLK_DIR | BP10GB_MDIO_DIR)); |
| |
| /* bnx2x_set_spio(pbpctl_dev, 5, MISC_REGISTERS_SPIO_OUTPUT_LOW); |
| bnx2x_set_spio(pbpctl_dev, 4, MISC_REGISTERS_SPIO_OUTPUT_LOW); |
| bnx2x_set_spio(pbpctl_dev, 4, MISC_REGISTERS_SPIO_INPUT_HI_Z); */ |
| |
| ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); |
| |
| printk("2reg=%x\n", ctrl_ext); |
| |
| #ifdef BP_SYNC_FLAG |
| spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); |
| #else |
| atomic_set(&pbpctl_dev->wdt_busy, 0); |
| #endif |
| |
| return 0; |
| |
| #endif |
| |
| } else if (!pbpctl_dev->bp_10g) { |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA))); |
| } else { |
| |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| (ctrl_ext & |
| ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); |
| |
| } |
| |
| usec_delay(CMND_INTERVAL); |
| |
| /*send sync cmd */ |
| write_pulse(pbpctl_dev, ctrl_ext, SYNC_CMD_VAL, SYNC_CMD_LEN); |
| /*send rd cmd */ |
| write_pulse(pbpctl_dev, ctrl_ext, RD_CMD_VAL, RD_CMD_LEN); |
| /*send addr */ |
| write_pulse(pbpctl_dev, ctrl_ext, addr, ADDR_CMD_LEN); |
| /*read data */ |
| /* zero */ |
| if (pbpctl_dev->bp_10g9) { |
| /* DATA 0 CLK 1 */ |
| /*BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext|BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9)); */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| (ctrl_ext | BP10G_MDIO_DATA_OUT9)); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| (ctrl | BP10G_MCLK_DATA_OUT9 | |
| BP10G_MCLK_DIR_OUT9)); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DATA5))); |
| |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| (ctrl_ext & |
| ~(BPCTLI_CTRL_EXT_MDIO_DATA80 | |
| BPCTLI_CTRL_EXT_MDIO_DIR80))); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 | |
| BPCTLI_CTRL_EXT_MCLK_DATA80)); |
| |
| } else if (pbpctl_dev->bp_540) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| (((ctrl | BP540_MDIO_DIR | BP540_MCLK_DIR | |
| BP540_MCLK_DATA) & ~BP540_MDIO_DATA))); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_DIR | BP10GB_MCLK_SET) |
| & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_SET | |
| BP10GB_MDIO_CLR | BP10GB_MCLK_CLR)); |
| |
| } else if (!pbpctl_dev->bp_10g) |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DIR |
| | |
| BPCTLI_CTRL_EXT_MDIO_DATA))); |
| else { |
| |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| (ctrl_ext | BP10G_MCLK_DATA_OUT | |
| BP10G_MDIO_DATA_OUT)); |
| |
| |
| } |
| usec_delay(PULSE_TIME); |
| |
| ctrl_value = read_pulse(pbpctl_dev, ctrl_ext, RD_DATA_LEN); |
| |
| if (pbpctl_dev->bp_10g9) { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL); |
| ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); |
| |
| /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ |
| /* DATA 0 CLK 0 */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| ((ctrl | BP10G_MCLK_DIR_OUT9) & |
| ~(BP10G_MCLK_DATA_OUT9))); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA5 |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA5))); |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MDIO_DIR80) |
| & |
| ~BPCTLI_CTRL_EXT_MDIO_DATA80)); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & |
| ~BPCTLI_CTRL_EXT_MCLK_DATA80)); |
| |
| } else if (pbpctl_dev->bp_540) { |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR | |
| BP540_MDIO_DIR) & |
| ~(BP540_MDIO_DATA | |
| BP540_MCLK_DATA))); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) |
| & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | |
| BP10GB_MDIO_SET | BP10GB_MCLK_SET)); |
| |
| } else if (!pbpctl_dev->bp_10g) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA))); |
| } else { |
| |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| (ctrl_ext & |
| ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); |
| |
| } |
| |
| usec_delay(CMND_INTERVAL * 4); |
| #ifdef BP_SYNC_FLAG |
| spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); |
| #else |
| atomic_set(&pbpctl_dev->wdt_busy, 0); |
| #endif |
| |
| return ctrl_value; |
| } |
| |
| static int wdt_pulse(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t ctrl_ext = 0, ctrl = 0; |
| bpctl_dev_t *pbpctl_dev_c = NULL; |
| |
| #ifdef BP_SYNC_FLAG |
| unsigned long flags; |
| |
| spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); |
| #else |
| |
| if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1) |
| return -1; |
| #endif |
| if (pbpctl_dev->bp_10g9) { |
| if (!(pbpctl_dev_c = get_status_port_fn(pbpctl_dev))) |
| return -1; |
| } |
| |
| if (pbpctl_dev->bp_10g9) { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, I2CCTL); |
| ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP); |
| |
| /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ |
| /* DATA 0 CLK 0 */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| ((ctrl | BP10G_MCLK_DIR_OUT9) & |
| ~(BP10G_MCLK_DATA_OUT9))); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA5 |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA5))); |
| } else if (pbpctl_dev->bp_i80) { |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MDIO_DIR80) |
| & |
| ~BPCTLI_CTRL_EXT_MDIO_DATA80)); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & |
| ~BPCTLI_CTRL_EXT_MCLK_DATA80)); |
| } else if (pbpctl_dev->bp_540) { |
| ctrl_ext = ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR | |
| BP540_MDIO_DIR) & |
| ~(BP540_MDIO_DATA | |
| BP540_MCLK_DATA))); |
| } else if (pbpctl_dev->bp_10gb) { |
| ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) |
| & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | |
| BP10GB_MDIO_SET | BP10GB_MCLK_SET)); |
| |
| } else if (!pbpctl_dev->bp_10g) { |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA))); |
| } else { |
| |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP); |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| (ctrl_ext & |
| ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); |
| |
| } |
| if (pbpctl_dev->bp_10g9) { |
| /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, ((ctrl_ext|BP10G_MCLK_DATA_OUT9)&~BP10G_MDIO_DATA_OUT9)); */ |
| /* DATA 0 CLK 1 */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| (ctrl | BP10G_MCLK_DATA_OUT9 | |
| BP10G_MCLK_DIR_OUT9)); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA5))); |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MDIO_DIR80) |
| & |
| ~BPCTLI_CTRL_EXT_MDIO_DATA80)); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| (ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80 | |
| BPCTLI_CTRL_EXT_MCLK_DATA80)); |
| |
| } else if (pbpctl_dev->bp_540) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | |
| BP540_MDIO_DIR | |
| BP540_MCLK_DIR | |
| BP540_MCLK_DATA) & |
| ~BP540_MDIO_DATA)); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); |
| |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_SET) |
| & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | |
| BP10GB_MDIO_SET | BP10GB_MCLK_CLR)); |
| |
| } else if (!pbpctl_dev->bp_10g) |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR |
| | |
| BPCTLI_CTRL_EXT_MCLK_DATA) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MDIO_DATA))); |
| else { |
| |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| ((ctrl_ext | BP10G_MCLK_DATA_OUT) & |
| ~BP10G_MDIO_DATA_OUT)); |
| |
| } |
| |
| usec_delay(WDT_INTERVAL); |
| if (pbpctl_dev->bp_10g9) { |
| /* BP10G_WRITE_REG(pbpctl_dev, I2CCTL, (ctrl_ext&~(BP10G_MCLK_DATA_OUT9|BP10G_MDIO_DATA_OUT9))); */ |
| /* DATA 0 CLK 0 */ |
| BP10G_WRITE_REG(pbpctl_dev, I2CCTL, |
| (ctrl_ext & ~BP10G_MDIO_DATA_OUT9)); |
| BP10G_WRITE_REG(pbpctl_dev_c, ESDP, |
| ((ctrl | BP10G_MCLK_DIR_OUT9) & |
| ~(BP10G_MCLK_DATA_OUT9))); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR5) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MCLK_DATA5 |
| | |
| BPCTLI_CTRL_EXT_MDIO_DATA5))); |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MDIO_DIR80) |
| & |
| ~BPCTLI_CTRL_EXT_MDIO_DATA80)); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl | BPCTLI_CTRL_EXT_MCLK_DIR80) & |
| ~BPCTLI_CTRL_EXT_MCLK_DATA80)); |
| |
| } else if (pbpctl_dev->bp_540) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl | BP540_MCLK_DIR | |
| BP540_MDIO_DIR) & |
| ~(BP540_MDIO_DATA | |
| BP540_MCLK_DATA))); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO); |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_SPIO, |
| (ctrl_ext | BP10GB_MDIO_CLR | BP10GB_MCLK_CLR) |
| & ~(BP10GB_MCLK_DIR | BP10GB_MDIO_DIR | |
| BP10GB_MDIO_SET | BP10GB_MCLK_SET)); |
| |
| } else if (!pbpctl_dev->bp_10g) |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MCLK_DATA |
| | |
| BPCTLI_CTRL_EXT_MDIO_DATA))); |
| else { |
| |
| BP10G_WRITE_REG(pbpctl_dev, EODSDP, |
| (ctrl_ext & |
| ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT))); |
| } |
| if ((pbpctl_dev->wdt_status == WDT_STATUS_EN) /*&& |
| (pbpctl_dev->bp_ext_ver<PXG4BPFI_VER) */ ) |
| pbpctl_dev->bypass_wdt_on_time = jiffies; |
| #ifdef BP_SYNC_FLAG |
| spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); |
| #endif |
| usec_delay(CMND_INTERVAL * 4); |
| return 0; |
| } |
| |
| static void data_pulse(bpctl_dev_t *pbpctl_dev, unsigned char value) |
| { |
| |
| uint32_t ctrl_ext = 0; |
| #ifdef BP_SYNC_FLAG |
| unsigned long flags; |
| #endif |
| wdt_time_left(pbpctl_dev); |
| #ifdef BP_SYNC_FLAG |
| spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); |
| #else |
| atomic_set(&pbpctl_dev->wdt_busy, 1); |
| #endif |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_SDP6_DIR | |
| BPCTLI_CTRL_EXT_SDP7_DIR) & |
| ~(BPCTLI_CTRL_EXT_SDP6_DATA | |
| BPCTLI_CTRL_EXT_SDP7_DATA))); |
| |
| usec_delay(INIT_CMND_INTERVAL); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_SDP6_DIR | |
| BPCTLI_CTRL_EXT_SDP7_DIR | |
| BPCTLI_CTRL_EXT_SDP6_DATA) & |
| ~ |
| (BPCTLI_CTRL_EXT_SDP7_DATA))); |
| usec_delay(INIT_CMND_INTERVAL); |
| |
| while (value) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | |
| BPCTLI_CTRL_EXT_SDP6_DIR | |
| BPCTLI_CTRL_EXT_SDP7_DIR | |
| BPCTLI_CTRL_EXT_SDP6_DATA | |
| BPCTLI_CTRL_EXT_SDP7_DATA); |
| usec_delay(PULSE_INTERVAL); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_SDP6_DIR |
| | |
| BPCTLI_CTRL_EXT_SDP7_DIR |
| | |
| BPCTLI_CTRL_EXT_SDP6_DATA) |
| & |
| ~BPCTLI_CTRL_EXT_SDP7_DATA)); |
| usec_delay(PULSE_INTERVAL); |
| value--; |
| |
| } |
| usec_delay(INIT_CMND_INTERVAL - PULSE_INTERVAL); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_SDP6_DIR | |
| BPCTLI_CTRL_EXT_SDP7_DIR) & |
| ~(BPCTLI_CTRL_EXT_SDP6_DATA | |
| BPCTLI_CTRL_EXT_SDP7_DATA))); |
| usec_delay(WDT_TIME_CNT); |
| if (pbpctl_dev->wdt_status == WDT_STATUS_EN) |
| pbpctl_dev->bypass_wdt_on_time = jiffies; |
| #ifdef BP_SYNC_FLAG |
| spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); |
| #else |
| atomic_set(&pbpctl_dev->wdt_busy, 0); |
| #endif |
| |
| } |
| |
| static int send_wdt_pulse(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t ctrl_ext = 0; |
| |
| #ifdef BP_SYNC_FLAG |
| unsigned long flags; |
| |
| spin_lock_irqsave(&pbpctl_dev->bypass_wr_lock, flags); |
| #else |
| |
| if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1) |
| return -1; |
| #endif |
| wdt_time_left(pbpctl_dev); |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | /* 1 */ |
| BPCTLI_CTRL_EXT_SDP7_DIR | |
| BPCTLI_CTRL_EXT_SDP7_DATA); |
| usec_delay(PULSE_INTERVAL); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | /* 0 */ |
| BPCTLI_CTRL_EXT_SDP7_DIR) & |
| ~BPCTLI_CTRL_EXT_SDP7_DATA)); |
| |
| usec_delay(PULSE_INTERVAL); |
| if (pbpctl_dev->wdt_status == WDT_STATUS_EN) |
| pbpctl_dev->bypass_wdt_on_time = jiffies; |
| #ifdef BP_SYNC_FLAG |
| spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags); |
| #endif |
| |
| return 0; |
| } |
| |
| void send_bypass_clear_pulse(bpctl_dev_t *pbpctl_dev, unsigned int value) |
| { |
| uint32_t ctrl_ext = 0; |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | /* 0 */ |
| BPCTLI_CTRL_EXT_SDP6_DIR) & |
| ~BPCTLI_CTRL_EXT_SDP6_DATA)); |
| |
| usec_delay(PULSE_INTERVAL); |
| while (value) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | /* 1 */ |
| BPCTLI_CTRL_EXT_SDP6_DIR | |
| BPCTLI_CTRL_EXT_SDP6_DATA); |
| usec_delay(PULSE_INTERVAL); |
| value--; |
| } |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | /* 0 */ |
| BPCTLI_CTRL_EXT_SDP6_DIR) & |
| ~BPCTLI_CTRL_EXT_SDP6_DATA)); |
| usec_delay(PULSE_INTERVAL); |
| } |
| |
| /* #endif OLD_FW */ |
| #ifdef BYPASS_DEBUG |
| |
| int pulse_set_fn(bpctl_dev_t *pbpctl_dev, unsigned int counter) |
| { |
| uint32_t ctrl_ext = 0; |
| |
| if (!pbpctl_dev) |
| return -1; |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| write_pulse_1(pbpctl_dev, ctrl_ext, counter, counter); |
| |
| pbpctl_dev->bypass_wdt_status = 0; |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| write_pulse_1(pbpctl_dev, ctrl_ext, counter, counter); |
| } else { |
| wdt_time_left(pbpctl_dev); |
| if (pbpctl_dev->wdt_status == WDT_STATUS_EN) { |
| pbpctl_dev->wdt_status = 0; |
| data_pulse(pbpctl_dev, counter); |
| pbpctl_dev->wdt_status = WDT_STATUS_EN; |
| pbpctl_dev->bypass_wdt_on_time = jiffies; |
| |
| } else |
| data_pulse(pbpctl_dev, counter); |
| } |
| |
| return 0; |
| } |
| |
| int zero_set_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t ctrl_ext = 0, ctrl_value = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| printk("zero_set"); |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_MCLK_DIR) |
| & |
| ~ |
| (BPCTLI_CTRL_EXT_MCLK_DATA |
| | |
| BPCTLI_CTRL_EXT_MDIO_DIR |
| | |
| BPCTLI_CTRL_EXT_MDIO_DATA))); |
| |
| } |
| return ctrl_value; |
| } |
| |
| int pulse_get2_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t ctrl_ext = 0, ctrl_value = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| printk("pulse_get_fn\n"); |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| ctrl_value = read_pulse_2(pbpctl_dev, ctrl_ext); |
| printk("read:%d\n", ctrl_value); |
| } |
| return ctrl_value; |
| } |
| |
| int pulse_get1_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t ctrl_ext = 0, ctrl_value = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| |
| printk("pulse_get_fn\n"); |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| ctrl_value = read_pulse_1(pbpctl_dev, ctrl_ext); |
| printk("read:%d\n", ctrl_value); |
| } |
| return ctrl_value; |
| } |
| |
| int gpio6_set_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t ctrl_ext = 0; |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | |
| BPCTLI_CTRL_EXT_SDP6_DIR | |
| BPCTLI_CTRL_EXT_SDP6_DATA); |
| return 0; |
| } |
| |
| int gpio7_set_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t ctrl_ext = 0; |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ctrl_ext | |
| BPCTLI_CTRL_EXT_SDP7_DIR | |
| BPCTLI_CTRL_EXT_SDP7_DATA); |
| return 0; |
| } |
| |
| int gpio7_clear_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t ctrl_ext = 0; |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_SDP7_DIR) & |
| ~BPCTLI_CTRL_EXT_SDP7_DATA)); |
| return 0; |
| } |
| |
| int gpio6_clear_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t ctrl_ext = 0; |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, ((ctrl_ext | |
| BPCTLI_CTRL_EXT_SDP6_DIR) & |
| ~BPCTLI_CTRL_EXT_SDP6_DATA)); |
| return 0; |
| } |
| #endif /*BYPASS_DEBUG */ |
| |
| static bpctl_dev_t *lookup_port(bpctl_dev_t *dev) |
| { |
| bpctl_dev_t *p; |
| int n; |
| for (n = 0, p = bpctl_dev_arr; n < device_num && p->pdev; n++) { |
| if (p->bus == dev->bus |
| && p->slot == dev->slot |
| && p->func == (dev->func ^ 1)) |
| return p; |
| } |
| return NULL; |
| } |
| |
| static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev) { |
| if (pbpctl_dev->func == 0 || pbpctl_dev->func == 2) |
| return lookup_port(pbpctl_dev); |
| } |
| return NULL; |
| } |
| |
| static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev) { |
| if (pbpctl_dev->func == 1 || pbpctl_dev->func == 3) |
| return lookup_port(pbpctl_dev); |
| } |
| return NULL; |
| } |
| |
| /**************************************/ |
| /**************INTEL API***************/ |
| /**************************************/ |
| |
| static void write_data_port_int(bpctl_dev_t *pbpctl_dev, |
| unsigned char ctrl_value) |
| { |
| uint32_t value; |
| |
| value = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| /* Make SDP0 Pin Directonality to Output */ |
| value |= BPCTLI_CTRL_SDP0_DIR; |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value); |
| |
| value &= ~BPCTLI_CTRL_SDP0_DATA; |
| value |= ((ctrl_value & 0x1) << BPCTLI_CTRL_SDP0_SHIFT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, value); |
| |
| value = (BPCTL_READ_REG(pbpctl_dev, CTRL_EXT)); |
| /* Make SDP2 Pin Directonality to Output */ |
| value |= BPCTLI_CTRL_EXT_SDP6_DIR; |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, value); |
| |
| value &= ~BPCTLI_CTRL_EXT_SDP6_DATA; |
| value |= (((ctrl_value & 0x2) >> 1) << BPCTLI_CTRL_EXT_SDP6_SHIFT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, value); |
| |
| } |
| |
| static int write_data_int(bpctl_dev_t *pbpctl_dev, unsigned char value) |
| { |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| |
| if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) |
| return -1; |
| atomic_set(&pbpctl_dev->wdt_busy, 1); |
| write_data_port_int(pbpctl_dev, value & 0x3); |
| write_data_port_int(pbpctl_dev_b, ((value & 0xc) >> 2)); |
| atomic_set(&pbpctl_dev->wdt_busy, 0); |
| |
| return 0; |
| } |
| |
| static int wdt_pulse_int(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if ((atomic_read(&pbpctl_dev->wdt_busy)) == 1) |
| return -1; |
| |
| if ((write_data_int(pbpctl_dev, RESET_WDT_INT)) < 0) |
| return -1; |
| msec_delay_bp(CMND_INTERVAL_INT); |
| if ((write_data_int(pbpctl_dev, CMND_OFF_INT)) < 0) |
| return -1; |
| msec_delay_bp(CMND_INTERVAL_INT); |
| |
| if (pbpctl_dev->wdt_status == WDT_STATUS_EN) |
| pbpctl_dev->bypass_wdt_on_time = jiffies; |
| |
| return 0; |
| } |
| |
| /*************************************/ |
| /************* COMMANDS **************/ |
| /*************************************/ |
| |
| /* CMND_ON 0x4 (100)*/ |
| int cmnd_on(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) |
| return 0; |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) |
| write_data(pbpctl_dev, CMND_ON); |
| else |
| data_pulse(pbpctl_dev, CMND_ON); |
| ret = 0; |
| } |
| return ret; |
| } |
| |
| /* CMND_OFF 0x2 (10)*/ |
| int cmnd_off(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { |
| write_data_int(pbpctl_dev, CMND_OFF_INT); |
| msec_delay_bp(CMND_INTERVAL_INT); |
| } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) |
| write_data(pbpctl_dev, CMND_OFF); |
| else |
| data_pulse(pbpctl_dev, CMND_OFF); |
| ret = 0; |
| }; |
| return ret; |
| } |
| |
| /* BYPASS_ON (0xa)*/ |
| int bypass_on(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| |
| if (pbpctl_dev->bp_caps & BP_CAP) { |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { |
| write_data_int(pbpctl_dev, BYPASS_ON_INT); |
| msec_delay_bp(BYPASS_DELAY_INT); |
| pbpctl_dev->bp_status_un = 0; |
| } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| write_data(pbpctl_dev, BYPASS_ON); |
| if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) |
| msec_delay_bp(LATCH_DELAY); |
| } else |
| data_pulse(pbpctl_dev, BYPASS_ON); |
| ret = 0; |
| }; |
| return ret; |
| } |
| |
| /* BYPASS_OFF (0x8 111)*/ |
| int bypass_off(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| |
| if (pbpctl_dev->bp_caps & BP_CAP) { |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { |
| write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT); |
| msec_delay_bp(BYPASS_DELAY_INT); |
| write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT); |
| msec_delay_bp(BYPASS_DELAY_INT); |
| pbpctl_dev->bp_status_un = 0; |
| } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| write_data(pbpctl_dev, BYPASS_OFF); |
| if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) |
| msec_delay_bp(LATCH_DELAY); |
| } else |
| data_pulse(pbpctl_dev, BYPASS_OFF); |
| ret = 0; |
| } |
| return ret; |
| } |
| |
| /* TAP_OFF (0x9)*/ |
| int tap_off(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| if ((pbpctl_dev->bp_caps & TAP_CAP) |
| && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) { |
| write_data(pbpctl_dev, TAP_OFF); |
| msec_delay_bp(LATCH_DELAY); |
| ret = 0; |
| }; |
| return ret; |
| } |
| |
| /* TAP_ON (0xb)*/ |
| int tap_on(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| if ((pbpctl_dev->bp_caps & TAP_CAP) |
| && (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) { |
| write_data(pbpctl_dev, TAP_ON); |
| msec_delay_bp(LATCH_DELAY); |
| ret = 0; |
| }; |
| return ret; |
| } |
| |
| /* DISC_OFF (0x9)*/ |
| int disc_off(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) { |
| write_data(pbpctl_dev, DISC_OFF); |
| msec_delay_bp(LATCH_DELAY); |
| } else |
| ret = BP_NOT_CAP; |
| return ret; |
| } |
| |
| /* DISC_ON (0xb)*/ |
| int disc_on(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| if ((pbpctl_dev->bp_caps & DISC_CAP) && (pbpctl_dev->bp_ext_ver >= 0x8)) { |
| write_data(pbpctl_dev, /*DISC_ON */ 0x85); |
| msec_delay_bp(LATCH_DELAY); |
| } else |
| ret = BP_NOT_CAP; |
| return ret; |
| } |
| |
| /* DISC_PORT_ON */ |
| int disc_port_on(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| bpctl_dev_t *pbpctl_dev_m; |
| |
| if ((is_bypass_fn(pbpctl_dev)) == 1) |
| pbpctl_dev_m = pbpctl_dev; |
| else |
| pbpctl_dev_m = get_master_port_fn(pbpctl_dev); |
| if (pbpctl_dev_m == NULL) |
| return BP_NOT_CAP; |
| |
| if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { |
| if (is_bypass_fn(pbpctl_dev) == 1) { |
| |
| write_data(pbpctl_dev_m, TX_DISA); |
| } else { |
| |
| write_data(pbpctl_dev_m, TX_DISB); |
| } |
| |
| msec_delay_bp(LATCH_DELAY); |
| |
| } |
| return ret; |
| } |
| |
| /* DISC_PORT_OFF */ |
| int disc_port_off(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| bpctl_dev_t *pbpctl_dev_m; |
| |
| if ((is_bypass_fn(pbpctl_dev)) == 1) |
| pbpctl_dev_m = pbpctl_dev; |
| else |
| pbpctl_dev_m = get_master_port_fn(pbpctl_dev); |
| if (pbpctl_dev_m == NULL) |
| return BP_NOT_CAP; |
| |
| if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { |
| if (is_bypass_fn(pbpctl_dev) == 1) |
| write_data(pbpctl_dev_m, TX_ENA); |
| else |
| write_data(pbpctl_dev_m, TX_ENB); |
| |
| msec_delay_bp(LATCH_DELAY); |
| |
| } |
| return ret; |
| } |
| |
| /*TWO_PORT_LINK_HW_EN (0xe)*/ |
| int tpl_hw_on(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0, ctrl = 0; |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| |
| if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) |
| return BP_NOT_CAP; |
| |
| if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) { |
| cmnd_on(pbpctl_dev); |
| write_data(pbpctl_dev, TPL2_ON); |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| cmnd_off(pbpctl_dev); |
| return ret; |
| } |
| |
| if (TPL_IF_SERIES(pbpctl_dev->subdevice)) { |
| ctrl = BPCTL_READ_REG(pbpctl_dev_b, CTRL); |
| BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL, |
| ((ctrl | BPCTLI_CTRL_SWDPIO0) & |
| ~BPCTLI_CTRL_SWDPIN0)); |
| } else |
| ret = BP_NOT_CAP; |
| return ret; |
| } |
| |
| /*TWO_PORT_LINK_HW_DIS (0xc)*/ |
| int tpl_hw_off(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0, ctrl = 0; |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| |
| if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) |
| return BP_NOT_CAP; |
| if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) { |
| cmnd_on(pbpctl_dev); |
| write_data(pbpctl_dev, TPL2_OFF); |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| cmnd_off(pbpctl_dev); |
| return ret; |
| } |
| if (TPL_IF_SERIES(pbpctl_dev->subdevice)) { |
| ctrl = BPCTL_READ_REG(pbpctl_dev_b, CTRL); |
| BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL, |
| (ctrl | BPCTLI_CTRL_SWDPIO0 | |
| BPCTLI_CTRL_SWDPIN0)); |
| } else |
| ret = BP_NOT_CAP; |
| return ret; |
| } |
| |
| /* WDT_OFF (0x6 110)*/ |
| int wdt_off(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { |
| bypass_off(pbpctl_dev); |
| } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) |
| write_data(pbpctl_dev, WDT_OFF); |
| else |
| data_pulse(pbpctl_dev, WDT_OFF); |
| pbpctl_dev->wdt_status = WDT_STATUS_DIS; |
| ret = 0; |
| }; |
| return ret; |
| } |
| |
| /* WDT_ON (0x10)*/ |
| |
| /***Global***/ |
| static unsigned int |
| wdt_val_array[] = { 1000, 1500, 2000, 3000, 4000, 8000, 16000, 32000, 0 }; |
| |
| int wdt_on(bpctl_dev_t *pbpctl_dev, unsigned int timeout) |
| { |
| |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| unsigned int pulse = 0, temp_value = 0, temp_cnt = 0; |
| pbpctl_dev->wdt_status = 0; |
| |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { |
| for (; wdt_val_array[temp_cnt]; temp_cnt++) |
| if (timeout <= wdt_val_array[temp_cnt]) |
| break; |
| |
| if (!wdt_val_array[temp_cnt]) |
| temp_cnt--; |
| |
| timeout = wdt_val_array[temp_cnt]; |
| temp_cnt += 0x7; |
| |
| write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT); |
| msec_delay_bp(BYPASS_DELAY_INT); |
| pbpctl_dev->bp_status_un = 0; |
| write_data_int(pbpctl_dev, temp_cnt); |
| pbpctl_dev->bypass_wdt_on_time = jiffies; |
| msec_delay_bp(CMND_INTERVAL_INT); |
| pbpctl_dev->bypass_timer_interval = timeout; |
| } else { |
| timeout = |
| (timeout < |
| TIMEOUT_UNIT ? TIMEOUT_UNIT : (timeout > |
| WDT_TIMEOUT_MAX ? |
| WDT_TIMEOUT_MAX : |
| timeout)); |
| temp_value = timeout / 100; |
| while ((temp_value >>= 1)) |
| temp_cnt++; |
| if (timeout > ((1 << temp_cnt) * 100)) |
| temp_cnt++; |
| pbpctl_dev->bypass_wdt_on_time = jiffies; |
| pulse = (WDT_ON | temp_cnt); |
| if (pbpctl_dev->bp_ext_ver == OLD_IF_VER) |
| data_pulse(pbpctl_dev, pulse); |
| else |
| write_data(pbpctl_dev, pulse); |
| pbpctl_dev->bypass_timer_interval = |
| (1 << temp_cnt) * 100; |
| } |
| pbpctl_dev->wdt_status = WDT_STATUS_EN; |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| void bp75_put_hw_semaphore_generic(bpctl_dev_t *pbpctl_dev) |
| { |
| u32 swsm; |
| |
| swsm = BPCTL_READ_REG(pbpctl_dev, SWSM); |
| |
| swsm &= ~(BPCTLI_SWSM_SMBI | BPCTLI_SWSM_SWESMBI); |
| |
| BPCTL_WRITE_REG(pbpctl_dev, SWSM, swsm); |
| } |
| |
| s32 bp75_get_hw_semaphore_generic(bpctl_dev_t *pbpctl_dev) |
| { |
| u32 swsm; |
| s32 ret_val = 0; |
| s32 timeout = 8192 + 1; |
| s32 i = 0; |
| |
| /* Get the SW semaphore */ |
| while (i < timeout) { |
| swsm = BPCTL_READ_REG(pbpctl_dev, SWSM); |
| if (!(swsm & BPCTLI_SWSM_SMBI)) |
| break; |
| |
| usec_delay(50); |
| i++; |
| } |
| |
| if (i == timeout) { |
| printk |
| ("bpctl_mod: Driver can't access device - SMBI bit is set.\n"); |
| ret_val = -1; |
| goto out; |
| } |
| |
| /* Get the FW semaphore. */ |
| for (i = 0; i < timeout; i++) { |
| swsm = BPCTL_READ_REG(pbpctl_dev, SWSM); |
| BPCTL_WRITE_REG(pbpctl_dev, SWSM, swsm | BPCTLI_SWSM_SWESMBI); |
| |
| /* Semaphore acquired if bit latched */ |
| if (BPCTL_READ_REG(pbpctl_dev, SWSM) & BPCTLI_SWSM_SWESMBI) |
| break; |
| |
| usec_delay(50); |
| } |
| |
| if (i == timeout) { |
| /* Release semaphores */ |
| bp75_put_hw_semaphore_generic(pbpctl_dev); |
| printk("bpctl_mod: Driver can't access the NVM\n"); |
| ret_val = -1; |
| goto out; |
| } |
| |
| out: |
| return ret_val; |
| } |
| |
| static void bp75_release_phy(bpctl_dev_t *pbpctl_dev) |
| { |
| u16 mask = BPCTLI_SWFW_PHY0_SM; |
| u32 swfw_sync; |
| |
| if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3)) |
| mask = BPCTLI_SWFW_PHY1_SM; |
| |
| while (bp75_get_hw_semaphore_generic(pbpctl_dev) != 0) ; |
| /* Empty */ |
| |
| swfw_sync = BPCTL_READ_REG(pbpctl_dev, SW_FW_SYNC); |
| swfw_sync &= ~mask; |
| BPCTL_WRITE_REG(pbpctl_dev, SW_FW_SYNC, swfw_sync); |
| |
| bp75_put_hw_semaphore_generic(pbpctl_dev); |
| } |
| |
| static s32 bp75_acquire_phy(bpctl_dev_t *pbpctl_dev) |
| { |
| u16 mask = BPCTLI_SWFW_PHY0_SM; |
| u32 swfw_sync; |
| u32 swmask; |
| u32 fwmask; |
| s32 ret_val = 0; |
| s32 i = 0, timeout = 200; |
| |
| if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3)) |
| mask = BPCTLI_SWFW_PHY1_SM; |
| |
| swmask = mask; |
| fwmask = mask << 16; |
| |
| while (i < timeout) { |
| if (bp75_get_hw_semaphore_generic(pbpctl_dev)) { |
| ret_val = -1; |
| goto out; |
| } |
| |
| swfw_sync = BPCTL_READ_REG(pbpctl_dev, SW_FW_SYNC); |
| if (!(swfw_sync & (fwmask | swmask))) |
| break; |
| |
| bp75_put_hw_semaphore_generic(pbpctl_dev); |
| mdelay(5); |
| i++; |
| } |
| |
| if (i == timeout) { |
| printk |
| ("bpctl_mod: Driver can't access resource, SW_FW_SYNC timeout.\n"); |
| ret_val = -1; |
| goto out; |
| } |
| |
| swfw_sync |= swmask; |
| BPCTL_WRITE_REG(pbpctl_dev, SW_FW_SYNC, swfw_sync); |
| |
| bp75_put_hw_semaphore_generic(pbpctl_dev); |
| |
| out: |
| return ret_val; |
| } |
| |
| s32 bp75_read_phy_reg_mdic(bpctl_dev_t *pbpctl_dev, u32 offset, u16 *data) |
| { |
| u32 i, mdic = 0; |
| s32 ret_val = 0; |
| u32 phy_addr = 1; |
| |
| mdic = ((offset << BPCTLI_MDIC_REG_SHIFT) | |
| (phy_addr << BPCTLI_MDIC_PHY_SHIFT) | (BPCTLI_MDIC_OP_READ)); |
| |
| BPCTL_WRITE_REG(pbpctl_dev, MDIC, mdic); |
| |
| for (i = 0; i < (BPCTLI_GEN_POLL_TIMEOUT * 3); i++) { |
| usec_delay(50); |
| mdic = BPCTL_READ_REG(pbpctl_dev, MDIC); |
| if (mdic & BPCTLI_MDIC_READY) |
| break; |
| } |
| if (!(mdic & BPCTLI_MDIC_READY)) { |
| printk("bpctl_mod: MDI Read did not complete\n"); |
| ret_val = -1; |
| goto out; |
| } |
| if (mdic & BPCTLI_MDIC_ERROR) { |
| printk("bpctl_mod: MDI Error\n"); |
| ret_val = -1; |
| goto out; |
| } |
| *data = (u16) mdic; |
| |
| out: |
| return ret_val; |
| } |
| |
| s32 bp75_write_phy_reg_mdic(bpctl_dev_t *pbpctl_dev, u32 offset, u16 data) |
| { |
| u32 i, mdic = 0; |
| s32 ret_val = 0; |
| u32 phy_addr = 1; |
| |
| mdic = (((u32) data) | |
| (offset << BPCTLI_MDIC_REG_SHIFT) | |
| (phy_addr << BPCTLI_MDIC_PHY_SHIFT) | (BPCTLI_MDIC_OP_WRITE)); |
| |
| BPCTL_WRITE_REG(pbpctl_dev, MDIC, mdic); |
| |
| for (i = 0; i < (BPCTLI_GEN_POLL_TIMEOUT * 3); i++) { |
| usec_delay(50); |
| mdic = BPCTL_READ_REG(pbpctl_dev, MDIC); |
| if (mdic & BPCTLI_MDIC_READY) |
| break; |
| } |
| if (!(mdic & BPCTLI_MDIC_READY)) { |
| printk("bpctl_mod: MDI Write did not complete\n"); |
| ret_val = -1; |
| goto out; |
| } |
| if (mdic & BPCTLI_MDIC_ERROR) { |
| printk("bpctl_mod: MDI Error\n"); |
| ret_val = -1; |
| goto out; |
| } |
| |
| out: |
| return ret_val; |
| } |
| |
| static s32 bp75_read_phy_reg(bpctl_dev_t *pbpctl_dev, u32 offset, u16 *data) |
| { |
| s32 ret_val = 0; |
| |
| ret_val = bp75_acquire_phy(pbpctl_dev); |
| if (ret_val) |
| goto out; |
| |
| if (offset > BPCTLI_MAX_PHY_MULTI_PAGE_REG) { |
| ret_val = bp75_write_phy_reg_mdic(pbpctl_dev, |
| BPCTLI_IGP01E1000_PHY_PAGE_SELECT, |
| (u16) offset); |
| if (ret_val) |
| goto release; |
| } |
| |
| ret_val = |
| bp75_read_phy_reg_mdic(pbpctl_dev, |
| BPCTLI_MAX_PHY_REG_ADDRESS & offset, data); |
| |
| release: |
| bp75_release_phy(pbpctl_dev); |
| out: |
| return ret_val; |
| } |
| |
| static s32 bp75_write_phy_reg(bpctl_dev_t *pbpctl_dev, u32 offset, u16 data) |
| { |
| s32 ret_val = 0; |
| |
| ret_val = bp75_acquire_phy(pbpctl_dev); |
| if (ret_val) |
| goto out; |
| |
| if (offset > BPCTLI_MAX_PHY_MULTI_PAGE_REG) { |
| ret_val = bp75_write_phy_reg_mdic(pbpctl_dev, |
| BPCTLI_IGP01E1000_PHY_PAGE_SELECT, |
| (u16) offset); |
| if (ret_val) |
| goto release; |
| } |
| |
| ret_val = |
| bp75_write_phy_reg_mdic(pbpctl_dev, |
| BPCTLI_MAX_PHY_REG_ADDRESS & offset, data); |
| |
| release: |
| bp75_release_phy(pbpctl_dev); |
| |
| out: |
| return ret_val; |
| } |
| |
| /* SET_TX (non-Bypass command :)) */ |
| static int set_tx(bpctl_dev_t *pbpctl_dev, int tx_state) |
| { |
| int ret = 0, ctrl = 0; |
| bpctl_dev_t *pbpctl_dev_m; |
| if ((is_bypass_fn(pbpctl_dev)) == 1) |
| pbpctl_dev_m = pbpctl_dev; |
| else |
| pbpctl_dev_m = get_master_port_fn(pbpctl_dev); |
| if (pbpctl_dev_m == NULL) |
| return BP_NOT_CAP; |
| if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| if (!tx_state) { |
| if (pbpctl_dev->bp_540) { |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| (ctrl | BP10G_SDP1_DIR | |
| BP10G_SDP1_DATA)); |
| |
| } else { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| (ctrl | BPCTLI_CTRL_SDP1_DIR |
| | BPCTLI_CTRL_SWDPIN1)); |
| } |
| } else { |
| if (pbpctl_dev->bp_540) { |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| ((ctrl | BP10G_SDP1_DIR) & |
| ~BP10G_SDP1_DATA)); |
| } else { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| ((ctrl | |
| BPCTLI_CTRL_SDP1_DIR) & |
| ~BPCTLI_CTRL_SWDPIN1)); |
| } |
| return ret; |
| |
| } |
| } else if (pbpctl_dev->bp_caps & TX_CTL_CAP) { |
| if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) { |
| if (tx_state) { |
| uint16_t mii_reg; |
| if (! |
| (ret = |
| bp75_read_phy_reg(pbpctl_dev, |
| BPCTLI_PHY_CONTROL, |
| &mii_reg))) { |
| if (mii_reg & BPCTLI_MII_CR_POWER_DOWN) { |
| ret = |
| bp75_write_phy_reg |
| (pbpctl_dev, |
| BPCTLI_PHY_CONTROL, |
| mii_reg & |
| ~BPCTLI_MII_CR_POWER_DOWN); |
| } |
| } |
| } else { |
| uint16_t mii_reg; |
| if (! |
| (ret = |
| bp75_read_phy_reg(pbpctl_dev, |
| BPCTLI_PHY_CONTROL, |
| &mii_reg))) { |
| |
| mii_reg |= BPCTLI_MII_CR_POWER_DOWN; |
| ret = |
| bp75_write_phy_reg(pbpctl_dev, |
| BPCTLI_PHY_CONTROL, |
| mii_reg); |
| } |
| } |
| |
| } |
| if (pbpctl_dev->bp_fiber5) { |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| |
| } else if (pbpctl_dev->bp_10gb) |
| ctrl = BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO); |
| |
| else if (!pbpctl_dev->bp_10g) |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| else |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| |
| if (!tx_state) |
| if (pbpctl_dev->bp_10g9) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| (ctrl | BP10G_SDP3_DATA | |
| BP10G_SDP3_DIR)); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| (ctrl | |
| BPCTLI_CTRL_EXT_SDP6_DIR | |
| BPCTLI_CTRL_EXT_SDP6_DATA)); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| if ((pbpctl_dev->func == 1) |
| || (pbpctl_dev->func == 3)) |
| BP10GB_WRITE_REG(pbpctl_dev, |
| MISC_REG_GPIO, |
| (ctrl | |
| BP10GB_GPIO0_SET_P1) & |
| ~(BP10GB_GPIO0_CLR_P1 | |
| BP10GB_GPIO0_OE_P1)); |
| else |
| BP10GB_WRITE_REG(pbpctl_dev, |
| MISC_REG_GPIO, |
| (ctrl | |
| BP10GB_GPIO0_OE_P0 | |
| BP10GB_GPIO0_SET_P0)); |
| |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| (ctrl | BPCTLI_CTRL_SDP1_DIR |
| | BPCTLI_CTRL_SWDPIN1)); |
| |
| } else if (pbpctl_dev->bp_540) { |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| (ctrl | BP10G_SDP1_DIR | |
| BP10G_SDP1_DATA)); |
| |
| } |
| |
| else if (!pbpctl_dev->bp_10g) |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| (ctrl | BPCTLI_CTRL_SWDPIO0 | |
| BPCTLI_CTRL_SWDPIN0)); |
| |
| else |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| (ctrl | BP10G_SDP0_DATA | |
| BP10G_SDP0_DIR)); |
| |
| else { |
| if (pbpctl_dev->bp_10g9) { |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| ((ctrl | BP10G_SDP3_DIR) & |
| ~BP10G_SDP3_DATA)); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, |
| ((ctrl | |
| BPCTLI_CTRL_EXT_SDP6_DIR) & |
| ~BPCTLI_CTRL_EXT_SDP6_DATA)); |
| |
| } else if (pbpctl_dev->bp_10gb) { |
| if ((bpctl_dev_arr->func == 1) |
| || (bpctl_dev_arr->func == 3)) |
| BP10GB_WRITE_REG(pbpctl_dev, |
| MISC_REG_GPIO, |
| (ctrl | |
| BP10GB_GPIO0_CLR_P1) & |
| ~(BP10GB_GPIO0_SET_P1 | |
| BP10GB_GPIO0_OE_P1)); |
| else |
| BP10GB_WRITE_REG(pbpctl_dev, |
| MISC_REG_GPIO, |
| (ctrl | |
| BP10GB_GPIO0_OE_P0 | |
| BP10GB_GPIO0_CLR_P0)); |
| |
| } else if (pbpctl_dev->bp_i80) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| ((ctrl | |
| BPCTLI_CTRL_SDP1_DIR) & |
| ~BPCTLI_CTRL_SWDPIN1)); |
| } else if (pbpctl_dev->bp_540) { |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| ((ctrl | BP10G_SDP1_DIR) & |
| ~BP10G_SDP1_DATA)); |
| } |
| |
| else if (!pbpctl_dev->bp_10g) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| ((ctrl | BPCTLI_CTRL_SWDPIO0) |
| & ~BPCTLI_CTRL_SWDPIN0)); |
| if (!PEGF_IF_SERIES(pbpctl_dev->subdevice)) { |
| BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL, |
| (ctrl & |
| ~ |
| (BPCTLI_CTRL_SDP0_DATA |
| | |
| BPCTLI_CTRL_SDP0_DIR))); |
| } |
| } else |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| ((ctrl | BP10G_SDP0_DIR) & |
| ~BP10G_SDP0_DATA)); |
| |
| } |
| |
| } else |
| ret = BP_NOT_CAP; |
| return ret; |
| |
| } |
| |
| /* SET_FORCE_LINK (non-Bypass command :)) */ |
| static int set_bp_force_link(bpctl_dev_t *pbpctl_dev, int tx_state) |
| { |
| int ret = 0, ctrl = 0; |
| |
| if (DBI_IF_SERIES(pbpctl_dev->subdevice)) { |
| |
| if ((pbpctl_dev->bp_10g) || (pbpctl_dev->bp_10g9)) { |
| |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| if (!tx_state) |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| ctrl & ~BP10G_SDP1_DIR); |
| else |
| BP10G_WRITE_REG(pbpctl_dev, ESDP, |
| ((ctrl | BP10G_SDP1_DIR) & |
| ~BP10G_SDP1_DATA)); |
| return ret; |
| } |
| |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /*RESET_CONT 0x20 */ |
| int reset_cont(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) |
| return BP_NOT_CAP; |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) |
| write_data(pbpctl_dev, RESET_CONT); |
| else |
| data_pulse(pbpctl_dev, RESET_CONT); |
| ret = 0; |
| }; |
| return ret; |
| } |
| |
| /*DIS_BYPASS_CAP 0x22 */ |
| int dis_bypass_cap(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & BP_DIS_CAP) { |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { |
| write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT); |
| msec_delay_bp(BYPASS_DELAY_INT); |
| } else { |
| write_data(pbpctl_dev, BYPASS_OFF); |
| msec_delay_bp(LATCH_DELAY); |
| write_data(pbpctl_dev, DIS_BYPASS_CAP); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| } |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /*EN_BYPASS_CAP 0x24 */ |
| int en_bypass_cap(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & BP_DIS_CAP) { |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { |
| write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT); |
| msec_delay_bp(BYPASS_DELAY_INT); |
| } else { |
| write_data(pbpctl_dev, EN_BYPASS_CAP); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| } |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /* BYPASS_STATE_PWRON 0x26*/ |
| int bypass_state_pwron(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) { |
| write_data(pbpctl_dev, BYPASS_STATE_PWRON); |
| if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) |
| msec_delay_bp(DFLT_PWRON_DELAY); |
| else |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /* NORMAL_STATE_PWRON 0x28*/ |
| int normal_state_pwron(bpctl_dev_t *pbpctl_dev) |
| { |
| if ((pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) |
| || (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP)) { |
| write_data(pbpctl_dev, NORMAL_STATE_PWRON); |
| if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) |
| msec_delay_bp(DFLT_PWRON_DELAY); |
| else |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /* BYPASS_STATE_PWROFF 0x27*/ |
| int bypass_state_pwroff(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP) { |
| write_data(pbpctl_dev, BYPASS_STATE_PWROFF); |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /* NORMAL_STATE_PWROFF 0x29*/ |
| int normal_state_pwroff(bpctl_dev_t *pbpctl_dev) |
| { |
| if ((pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) { |
| write_data(pbpctl_dev, NORMAL_STATE_PWROFF); |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /*TAP_STATE_PWRON 0x2a*/ |
| int tap_state_pwron(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) { |
| write_data(pbpctl_dev, TAP_STATE_PWRON); |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /*DIS_TAP_CAP 0x2c*/ |
| int dis_tap_cap(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & TAP_DIS_CAP) { |
| write_data(pbpctl_dev, DIS_TAP_CAP); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /*EN_TAP_CAP 0x2e*/ |
| int en_tap_cap(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & TAP_DIS_CAP) { |
| write_data(pbpctl_dev, EN_TAP_CAP); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /*DISC_STATE_PWRON 0x2a*/ |
| int disc_state_pwron(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= 0x8) { |
| write_data(pbpctl_dev, DISC_STATE_PWRON); |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| return BP_OK; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /*DIS_DISC_CAP 0x2c*/ |
| int dis_disc_cap(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & DISC_DIS_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= 0x8) { |
| write_data(pbpctl_dev, DIS_DISC_CAP); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| return BP_OK; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /*DISC_STATE_PWRON 0x2a*/ |
| int disc_port_state_pwron(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| bpctl_dev_t *pbpctl_dev_m; |
| |
| return BP_NOT_CAP; |
| |
| if ((is_bypass_fn(pbpctl_dev)) == 1) |
| pbpctl_dev_m = pbpctl_dev; |
| else |
| pbpctl_dev_m = get_master_port_fn(pbpctl_dev); |
| if (pbpctl_dev_m == NULL) |
| return BP_NOT_CAP; |
| |
| if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { |
| if (is_bypass_fn(pbpctl_dev) == 1) |
| write_data(pbpctl_dev_m, TX_DISA_PWRUP); |
| else |
| write_data(pbpctl_dev_m, TX_DISB_PWRUP); |
| |
| msec_delay_bp(LATCH_DELAY); |
| |
| } |
| return ret; |
| } |
| |
| int normal_port_state_pwron(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| bpctl_dev_t *pbpctl_dev_m; |
| return BP_NOT_CAP; |
| |
| if ((is_bypass_fn(pbpctl_dev)) == 1) |
| pbpctl_dev_m = pbpctl_dev; |
| else |
| pbpctl_dev_m = get_master_port_fn(pbpctl_dev); |
| if (pbpctl_dev_m == NULL) |
| return BP_NOT_CAP; |
| |
| if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { |
| if (is_bypass_fn(pbpctl_dev) == 1) |
| write_data(pbpctl_dev_m, TX_ENA_PWRUP); |
| else |
| write_data(pbpctl_dev_m, TX_ENB_PWRUP); |
| |
| msec_delay_bp(LATCH_DELAY); |
| |
| } |
| return ret; |
| } |
| |
| /*EN_TAP_CAP 0x2e*/ |
| int en_disc_cap(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & DISC_DIS_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= 0x8) { |
| write_data(pbpctl_dev, EN_DISC_CAP); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| return BP_OK; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int std_nic_on(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & STD_NIC_CAP) { |
| |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { |
| write_data_int(pbpctl_dev, DIS_BYPASS_CAP_INT); |
| msec_delay_bp(BYPASS_DELAY_INT); |
| pbpctl_dev->bp_status_un = 0; |
| return BP_OK; |
| } |
| |
| if (pbpctl_dev->bp_ext_ver >= 0x8) { |
| write_data(pbpctl_dev, STD_NIC_ON); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| return BP_OK; |
| |
| } |
| |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| wdt_off(pbpctl_dev); |
| |
| if (pbpctl_dev->bp_caps & BP_CAP) { |
| write_data(pbpctl_dev, BYPASS_OFF); |
| msec_delay_bp(LATCH_DELAY); |
| } |
| |
| if (pbpctl_dev->bp_caps & TAP_CAP) { |
| write_data(pbpctl_dev, TAP_OFF); |
| msec_delay_bp(LATCH_DELAY); |
| } |
| |
| write_data(pbpctl_dev, NORMAL_STATE_PWRON); |
| if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) |
| msec_delay_bp(DFLT_PWRON_DELAY); |
| else |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| |
| if (pbpctl_dev->bp_caps & BP_DIS_CAP) { |
| write_data(pbpctl_dev, DIS_BYPASS_CAP); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| } |
| |
| if (pbpctl_dev->bp_caps & TAP_DIS_CAP) { |
| write_data(pbpctl_dev, DIS_TAP_CAP); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| |
| } |
| return 0; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int std_nic_off(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & STD_NIC_CAP) { |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { |
| write_data_int(pbpctl_dev, PWROFF_BYPASS_ON_INT); |
| msec_delay_bp(BYPASS_DELAY_INT); |
| return BP_OK; |
| } |
| if (pbpctl_dev->bp_ext_ver >= 0x8) { |
| write_data(pbpctl_dev, STD_NIC_OFF); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| return BP_OK; |
| |
| } |
| |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| |
| if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) { |
| write_data(pbpctl_dev, TAP_STATE_PWRON); |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| } |
| |
| if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) { |
| write_data(pbpctl_dev, BYPASS_STATE_PWRON); |
| if (pbpctl_dev->bp_ext_ver > PXG2BPI_VER) |
| msec_delay_bp(LATCH_DELAY + |
| EEPROM_WR_DELAY); |
| else |
| msec_delay_bp(DFLT_PWRON_DELAY); |
| } |
| |
| if (pbpctl_dev->bp_caps & TAP_DIS_CAP) { |
| write_data(pbpctl_dev, EN_TAP_CAP); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| } |
| if (pbpctl_dev->bp_caps & DISC_DIS_CAP) { |
| write_data(pbpctl_dev, EN_DISC_CAP); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| } |
| |
| if (pbpctl_dev->bp_caps & BP_DIS_CAP) { |
| write_data(pbpctl_dev, EN_BYPASS_CAP); |
| msec_delay_bp(BYPASS_CAP_DELAY); |
| } |
| |
| return 0; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int wdt_time_left(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| /* 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; */ |
| unsigned long curr_time = jiffies, delta_time = 0, wdt_on_time = |
| pbpctl_dev->bypass_wdt_on_time, delta_time_msec = 0; |
| int time_left = 0; |
| |
| switch (pbpctl_dev->wdt_status) { |
| case WDT_STATUS_DIS: |
| time_left = 0; |
| break; |
| case WDT_STATUS_EN: |
| delta_time = |
| (curr_time >= |
| wdt_on_time) ? (curr_time - wdt_on_time) : (~wdt_on_time + |
| curr_time); |
| delta_time_msec = jiffies_to_msecs(delta_time); |
| time_left = pbpctl_dev->bypass_timer_interval - delta_time_msec; |
| if (time_left < 0) { |
| time_left = -1; |
| pbpctl_dev->wdt_status = WDT_STATUS_EXP; |
| } |
| break; |
| case WDT_STATUS_EXP: |
| time_left = -1; |
| break; |
| } |
| |
| return time_left; |
| } |
| |
| static int wdt_timer(bpctl_dev_t *pbpctl_dev, int *time_left) |
| { |
| int ret = 0; |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| { |
| if (pbpctl_dev->wdt_status == WDT_STATUS_UNKNOWN) |
| ret = BP_NOT_CAP; |
| else |
| *time_left = wdt_time_left(pbpctl_dev); |
| } |
| |
| } else |
| ret = BP_NOT_CAP; |
| return ret; |
| } |
| |
| static int wdt_timer_reload(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| int ret = 0; |
| |
| if ((pbpctl_dev->bp_caps & WD_CTL_CAP) && |
| (pbpctl_dev->wdt_status != WDT_STATUS_UNKNOWN)) { |
| if (pbpctl_dev->wdt_status == WDT_STATUS_DIS) |
| return 0; |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) |
| ret = wdt_pulse(pbpctl_dev); |
| else if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) |
| ret = wdt_pulse_int(pbpctl_dev); |
| else |
| ret = send_wdt_pulse(pbpctl_dev); |
| /* if (ret==-1) |
| mod_timer(&pbpctl_dev->bp_timer, jiffies+1);*/ |
| return 1; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| static void wd_reset_timer(unsigned long param) |
| { |
| bpctl_dev_t *pbpctl_dev = (bpctl_dev_t *) param; |
| #ifdef BP_SELF_TEST |
| struct sk_buff *skb_tmp; |
| #endif |
| |
| if ((pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) && |
| ((atomic_read(&pbpctl_dev->wdt_busy)) == 1)) { |
| mod_timer(&pbpctl_dev->bp_timer, jiffies + 1); |
| return; |
| } |
| #ifdef BP_SELF_TEST |
| |
| if (pbpctl_dev->bp_self_test_flag == 1) { |
| skb_tmp = dev_alloc_skb(BPTEST_DATA_LEN + 2); |
| if ((skb_tmp) && (pbpctl_dev->ndev) && (pbpctl_dev->bp_tx_data)) { |
| memcpy(skb_put(skb_tmp, BPTEST_DATA_LEN), |
| pbpctl_dev->bp_tx_data, BPTEST_DATA_LEN); |
| skb_tmp->dev = pbpctl_dev->ndev; |
| skb_tmp->protocol = |
| eth_type_trans(skb_tmp, pbpctl_dev->ndev); |
| skb_tmp->ip_summed = CHECKSUM_UNNECESSARY; |
| netif_receive_skb(skb_tmp); |
| goto bp_timer_reload; |
| return; |
| } |
| } |
| #endif |
| |
| wdt_timer_reload(pbpctl_dev); |
| #ifdef BP_SELF_TEST |
| bp_timer_reload: |
| #endif |
| if (pbpctl_dev->reset_time) { |
| mod_timer(&pbpctl_dev->bp_timer, |
| jiffies + (HZ * pbpctl_dev->reset_time) / 1000); |
| } |
| } |
| |
| /*WAIT_AT_PWRUP 0x80 */ |
| int bp_wait_at_pwup_en(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { |
| write_data(pbpctl_dev, BP_WAIT_AT_PWUP_EN); |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| |
| return BP_OK; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /*DIS_WAIT_AT_PWRUP 0x81 */ |
| int bp_wait_at_pwup_dis(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| |
| if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { |
| write_data(pbpctl_dev, BP_WAIT_AT_PWUP_DIS); |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| |
| return BP_OK; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /*EN_HW_RESET 0x82 */ |
| |
| int bp_hw_reset_en(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { |
| write_data(pbpctl_dev, BP_HW_RESET_EN); |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| |
| return BP_OK; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /*DIS_HW_RESET 0x83 */ |
| |
| int bp_hw_reset_dis(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { |
| write_data(pbpctl_dev, BP_HW_RESET_DIS); |
| msec_delay_bp(LATCH_DELAY + EEPROM_WR_DELAY); |
| |
| return BP_OK; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| |
| int wdt_exp_mode(bpctl_dev_t *pbpctl_dev, int mode) |
| { |
| uint32_t status_reg = 0, status_reg1 = 0; |
| |
| if ((pbpctl_dev->bp_caps & (TAP_STATUS_CAP | DISC_CAP)) && |
| (pbpctl_dev->bp_caps & BP_CAP)) { |
| if (pbpctl_dev->bp_ext_ver >= PXE2TBPI_VER) { |
| |
| if ((pbpctl_dev->bp_ext_ver >= 0x8) && |
| (mode == 2) && (pbpctl_dev->bp_caps & DISC_CAP)) { |
| status_reg1 = |
| read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR); |
| if (!(status_reg1 & WDTE_DISC_BPN_MASK)) |
| write_reg(pbpctl_dev, |
| status_reg1 | |
| WDTE_DISC_BPN_MASK, |
| STATUS_DISC_REG_ADDR); |
| return BP_OK; |
| } |
| } |
| status_reg = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR); |
| |
| if ((mode == 0) && (pbpctl_dev->bp_caps & BP_CAP)) { |
| if (pbpctl_dev->bp_ext_ver >= 0x8) { |
| status_reg1 = |
| read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR); |
| if (status_reg1 & WDTE_DISC_BPN_MASK) |
| write_reg(pbpctl_dev, |
| status_reg1 & |
| ~WDTE_DISC_BPN_MASK, |
| STATUS_DISC_REG_ADDR); |
| } |
| if (status_reg & WDTE_TAP_BPN_MASK) |
| write_reg(pbpctl_dev, |
| status_reg & ~WDTE_TAP_BPN_MASK, |
| STATUS_TAP_REG_ADDR); |
| return BP_OK; |
| |
| } else if ((mode == 1) && (pbpctl_dev->bp_caps & TAP_CAP)) { |
| if (!(status_reg & WDTE_TAP_BPN_MASK)) |
| write_reg(pbpctl_dev, |
| status_reg | WDTE_TAP_BPN_MASK, |
| STATUS_TAP_REG_ADDR); |
| /*else return BP_NOT_CAP; */ |
| return BP_OK; |
| } |
| |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int bypass_fw_ver(bpctl_dev_t *pbpctl_dev) |
| { |
| if (is_bypass_fn(pbpctl_dev)) |
| return read_reg(pbpctl_dev, VER_REG_ADDR); |
| else |
| return BP_NOT_CAP; |
| } |
| |
| int bypass_sign_check(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (is_bypass_fn(pbpctl_dev)) |
| return (((read_reg(pbpctl_dev, PIC_SIGN_REG_ADDR)) == |
| PIC_SIGN_VALUE) ? 1 : 0); |
| else |
| return BP_NOT_CAP; |
| } |
| |
| static int tx_status(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t ctrl = 0; |
| bpctl_dev_t *pbpctl_dev_m; |
| if ((is_bypass_fn(pbpctl_dev)) == 1) |
| pbpctl_dev_m = pbpctl_dev; |
| else |
| pbpctl_dev_m = get_master_port_fn(pbpctl_dev); |
| if (pbpctl_dev_m == NULL) |
| return BP_NOT_CAP; |
| if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { |
| |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| if (pbpctl_dev->bp_i80) |
| return ((ctrl & BPCTLI_CTRL_SWDPIN1) != 0 ? 0 : 1); |
| if (pbpctl_dev->bp_540) { |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| |
| return ((ctrl & BP10G_SDP1_DATA) != 0 ? 0 : 1); |
| } |
| |
| } |
| |
| if (pbpctl_dev->bp_caps & TX_CTL_CAP) { |
| if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) { |
| uint16_t mii_reg; |
| if (! |
| (bp75_read_phy_reg |
| (pbpctl_dev, BPCTLI_PHY_CONTROL, &mii_reg))) { |
| if (mii_reg & BPCTLI_MII_CR_POWER_DOWN) |
| return 0; |
| |
| else |
| return 1; |
| } |
| return -1; |
| } |
| |
| if (pbpctl_dev->bp_10g9) { |
| return ((BP10G_READ_REG(pbpctl_dev, ESDP) & |
| BP10G_SDP3_DATA) != 0 ? 0 : 1); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| if (ctrl & BPCTLI_CTRL_EXT_SDP6_DATA) |
| return 0; |
| return 1; |
| } else if (pbpctl_dev->bp_10gb) { |
| ctrl = BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO); |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO, |
| (ctrl | BP10GB_GPIO0_OE_P1) & |
| ~(BP10GB_GPIO0_SET_P1 | |
| BP10GB_GPIO0_CLR_P1)); |
| |
| if ((pbpctl_dev->func == 1) || (pbpctl_dev->func == 3)) |
| return (((BP10GB_READ_REG |
| (pbpctl_dev, |
| MISC_REG_GPIO)) & BP10GB_GPIO0_P1) != |
| 0 ? 0 : 1); |
| else |
| return (((BP10GB_READ_REG |
| (pbpctl_dev, |
| MISC_REG_GPIO)) & BP10GB_GPIO0_P0) != |
| 0 ? 0 : 1); |
| } |
| |
| if (!pbpctl_dev->bp_10g) { |
| |
| ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL); |
| if (pbpctl_dev->bp_i80) |
| return ((ctrl & BPCTLI_CTRL_SWDPIN1) != |
| 0 ? 0 : 1); |
| if (pbpctl_dev->bp_540) { |
| ctrl = BP10G_READ_REG(pbpctl_dev, ESDP); |
| |
| return ((ctrl & BP10G_SDP1_DATA) != 0 ? 0 : 1); |
| } |
| |
| return ((ctrl & BPCTLI_CTRL_SWDPIN0) != 0 ? 0 : 1); |
| } else |
| return ((BP10G_READ_REG(pbpctl_dev, ESDP) & |
| BP10G_SDP0_DATA) != 0 ? 0 : 1); |
| |
| } |
| return BP_NOT_CAP; |
| } |
| |
| static int bp_force_link_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (DBI_IF_SERIES(pbpctl_dev->subdevice)) { |
| |
| if ((pbpctl_dev->bp_10g) || (pbpctl_dev->bp_10g9)) { |
| return ((BP10G_READ_REG(pbpctl_dev, ESDP) & |
| BP10G_SDP1_DIR) != 0 ? 1 : 0); |
| |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int bypass_from_last_read(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t ctrl_ext = 0; |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| |
| if ((pbpctl_dev->bp_caps & SW_CTL_CAP) |
| && (pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) { |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT); |
| BPCTL_BP_WRITE_REG(pbpctl_dev_b, CTRL_EXT, |
| (ctrl_ext & ~BPCTLI_CTRL_EXT_SDP7_DIR)); |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT); |
| if (ctrl_ext & BPCTLI_CTRL_EXT_SDP7_DATA) |
| return 0; |
| return 1; |
| } else |
| return BP_NOT_CAP; |
| } |
| |
| int bypass_status_clear(bpctl_dev_t *pbpctl_dev) |
| { |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| |
| if ((pbpctl_dev->bp_caps & SW_CTL_CAP) |
| && (pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) { |
| |
| send_bypass_clear_pulse(pbpctl_dev_b, 1); |
| return 0; |
| } else |
| return BP_NOT_CAP; |
| } |
| |
| int bypass_flag_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if ((pbpctl_dev->bp_caps & BP_CAP)) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & |
| BYPASS_FLAG_MASK) == |
| BYPASS_FLAG_MASK) ? 1 : 0); |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int bypass_flag_status_clear(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & BP_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| uint32_t status_reg = 0; |
| status_reg = read_reg(pbpctl_dev, STATUS_REG_ADDR); |
| write_reg(pbpctl_dev, status_reg & ~BYPASS_FLAG_MASK, |
| STATUS_REG_ADDR); |
| return 0; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int bypass_change_status(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| |
| if (pbpctl_dev->bp_caps & BP_STATUS_CHANGE_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= 0x8) { |
| ret = bypass_flag_status(pbpctl_dev); |
| bypass_flag_status_clear(pbpctl_dev); |
| } else if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| ret = bypass_flag_status(pbpctl_dev); |
| bypass_flag_status_clear(pbpctl_dev); |
| } else { |
| ret = bypass_from_last_read(pbpctl_dev); |
| bypass_status_clear(pbpctl_dev); |
| } |
| } |
| return ret; |
| } |
| |
| int bypass_off_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & BP_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & |
| BYPASS_OFF_MASK) == BYPASS_OFF_MASK) ? 1 : 0); |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| static int bypass_status(bpctl_dev_t *pbpctl_dev) |
| { |
| u32 ctrl_ext = 0; |
| if (pbpctl_dev->bp_caps & BP_CAP) { |
| |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| |
| if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) |
| return BP_NOT_CAP; |
| |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { |
| |
| if (!pbpctl_dev->bp_status_un) |
| return (((BPCTL_READ_REG |
| (pbpctl_dev_b, |
| CTRL_EXT)) & |
| BPCTLI_CTRL_EXT_SDP7_DATA) != |
| 0 ? 1 : 0); |
| else |
| return BP_NOT_CAP; |
| } |
| if (pbpctl_dev->bp_ext_ver >= 0x8) { |
| |
| if (pbpctl_dev->bp_10g9) { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL); |
| BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL, |
| (ctrl_ext | BP10G_I2C_CLK_OUT)); |
| return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) & |
| BP10G_I2C_CLK_IN) != 0 ? 0 : 1); |
| |
| } else if (pbpctl_dev->bp_540) { |
| return (((BP10G_READ_REG(pbpctl_dev_b, ESDP)) & |
| BP10G_SDP0_DATA) != 0 ? 0 : 1); |
| } |
| |
| else if ((pbpctl_dev->bp_fiber5) |
| || (pbpctl_dev->bp_i80)) { |
| return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) & |
| BPCTLI_CTRL_SWDPIN0) != 0 ? 0 : 1); |
| } else if (pbpctl_dev->bp_10gb) { |
| ctrl_ext = |
| BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO); |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO, |
| (ctrl_ext | BP10GB_GPIO3_OE_P0) |
| & ~(BP10GB_GPIO3_SET_P0 | |
| BP10GB_GPIO3_CLR_P0)); |
| |
| return (((BP10GB_READ_REG |
| (pbpctl_dev, |
| MISC_REG_GPIO)) & BP10GB_GPIO3_P0) != |
| 0 ? 0 : 1); |
| } |
| |
| else if (!pbpctl_dev->bp_10g) |
| return (((BPCTL_READ_REG |
| (pbpctl_dev_b, |
| CTRL_EXT)) & |
| BPCTLI_CTRL_EXT_SDP7_DATA) != |
| 0 ? 0 : 1); |
| |
| else { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP); |
| BP10G_WRITE_REG(pbpctl_dev_b, EODSDP, |
| (ctrl_ext | |
| BP10G_SDP7_DATA_OUT)); |
| return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) & |
| BP10G_SDP7_DATA_IN) != 0 ? 0 : 1); |
| } |
| |
| } else if (pbpctl_dev->media_type == bp_copper) { |
| |
| return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) & |
| BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0); |
| } else { |
| if ((bypass_status_clear(pbpctl_dev)) >= 0) |
| return bypass_from_last_read(pbpctl_dev); |
| } |
| |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int default_pwron_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| return ((((read_reg |
| (pbpctl_dev, |
| STATUS_REG_ADDR)) & DFLT_PWRON_MASK) |
| == DFLT_PWRON_MASK) ? 0 : 1); |
| } |
| } /*else if ((!pbpctl_dev->bp_caps&BP_DIS_CAP)&& |
| (pbpctl_dev->bp_caps&BP_PWUP_ON_CAP)) |
| return 1; */ |
| } |
| return BP_NOT_CAP; |
| } |
| |
| static int default_pwroff_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| /*if ((!pbpctl_dev->bp_caps&BP_DIS_CAP)&& |
| (pbpctl_dev->bp_caps&BP_PWOFF_ON_CAP)) |
| return 1; */ |
| if ((pbpctl_dev->bp_caps & SW_CTL_CAP) |
| && (pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) { |
| return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & |
| DFLT_PWROFF_MASK) == DFLT_PWROFF_MASK) ? 0 : 1); |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int dis_bypass_cap_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & BP_DIS_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & |
| DIS_BYPASS_CAP_MASK) == |
| DIS_BYPASS_CAP_MASK) ? 1 : 0); |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int cmd_en_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & |
| CMND_EN_MASK) == CMND_EN_MASK) ? 1 : 0); |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int wdt_en_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| return ((((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & |
| WDT_EN_MASK) == WDT_EN_MASK) ? 1 : 0); |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int wdt_programmed(bpctl_dev_t *pbpctl_dev, int *timeout) |
| { |
| int ret = 0; |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| if ((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & |
| WDT_EN_MASK) { |
| u8 wdt_val; |
| wdt_val = read_reg(pbpctl_dev, WDT_REG_ADDR); |
| *timeout = (1 << wdt_val) * 100; |
| } else |
| *timeout = 0; |
| } else { |
| int curr_wdt_status = pbpctl_dev->wdt_status; |
| if (curr_wdt_status == WDT_STATUS_UNKNOWN) |
| *timeout = -1; |
| else |
| *timeout = |
| curr_wdt_status == |
| 0 ? 0 : pbpctl_dev->bypass_timer_interval; |
| }; |
| } else |
| ret = BP_NOT_CAP; |
| return ret; |
| } |
| |
| int bypass_support(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { |
| ret = |
| ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) & |
| BYPASS_SUPPORT_MASK) == |
| BYPASS_SUPPORT_MASK) ? 1 : 0); |
| } else if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) |
| ret = 1; |
| } else |
| ret = BP_NOT_CAP; |
| return ret; |
| } |
| |
| int tap_support(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { |
| ret = |
| ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) & |
| TAP_SUPPORT_MASK) == TAP_SUPPORT_MASK) ? 1 : 0); |
| } else if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) |
| ret = 0; |
| } else |
| ret = BP_NOT_CAP; |
| return ret; |
| } |
| |
| int normal_support(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { |
| ret = |
| ((((read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR)) & |
| NORMAL_UNSUPPORT_MASK) == |
| NORMAL_UNSUPPORT_MASK) ? 0 : 1); |
| } else |
| ret = 1; |
| }; |
| return ret; |
| } |
| |
| int get_bp_prod_caps(bpctl_dev_t *pbpctl_dev) |
| { |
| if ((pbpctl_dev->bp_caps & SW_CTL_CAP) && |
| (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER)) |
| return read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR); |
| return BP_NOT_CAP; |
| |
| } |
| |
| int tap_flag_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) |
| return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & |
| TAP_FLAG_MASK) == TAP_FLAG_MASK) ? 1 : 0); |
| |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int tap_flag_status_clear(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t status_reg = 0; |
| if (pbpctl_dev->bp_caps & TAP_STATUS_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { |
| status_reg = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR); |
| write_reg(pbpctl_dev, status_reg & ~TAP_FLAG_MASK, |
| STATUS_TAP_REG_ADDR); |
| return 0; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int tap_change_status(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { |
| if (pbpctl_dev->bp_caps & TAP_CAP) { |
| if (pbpctl_dev->bp_caps & BP_CAP) { |
| ret = tap_flag_status(pbpctl_dev); |
| tap_flag_status_clear(pbpctl_dev); |
| } else { |
| ret = bypass_from_last_read(pbpctl_dev); |
| bypass_status_clear(pbpctl_dev); |
| } |
| } |
| } |
| return ret; |
| } |
| |
| int tap_off_status(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & TAP_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) |
| return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & |
| TAP_OFF_MASK) == TAP_OFF_MASK) ? 1 : 0); |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int tap_status(bpctl_dev_t *pbpctl_dev) |
| { |
| u32 ctrl_ext = 0; |
| |
| if (pbpctl_dev->bp_caps & TAP_CAP) { |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| |
| if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) |
| return BP_NOT_CAP; |
| |
| if (pbpctl_dev->bp_ext_ver >= 0x8) { |
| if (!pbpctl_dev->bp_10g) |
| return (((BPCTL_READ_REG |
| (pbpctl_dev_b, |
| CTRL_EXT)) & |
| BPCTLI_CTRL_EXT_SDP6_DATA) != |
| 0 ? 0 : 1); |
| else { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP); |
| BP10G_WRITE_REG(pbpctl_dev_b, EODSDP, |
| (ctrl_ext | |
| BP10G_SDP6_DATA_OUT)); |
| return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) & |
| BP10G_SDP6_DATA_IN) != 0 ? 0 : 1); |
| } |
| |
| } else if (pbpctl_dev->media_type == bp_copper) |
| return (((BPCTL_READ_REG(pbpctl_dev, CTRL)) & |
| BPCTLI_CTRL_SWDPIN0) != 0 ? 1 : 0); |
| else { |
| if ((bypass_status_clear(pbpctl_dev)) >= 0) |
| return bypass_from_last_read(pbpctl_dev); |
| } |
| |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int default_pwron_tap_status(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) |
| return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & |
| DFLT_PWRON_TAP_MASK) == |
| DFLT_PWRON_TAP_MASK) ? 1 : 0); |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int dis_tap_cap_status(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) |
| return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & |
| DIS_TAP_CAP_MASK) == |
| DIS_TAP_CAP_MASK) ? 1 : 0); |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int disc_flag_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & DISC_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= 0x8) |
| return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & |
| DISC_FLAG_MASK) == DISC_FLAG_MASK) ? 1 : 0); |
| |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int disc_flag_status_clear(bpctl_dev_t *pbpctl_dev) |
| { |
| uint32_t status_reg = 0; |
| if (pbpctl_dev->bp_caps & DISC_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= 0x8) { |
| status_reg = read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR); |
| write_reg(pbpctl_dev, status_reg & ~DISC_FLAG_MASK, |
| STATUS_DISC_REG_ADDR); |
| return BP_OK; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int disc_change_status(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| if (pbpctl_dev->bp_caps & DISC_CAP) { |
| ret = disc_flag_status(pbpctl_dev); |
| disc_flag_status_clear(pbpctl_dev); |
| return ret; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int disc_off_status(bpctl_dev_t *pbpctl_dev) |
| { |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| u32 ctrl_ext = 0; |
| |
| if (pbpctl_dev->bp_caps & DISC_CAP) { |
| if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) |
| return BP_NOT_CAP; |
| if (DISCF_IF_SERIES(pbpctl_dev->subdevice)) |
| return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & |
| DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0); |
| |
| if (pbpctl_dev->bp_i80) { |
| return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT)) & |
| BPCTLI_CTRL_EXT_SDP6_DATA) != 0 ? 1 : 0); |
| |
| } |
| if (pbpctl_dev->bp_540) { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, ESDP); |
| return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) & |
| BP10G_SDP2_DATA) != 0 ? 1 : 0); |
| |
| } |
| if (pbpctl_dev->media_type == bp_copper) { |
| |
| #if 0 |
| return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & |
| DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0); |
| #endif |
| if (!pbpctl_dev->bp_10g) |
| return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) & |
| BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0); |
| else |
| return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) & |
| BP10G_SDP1_DATA) != 0 ? 1 : 0); |
| |
| } else { |
| |
| if (pbpctl_dev->bp_10g9) { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL); |
| BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL, |
| (ctrl_ext | |
| BP10G_I2C_DATA_OUT)); |
| return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) & |
| BP10G_I2C_DATA_IN) != 0 ? 1 : 0); |
| |
| } else if (pbpctl_dev->bp_fiber5) { |
| return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) & |
| BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0); |
| } else if (pbpctl_dev->bp_10gb) { |
| ctrl_ext = |
| BP10GB_READ_REG(pbpctl_dev, MISC_REG_GPIO); |
| BP10GB_WRITE_REG(pbpctl_dev, MISC_REG_GPIO, |
| (ctrl_ext | BP10GB_GPIO3_OE_P1) |
| & ~(BP10GB_GPIO3_SET_P1 | |
| BP10GB_GPIO3_CLR_P1)); |
| |
| return (((BP10GB_READ_REG |
| (pbpctl_dev, |
| MISC_REG_GPIO)) & BP10GB_GPIO3_P1) != |
| 0 ? 1 : 0); |
| } |
| if (!pbpctl_dev->bp_10g) { |
| |
| return (((BPCTL_READ_REG |
| (pbpctl_dev_b, |
| CTRL_EXT)) & |
| BPCTLI_CTRL_EXT_SDP6_DATA) != |
| 0 ? 1 : 0); |
| } else { |
| ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, EODSDP); |
| BP10G_WRITE_REG(pbpctl_dev_b, EODSDP, |
| (ctrl_ext | |
| BP10G_SDP6_DATA_OUT)); |
| return (((BP10G_READ_REG(pbpctl_dev_b, EODSDP)) |
| & BP10G_SDP6_DATA_IN) != 0 ? 1 : 0); |
| } |
| |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| static int disc_status(bpctl_dev_t *pbpctl_dev) |
| { |
| int ctrl = 0; |
| if (pbpctl_dev->bp_caps & DISC_CAP) { |
| |
| if ((ctrl = disc_off_status(pbpctl_dev)) < 0) |
| return ctrl; |
| return ((ctrl == 0) ? 1 : 0); |
| |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int default_pwron_disc_status(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= 0x8) |
| return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & |
| DFLT_PWRON_DISC_MASK) == |
| DFLT_PWRON_DISC_MASK) ? 1 : 0); |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int dis_disc_cap_status(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & DIS_DISC_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= 0x8) |
| return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & |
| DIS_DISC_CAP_MASK) == |
| DIS_DISC_CAP_MASK) ? 1 : 0); |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int disc_port_status(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| bpctl_dev_t *pbpctl_dev_m; |
| |
| if ((is_bypass_fn(pbpctl_dev)) == 1) |
| pbpctl_dev_m = pbpctl_dev; |
| else |
| pbpctl_dev_m = get_master_port_fn(pbpctl_dev); |
| if (pbpctl_dev_m == NULL) |
| return BP_NOT_CAP; |
| |
| if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { |
| if (is_bypass_fn(pbpctl_dev) == 1) { |
| return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & |
| TX_DISA_MASK) == TX_DISA_MASK) ? 1 : 0); |
| } else |
| return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & |
| TX_DISB_MASK) == TX_DISB_MASK) ? 1 : 0); |
| |
| } |
| return ret; |
| } |
| |
| int default_pwron_disc_port_status(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| bpctl_dev_t *pbpctl_dev_m; |
| |
| if ((is_bypass_fn(pbpctl_dev)) == 1) |
| pbpctl_dev_m = pbpctl_dev; |
| else |
| pbpctl_dev_m = get_master_port_fn(pbpctl_dev); |
| if (pbpctl_dev_m == NULL) |
| return BP_NOT_CAP; |
| |
| if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) { |
| if (is_bypass_fn(pbpctl_dev) == 1) |
| return ret; |
| /* return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); */ |
| else |
| return ret; |
| /* return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); */ |
| |
| } |
| return ret; |
| } |
| |
| int wdt_exp_mode_status(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver <= PXG2BPI_VER) |
| return 0; /* bypass mode */ |
| else if (pbpctl_dev->bp_ext_ver == PXG2TBPI_VER) |
| return 1; /* tap mode */ |
| else if (pbpctl_dev->bp_ext_ver >= PXE2TBPI_VER) { |
| if (pbpctl_dev->bp_ext_ver >= 0x8) { |
| if (((read_reg |
| (pbpctl_dev, |
| STATUS_DISC_REG_ADDR)) & |
| WDTE_DISC_BPN_MASK) == WDTE_DISC_BPN_MASK) |
| return 2; |
| } |
| return ((((read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR)) & |
| WDTE_TAP_BPN_MASK) == |
| WDTE_TAP_BPN_MASK) ? 1 : 0); |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int tpl2_flag_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) { |
| return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & |
| TPL2_FLAG_MASK) == TPL2_FLAG_MASK) ? 1 : 0); |
| |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int tpl_hw_status(bpctl_dev_t *pbpctl_dev) |
| { |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| |
| if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) |
| return BP_NOT_CAP; |
| |
| if (TPL_IF_SERIES(pbpctl_dev->subdevice)) |
| return (((BPCTL_READ_REG(pbpctl_dev, CTRL)) & |
| BPCTLI_CTRL_SWDPIN0) != 0 ? 1 : 0); |
| return BP_NOT_CAP; |
| } |
| |
| |
| int bp_wait_at_pwup_status(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| if (pbpctl_dev->bp_ext_ver >= 0x8) |
| return ((((read_reg(pbpctl_dev, CONT_CONFIG_REG_ADDR)) & |
| WAIT_AT_PWUP_MASK) == |
| WAIT_AT_PWUP_MASK) ? 1 : 0); |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int bp_hw_reset_status(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| |
| if (pbpctl_dev->bp_ext_ver >= 0x8) |
| return ((((read_reg(pbpctl_dev, CONT_CONFIG_REG_ADDR)) & |
| EN_HW_RESET_MASK) == |
| EN_HW_RESET_MASK) ? 1 : 0); |
| } |
| return BP_NOT_CAP; |
| } |
| |
| |
| int std_nic_status(bpctl_dev_t *pbpctl_dev) |
| { |
| int status_val = 0; |
| |
| if (pbpctl_dev->bp_caps & STD_NIC_CAP) { |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) |
| return BP_NOT_CAP; |
| if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { |
| return ((((read_reg(pbpctl_dev, STATUS_DISC_REG_ADDR)) & |
| STD_NIC_ON_MASK) == STD_NIC_ON_MASK) ? 1 : 0); |
| } |
| |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| if (pbpctl_dev->bp_caps & BP_CAP) { |
| status_val = |
| read_reg(pbpctl_dev, STATUS_REG_ADDR); |
| if (((!(status_val & WDT_EN_MASK)) |
| && ((status_val & STD_NIC_MASK) == |
| STD_NIC_MASK))) |
| status_val = 1; |
| else |
| return 0; |
| } |
| if (pbpctl_dev->bp_caps & TAP_CAP) { |
| status_val = |
| read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR); |
| if ((status_val & STD_NIC_TAP_MASK) == |
| STD_NIC_TAP_MASK) |
| status_val = 1; |
| else |
| return 0; |
| } |
| if (pbpctl_dev->bp_caps & TAP_CAP) { |
| if ((disc_off_status(pbpctl_dev))) |
| status_val = 1; |
| else |
| return 0; |
| } |
| |
| return status_val; |
| } |
| } |
| return BP_NOT_CAP; |
| } |
| |
| /******************************************************/ |
| /**************SW_INIT*********************************/ |
| /******************************************************/ |
| void bypass_caps_init(bpctl_dev_t *pbpctl_dev) |
| { |
| u_int32_t ctrl_ext = 0; |
| bpctl_dev_t *pbpctl_dev_m = NULL; |
| |
| #ifdef BYPASS_DEBUG |
| int ret = 0; |
| if (!(INTEL_IF_SERIES(adapter->bp_device_block.subdevice))) { |
| ret = read_reg(pbpctl_dev, VER_REG_ADDR); |
| printk("VER_REG reg1=%x\n", ret); |
| ret = read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR); |
| printk("PRODUCT_CAP reg=%x\n", ret); |
| ret = read_reg(pbpctl_dev, STATUS_TAP_REG_ADDR); |
| printk("STATUS_TAP reg1=%x\n", ret); |
| ret = read_reg(pbpctl_dev, 0x7); |
| printk("SIG_REG reg1=%x\n", ret); |
| ret = read_reg(pbpctl_dev, STATUS_REG_ADDR); |
| printk("STATUS_REG_ADDR=%x\n", ret); |
| ret = read_reg(pbpctl_dev, WDT_REG_ADDR); |
| printk("WDT_REG_ADDR=%x\n", ret); |
| ret = read_reg(pbpctl_dev, TMRL_REG_ADDR); |
| printk("TMRL_REG_ADDR=%x\n", ret); |
| ret = read_reg(pbpctl_dev, TMRH_REG_ADDR); |
| printk("TMRH_REG_ADDR=%x\n", ret); |
| } |
| #endif |
| if ((pbpctl_dev->bp_fiber5) || (pbpctl_dev->bp_10g9)) { |
| pbpctl_dev->media_type = bp_fiber; |
| } else if (pbpctl_dev->bp_10gb) { |
| if (BP10GB_CX4_SERIES(pbpctl_dev->subdevice)) |
| pbpctl_dev->media_type = bp_cx4; |
| else |
| pbpctl_dev->media_type = bp_fiber; |
| |
| } |
| |
| else if (pbpctl_dev->bp_540) |
| pbpctl_dev->media_type = bp_none; |
| else if (!pbpctl_dev->bp_10g) { |
| |
| ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT); |
| if ((ctrl_ext & BPCTLI_CTRL_EXT_LINK_MODE_MASK) == 0x0) |
| pbpctl_dev->media_type = bp_copper; |
| else |
| pbpctl_dev->media_type = bp_fiber; |
| |
| } else { |
| if (BP10G_CX4_SERIES(pbpctl_dev->subdevice)) |
| pbpctl_dev->media_type = bp_cx4; |
| else |
| pbpctl_dev->media_type = bp_fiber; |
| } |
| |
| if (is_bypass_fn(pbpctl_dev)) { |
| |
| pbpctl_dev->bp_caps |= BP_PWOFF_ON_CAP; |
| if (pbpctl_dev->media_type == bp_fiber) |
| pbpctl_dev->bp_caps |= |
| (TX_CTL_CAP | TX_STATUS_CAP | TPL_CAP); |
| |
| if (TPL_IF_SERIES(pbpctl_dev->subdevice)) { |
| pbpctl_dev->bp_caps |= TPL_CAP; |
| } |
| |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) { |
| pbpctl_dev->bp_caps |= |
| (BP_CAP | BP_STATUS_CAP | SW_CTL_CAP | |
| BP_PWUP_ON_CAP | BP_PWUP_OFF_CAP | BP_PWOFF_OFF_CAP |
| | WD_CTL_CAP | WD_STATUS_CAP | STD_NIC_CAP | |
| WD_TIMEOUT_CAP); |
| |
| pbpctl_dev->bp_ext_ver = OLD_IF_VER; |
| return; |
| } |
| |
| if ((pbpctl_dev->bp_fw_ver == 0xff) && |
| OLD_IF_SERIES(pbpctl_dev->subdevice)) { |
| |
| pbpctl_dev->bp_caps |= |
| (BP_CAP | BP_STATUS_CAP | BP_STATUS_CHANGE_CAP | |
| SW_CTL_CAP | BP_PWUP_ON_CAP | WD_CTL_CAP | |
| WD_STATUS_CAP | WD_TIMEOUT_CAP); |
| |
| pbpctl_dev->bp_ext_ver = OLD_IF_VER; |
| return; |
| } |
| |
| else { |
| switch (pbpctl_dev->bp_fw_ver) { |
| case BP_FW_VER_A0: |
| case BP_FW_VER_A1:{ |
| pbpctl_dev->bp_ext_ver = |
| (pbpctl_dev-> |
| bp_fw_ver & EXT_VER_MASK); |
| break; |
| } |
| default:{ |
| if ((bypass_sign_check(pbpctl_dev)) != |
| 1) { |
| pbpctl_dev->bp_caps = 0; |
| return; |
| } |
| pbpctl_dev->bp_ext_ver = |
| (pbpctl_dev-> |
| bp_fw_ver & EXT_VER_MASK); |
| } |
| } |
| } |
| |
| if (pbpctl_dev->bp_ext_ver == PXG2BPI_VER) |
| pbpctl_dev->bp_caps |= |
| (BP_CAP | BP_STATUS_CAP | BP_STATUS_CHANGE_CAP | |
| SW_CTL_CAP | BP_DIS_CAP | BP_DIS_STATUS_CAP | |
| BP_PWUP_ON_CAP | BP_PWUP_OFF_CAP | BP_PWUP_CTL_CAP |
| | WD_CTL_CAP | STD_NIC_CAP | WD_STATUS_CAP | |
| WD_TIMEOUT_CAP); |
| else if (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER) { |
| int cap_reg; |
| |
| pbpctl_dev->bp_caps |= |
| (SW_CTL_CAP | WD_CTL_CAP | WD_STATUS_CAP | |
| WD_TIMEOUT_CAP); |
| cap_reg = get_bp_prod_caps(pbpctl_dev); |
| |
| if ((cap_reg & NORMAL_UNSUPPORT_MASK) == |
| NORMAL_UNSUPPORT_MASK) |
| pbpctl_dev->bp_caps |= NIC_CAP_NEG; |
| else |
| pbpctl_dev->bp_caps |= STD_NIC_CAP; |
| |
| if ((normal_support(pbpctl_dev)) == 1) |
| |
| pbpctl_dev->bp_caps |= STD_NIC_CAP; |
| |
| else |
| pbpctl_dev->bp_caps |= NIC_CAP_NEG; |
| if ((cap_reg & BYPASS_SUPPORT_MASK) == |
| BYPASS_SUPPORT_MASK) { |
| pbpctl_dev->bp_caps |= |
| (BP_CAP | BP_STATUS_CAP | |
| BP_STATUS_CHANGE_CAP | BP_DIS_CAP | |
| BP_DIS_STATUS_CAP | BP_PWUP_ON_CAP | |
| BP_PWUP_OFF_CAP | BP_PWUP_CTL_CAP); |
| if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER7) |
| pbpctl_dev->bp_caps |= |
| BP_PWOFF_ON_CAP | BP_PWOFF_OFF_CAP | |
| BP_PWOFF_CTL_CAP; |
| } |
| if ((cap_reg & TAP_SUPPORT_MASK) == TAP_SUPPORT_MASK) { |
| pbpctl_dev->bp_caps |= |
| (TAP_CAP | TAP_STATUS_CAP | |
| TAP_STATUS_CHANGE_CAP | TAP_DIS_CAP | |
| TAP_DIS_STATUS_CAP | TAP_PWUP_ON_CAP | |
| TAP_PWUP_OFF_CAP | TAP_PWUP_CTL_CAP); |
| } |
| if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER8) { |
| if ((cap_reg & DISC_SUPPORT_MASK) == |
| DISC_SUPPORT_MASK) |
| pbpctl_dev->bp_caps |= |
| (DISC_CAP | DISC_DIS_CAP | |
| DISC_PWUP_CTL_CAP); |
| if ((cap_reg & TPL2_SUPPORT_MASK) == |
| TPL2_SUPPORT_MASK) { |
| pbpctl_dev->bp_caps_ex |= TPL2_CAP_EX; |
| pbpctl_dev->bp_caps |= TPL_CAP; |
| pbpctl_dev->bp_tpl_flag = |
| tpl2_flag_status(pbpctl_dev); |
| } |
| |
| } |
| |
| if (pbpctl_dev->bp_ext_ver >= BP_FW_EXT_VER9) { |
| if ((cap_reg & DISC_PORT_SUPPORT_MASK) == |
| DISC_PORT_SUPPORT_MASK) { |
| pbpctl_dev->bp_caps_ex |= |
| DISC_PORT_CAP_EX; |
| pbpctl_dev->bp_caps |= |
| (TX_CTL_CAP | TX_STATUS_CAP); |
| } |
| |
| } |
| |
| } |
| if (pbpctl_dev->bp_ext_ver >= PXG2BPI_VER) { |
| if ((read_reg(pbpctl_dev, STATUS_REG_ADDR)) & |
| WDT_EN_MASK) |
| pbpctl_dev->wdt_status = WDT_STATUS_EN; |
| else |
| pbpctl_dev->wdt_status = WDT_STATUS_DIS; |
| } |
| |
| } else if ((P2BPFI_IF_SERIES(pbpctl_dev->subdevice)) || |
| (PEGF5_IF_SERIES(pbpctl_dev->subdevice)) || |
| (PEGF80_IF_SERIES(pbpctl_dev->subdevice)) || |
| (BP10G9_IF_SERIES(pbpctl_dev->subdevice))) { |
| pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP); |
| } |
| if ((pbpctl_dev->subdevice & 0xa00) == 0xa00) |
| pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP); |
| if (PEG5_IF_SERIES(pbpctl_dev->subdevice)) |
| pbpctl_dev->bp_caps |= (TX_CTL_CAP | TX_STATUS_CAP); |
| |
| if (BP10GB_IF_SERIES(pbpctl_dev->subdevice)) { |
| pbpctl_dev->bp_caps &= ~(TX_CTL_CAP | TX_STATUS_CAP); |
| } |
| pbpctl_dev_m = get_master_port_fn(pbpctl_dev); |
| if (pbpctl_dev_m != NULL) { |
| int cap_reg = 0; |
| if (pbpctl_dev_m->bp_ext_ver >= 0x9) { |
| cap_reg = get_bp_prod_caps(pbpctl_dev_m); |
| if ((cap_reg & DISC_PORT_SUPPORT_MASK) == |
| DISC_PORT_SUPPORT_MASK) |
| pbpctl_dev->bp_caps |= |
| (TX_CTL_CAP | TX_STATUS_CAP); |
| pbpctl_dev->bp_caps_ex |= DISC_PORT_CAP_EX; |
| } |
| } |
| } |
| |
| int bypass_off_init(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| |
| if ((ret = cmnd_on(pbpctl_dev)) < 0) |
| return ret; |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) |
| return dis_bypass_cap(pbpctl_dev); |
| wdt_off(pbpctl_dev); |
| if (pbpctl_dev->bp_caps & BP_CAP) |
| bypass_off(pbpctl_dev); |
| if (pbpctl_dev->bp_caps & TAP_CAP) |
| tap_off(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| return 0; |
| } |
| |
| void remove_bypass_wd_auto(bpctl_dev_t *pbpctl_dev) |
| { |
| #ifdef BP_SELF_TEST |
| bpctl_dev_t *pbpctl_dev_sl = NULL; |
| #endif |
| |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| |
| del_timer_sync(&pbpctl_dev->bp_timer); |
| #ifdef BP_SELF_TEST |
| pbpctl_dev_sl = get_status_port_fn(pbpctl_dev); |
| if (pbpctl_dev_sl && (pbpctl_dev_sl->ndev)) { |
| if ((pbpctl_dev_sl->ndev->netdev_ops) |
| && (pbpctl_dev_sl->old_ops)) { |
| rtnl_lock(); |
| pbpctl_dev_sl->ndev->netdev_ops = |
| pbpctl_dev_sl->old_ops; |
| pbpctl_dev_sl->old_ops = NULL; |
| |
| rtnl_unlock(); |
| |
| } |
| |
| } |
| #endif |
| } |
| |
| } |
| |
| int init_bypass_wd_auto(bpctl_dev_t *pbpctl_dev) |
| { |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| init_timer(&pbpctl_dev->bp_timer); |
| pbpctl_dev->bp_timer.function = &wd_reset_timer; |
| pbpctl_dev->bp_timer.data = (unsigned long)pbpctl_dev; |
| return 1; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| #ifdef BP_SELF_TEST |
| int bp_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) |
| { |
| bpctl_dev_t *pbpctl_dev = NULL, *pbpctl_dev_m = NULL; |
| int idx_dev = 0; |
| struct ethhdr *eth = (struct ethhdr *)skb->data; |
| |
| for (idx_dev = 0; |
| ((bpctl_dev_arr[idx_dev].ndev != NULL) && (idx_dev < device_num)); |
| idx_dev++) { |
| if (bpctl_dev_arr[idx_dev].ndev == dev) { |
| pbpctl_dev = &bpctl_dev_arr[idx_dev]; |
| break; |
| } |
| } |
| if (!pbpctl_dev) |
| return 1; |
| if ((htons(ETH_P_BPTEST) == eth->h_proto)) { |
| |
| pbpctl_dev_m = get_master_port_fn(pbpctl_dev); |
| if (pbpctl_dev_m) { |
| |
| if (bypass_status(pbpctl_dev_m)) { |
| cmnd_on(pbpctl_dev_m); |
| bypass_off(pbpctl_dev_m); |
| cmnd_off(pbpctl_dev_m); |
| } |
| wdt_timer_reload(pbpctl_dev_m); |
| } |
| dev_kfree_skb_irq(skb); |
| return 0; |
| } |
| return pbpctl_dev->hard_start_xmit_save(skb, dev); |
| } |
| #endif |
| |
| int set_bypass_wd_auto(bpctl_dev_t *pbpctl_dev, unsigned int param) |
| { |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| if (pbpctl_dev->reset_time != param) { |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) |
| pbpctl_dev->reset_time = |
| (param < |
| WDT_AUTO_MIN_INT) ? WDT_AUTO_MIN_INT : |
| param; |
| else |
| pbpctl_dev->reset_time = param; |
| if (param) |
| mod_timer(&pbpctl_dev->bp_timer, jiffies); |
| } |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int get_bypass_wd_auto(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| return pbpctl_dev->reset_time; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| #ifdef BP_SELF_TEST |
| |
| int set_bp_self_test(bpctl_dev_t *pbpctl_dev, unsigned int param) |
| { |
| bpctl_dev_t *pbpctl_dev_sl = NULL; |
| |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| pbpctl_dev->bp_self_test_flag = param == 0 ? 0 : 1; |
| pbpctl_dev_sl = get_status_port_fn(pbpctl_dev); |
| |
| if ((pbpctl_dev_sl->ndev) && (pbpctl_dev_sl->ndev->netdev_ops)) { |
| rtnl_lock(); |
| if (pbpctl_dev->bp_self_test_flag == 1) { |
| |
| pbpctl_dev_sl->old_ops = |
| pbpctl_dev_sl->ndev->netdev_ops; |
| pbpctl_dev_sl->new_ops = |
| *pbpctl_dev_sl->old_ops; |
| pbpctl_dev_sl->new_ops.ndo_start_xmit = |
| bp_hard_start_xmit; |
| pbpctl_dev_sl->ndev->netdev_ops = |
| &pbpctl_dev_sl->new_ops; |
| |
| } else if (pbpctl_dev_sl->old_ops) { |
| pbpctl_dev_sl->ndev->netdev_ops = |
| pbpctl_dev_sl->old_ops; |
| pbpctl_dev_sl->old_ops = NULL; |
| } |
| rtnl_unlock(); |
| } |
| |
| set_bypass_wd_auto(pbpctl_dev, param); |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int get_bp_self_test(bpctl_dev_t *pbpctl_dev) |
| { |
| |
| if (pbpctl_dev->bp_caps & WD_CTL_CAP) { |
| if (pbpctl_dev->bp_self_test_flag == 1) |
| return pbpctl_dev->reset_time; |
| else |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| #endif |
| |
| /**************************************************************/ |
| /************************* API ********************************/ |
| /**************************************************************/ |
| |
| int is_bypass_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return (((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) ? 1 : 0); |
| } |
| |
| int set_bypass_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode) |
| { |
| int ret = 0; |
| |
| if (!(pbpctl_dev->bp_caps & BP_CAP)) |
| return BP_NOT_CAP; |
| if ((ret = cmnd_on(pbpctl_dev)) < 0) |
| return ret; |
| if (!bypass_mode) |
| ret = bypass_off(pbpctl_dev); |
| else |
| ret = bypass_on(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| |
| return ret; |
| } |
| |
| int get_bypass_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| return bypass_status(pbpctl_dev); |
| } |
| |
| int get_bypass_change_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return bypass_change_status(pbpctl_dev); |
| } |
| |
| int set_dis_bypass_fn(bpctl_dev_t *pbpctl_dev, int dis_param) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (!(pbpctl_dev->bp_caps & BP_DIS_CAP)) |
| return BP_NOT_CAP; |
| if ((ret = cmnd_on(pbpctl_dev)) < 0) |
| return ret; |
| if (dis_param) |
| ret = dis_bypass_cap(pbpctl_dev); |
| else |
| ret = en_bypass_cap(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| return ret; |
| } |
| |
| int get_dis_bypass_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return dis_bypass_cap_status(pbpctl_dev); |
| } |
| |
| int set_bypass_pwoff_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (!(pbpctl_dev->bp_caps & BP_PWOFF_CTL_CAP)) |
| return BP_NOT_CAP; |
| if ((ret = cmnd_on(pbpctl_dev)) < 0) |
| return ret; |
| if (bypass_mode) |
| ret = bypass_state_pwroff(pbpctl_dev); |
| else |
| ret = normal_state_pwroff(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| return ret; |
| } |
| |
| int get_bypass_pwoff_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return default_pwroff_status(pbpctl_dev); |
| } |
| |
| int set_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (!(pbpctl_dev->bp_caps & BP_PWUP_CTL_CAP)) |
| return BP_NOT_CAP; |
| if ((ret = cmnd_on(pbpctl_dev)) < 0) |
| return ret; |
| if (bypass_mode) |
| ret = bypass_state_pwron(pbpctl_dev); |
| else |
| ret = normal_state_pwron(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| return ret; |
| } |
| |
| int get_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return default_pwron_status(pbpctl_dev); |
| } |
| |
| int set_bypass_wd_fn(bpctl_dev_t *pbpctl_dev, int timeout) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (!(pbpctl_dev->bp_caps & WD_CTL_CAP)) |
| return BP_NOT_CAP; |
| |
| if ((ret = cmnd_on(pbpctl_dev)) < 0) |
| return ret; |
| if (!timeout) |
| ret = wdt_off(pbpctl_dev); |
| else { |
| wdt_on(pbpctl_dev, timeout); |
| ret = pbpctl_dev->bypass_timer_interval; |
| } |
| cmnd_off(pbpctl_dev); |
| return ret; |
| } |
| |
| int get_bypass_wd_fn(bpctl_dev_t *pbpctl_dev, int *timeout) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return wdt_programmed(pbpctl_dev, timeout); |
| } |
| |
| int get_wd_expire_time_fn(bpctl_dev_t *pbpctl_dev, int *time_left) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return wdt_timer(pbpctl_dev, time_left); |
| } |
| |
| int reset_bypass_wd_timer_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return wdt_timer_reload(pbpctl_dev); |
| } |
| |
| int get_wd_set_caps_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| int bp_status = 0; |
| |
| unsigned int step_value = TIMEOUT_MAX_STEP + 1, bit_cnt = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (INTEL_IF_SERIES(pbpctl_dev->subdevice)) |
| return BP_NOT_CAP; |
| |
| while ((step_value >>= 1)) |
| bit_cnt++; |
| |
| if (is_bypass_fn(pbpctl_dev)) { |
| bp_status = |
| WD_STEP_COUNT_MASK(bit_cnt) | WDT_STEP_TIME | |
| WD_MIN_TIME_MASK(TIMEOUT_UNIT / 100); |
| } else |
| return -1; |
| |
| return bp_status; |
| } |
| |
| int set_std_nic_fn(bpctl_dev_t *pbpctl_dev, int nic_mode) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (!(pbpctl_dev->bp_caps & STD_NIC_CAP)) |
| return BP_NOT_CAP; |
| |
| if ((ret = cmnd_on(pbpctl_dev)) < 0) |
| return ret; |
| if (nic_mode) |
| ret = std_nic_on(pbpctl_dev); |
| else |
| ret = std_nic_off(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| return ret; |
| } |
| |
| int get_std_nic_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return std_nic_status(pbpctl_dev); |
| } |
| |
| int set_tap_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((pbpctl_dev->bp_caps & TAP_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) { |
| if (!tap_mode) |
| tap_off(pbpctl_dev); |
| else |
| tap_on(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int get_tap_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return tap_status(pbpctl_dev); |
| } |
| |
| int set_tap_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((pbpctl_dev->bp_caps & TAP_PWUP_CTL_CAP) |
| && ((cmnd_on(pbpctl_dev)) >= 0)) { |
| if (tap_mode) |
| ret = tap_state_pwron(pbpctl_dev); |
| else |
| ret = normal_state_pwron(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| } else |
| ret = BP_NOT_CAP; |
| return ret; |
| } |
| |
| int get_tap_pwup_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((ret = default_pwron_tap_status(pbpctl_dev)) < 0) |
| return ret; |
| return ((ret == 0) ? 1 : 0); |
| } |
| |
| int get_tap_change_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return tap_change_status(pbpctl_dev); |
| } |
| |
| int set_dis_tap_fn(bpctl_dev_t *pbpctl_dev, int dis_param) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((pbpctl_dev->bp_caps & TAP_DIS_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) { |
| if (dis_param) |
| ret = dis_tap_cap(pbpctl_dev); |
| else |
| ret = en_tap_cap(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| return ret; |
| } else |
| return BP_NOT_CAP; |
| } |
| |
| int get_dis_tap_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return dis_tap_cap_status(pbpctl_dev); |
| } |
| |
| int set_disc_fn(bpctl_dev_t *pbpctl_dev, int disc_mode) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((pbpctl_dev->bp_caps & DISC_CAP) && ((cmnd_on(pbpctl_dev)) >= 0)) { |
| if (!disc_mode) |
| disc_off(pbpctl_dev); |
| else |
| disc_on(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| |
| return BP_OK; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int get_disc_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| ret = disc_status(pbpctl_dev); |
| |
| return ret; |
| } |
| |
| int set_disc_pwup_fn(bpctl_dev_t *pbpctl_dev, int disc_mode) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((pbpctl_dev->bp_caps & DISC_PWUP_CTL_CAP) |
| && ((cmnd_on(pbpctl_dev)) >= 0)) { |
| if (disc_mode) |
| ret = disc_state_pwron(pbpctl_dev); |
| else |
| ret = normal_state_pwron(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| } else |
| ret = BP_NOT_CAP; |
| return ret; |
| } |
| |
| int get_disc_pwup_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| ret = default_pwron_disc_status(pbpctl_dev); |
| return (ret == 0 ? 1 : (ret < 0 ? BP_NOT_CAP : 0)); |
| } |
| |
| int get_disc_change_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| ret = disc_change_status(pbpctl_dev); |
| return ret; |
| } |
| |
| int set_dis_disc_fn(bpctl_dev_t *pbpctl_dev, int dis_param) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((pbpctl_dev->bp_caps & DISC_DIS_CAP) |
| && ((cmnd_on(pbpctl_dev)) >= 0)) { |
| if (dis_param) |
| ret = dis_disc_cap(pbpctl_dev); |
| else |
| ret = en_disc_cap(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| return ret; |
| } else |
| return BP_NOT_CAP; |
| } |
| |
| int get_dis_disc_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| ret = dis_disc_cap_status(pbpctl_dev); |
| |
| return ret; |
| } |
| |
| int set_disc_port_fn(bpctl_dev_t *pbpctl_dev, int disc_mode) |
| { |
| int ret = BP_NOT_CAP; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (!disc_mode) |
| ret = disc_port_off(pbpctl_dev); |
| else |
| ret = disc_port_on(pbpctl_dev); |
| |
| return ret; |
| } |
| |
| int get_disc_port_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return disc_port_status(pbpctl_dev); |
| } |
| |
| int set_disc_port_pwup_fn(bpctl_dev_t *pbpctl_dev, int disc_mode) |
| { |
| int ret = BP_NOT_CAP; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (!disc_mode) |
| ret = normal_port_state_pwron(pbpctl_dev); |
| else |
| ret = disc_port_state_pwron(pbpctl_dev); |
| |
| return ret; |
| } |
| |
| int get_disc_port_pwup_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((ret = default_pwron_disc_port_status(pbpctl_dev)) < 0) |
| return ret; |
| return ((ret == 0) ? 1 : 0); |
| } |
| |
| int get_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return wdt_exp_mode_status(pbpctl_dev); |
| } |
| |
| int set_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev, int param) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return wdt_exp_mode(pbpctl_dev, param); |
| } |
| |
| int reset_cont_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((ret = cmnd_on(pbpctl_dev)) < 0) |
| return ret; |
| return reset_cont(pbpctl_dev); |
| } |
| |
| int set_tx_fn(bpctl_dev_t *pbpctl_dev, int tx_state) |
| { |
| |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((pbpctl_dev->bp_caps & TPL_CAP) && |
| (pbpctl_dev->bp_caps & SW_CTL_CAP)) { |
| if ((pbpctl_dev->bp_tpl_flag)) |
| return BP_NOT_CAP; |
| } else if ((pbpctl_dev_b = get_master_port_fn(pbpctl_dev))) { |
| if ((pbpctl_dev_b->bp_caps & TPL_CAP) && |
| (pbpctl_dev_b->bp_tpl_flag)) |
| return BP_NOT_CAP; |
| } |
| return set_tx(pbpctl_dev, tx_state); |
| } |
| |
| int set_bp_force_link_fn(int dev_num, int tx_state) |
| { |
| static bpctl_dev_t *bpctl_dev_curr; |
| |
| if ((dev_num < 0) || (dev_num > device_num) |
| || (bpctl_dev_arr[dev_num].pdev == NULL)) |
| return -1; |
| bpctl_dev_curr = &bpctl_dev_arr[dev_num]; |
| |
| return set_bp_force_link(bpctl_dev_curr, tx_state); |
| } |
| |
| int set_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev, int param) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return set_bypass_wd_auto(pbpctl_dev, param); |
| } |
| |
| int get_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return get_bypass_wd_auto(pbpctl_dev); |
| } |
| |
| #ifdef BP_SELF_TEST |
| int set_bp_self_test_fn(bpctl_dev_t *pbpctl_dev, int param) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return set_bp_self_test(pbpctl_dev, param); |
| } |
| |
| int get_bp_self_test_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return get_bp_self_test(pbpctl_dev); |
| } |
| |
| #endif |
| |
| int get_bypass_caps_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| return pbpctl_dev->bp_caps; |
| |
| } |
| |
| int get_bypass_slave_fn(bpctl_dev_t *pbpctl_dev, bpctl_dev_t **pbpctl_dev_out) |
| { |
| int idx_dev = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) { |
| for (idx_dev = 0; |
| ((bpctl_dev_arr[idx_dev].pdev != NULL) |
| && (idx_dev < device_num)); idx_dev++) { |
| if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) |
| && (bpctl_dev_arr[idx_dev].slot == |
| pbpctl_dev->slot)) { |
| if ((pbpctl_dev->func == 0) |
| && (bpctl_dev_arr[idx_dev].func == 1)) { |
| *pbpctl_dev_out = |
| &bpctl_dev_arr[idx_dev]; |
| return 1; |
| } |
| if ((pbpctl_dev->func == 2) && |
| (bpctl_dev_arr[idx_dev].func == 3)) { |
| *pbpctl_dev_out = |
| &bpctl_dev_arr[idx_dev]; |
| return 1; |
| } |
| } |
| } |
| return -1; |
| } else |
| return 0; |
| } |
| |
| int is_bypass(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((pbpctl_dev->func == 0) || (pbpctl_dev->func == 2)) |
| return 1; |
| else |
| return 0; |
| } |
| |
| int get_tx_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if ((pbpctl_dev->bp_caps & TPL_CAP) && |
| (pbpctl_dev->bp_caps & SW_CTL_CAP)) { |
| if ((pbpctl_dev->bp_tpl_flag)) |
| return BP_NOT_CAP; |
| } else if ((pbpctl_dev_b = get_master_port_fn(pbpctl_dev))) { |
| if ((pbpctl_dev_b->bp_caps & TPL_CAP) && |
| (pbpctl_dev_b->bp_tpl_flag)) |
| return BP_NOT_CAP; |
| } |
| return tx_status(pbpctl_dev); |
| } |
| |
| int get_bp_force_link_fn(int dev_num) |
| { |
| static bpctl_dev_t *bpctl_dev_curr; |
| |
| if ((dev_num < 0) || (dev_num > device_num) |
| || (bpctl_dev_arr[dev_num].pdev == NULL)) |
| return -1; |
| bpctl_dev_curr = &bpctl_dev_arr[dev_num]; |
| |
| return bp_force_link_status(bpctl_dev_curr); |
| } |
| |
| static int get_bypass_link_status(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (pbpctl_dev->media_type == bp_fiber) |
| return ((BPCTL_READ_REG(pbpctl_dev, CTRL) & |
| BPCTLI_CTRL_SWDPIN1)); |
| else |
| return ((BPCTL_READ_REG(pbpctl_dev, STATUS) & |
| BPCTLI_STATUS_LU)); |
| |
| } |
| |
| static void bp_tpl_timer_fn(unsigned long param) |
| { |
| bpctl_dev_t *pbpctl_dev = (bpctl_dev_t *) param; |
| uint32_t link1, link2; |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| |
| if (!(pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) |
| return; |
| |
| if (!pbpctl_dev->bp_tpl_flag) { |
| set_tx(pbpctl_dev_b, 1); |
| set_tx(pbpctl_dev, 1); |
| return; |
| } |
| link1 = get_bypass_link_status(pbpctl_dev); |
| |
| link2 = get_bypass_link_status(pbpctl_dev_b); |
| if ((link1) && (tx_status(pbpctl_dev))) { |
| if ((!link2) && (tx_status(pbpctl_dev_b))) { |
| set_tx(pbpctl_dev, 0); |
| } else if (!tx_status(pbpctl_dev_b)) { |
| set_tx(pbpctl_dev_b, 1); |
| } |
| } else if ((!link1) && (tx_status(pbpctl_dev))) { |
| if ((link2) && (tx_status(pbpctl_dev_b))) { |
| set_tx(pbpctl_dev_b, 0); |
| } |
| } else if ((link1) && (!tx_status(pbpctl_dev))) { |
| if ((link2) && (tx_status(pbpctl_dev_b))) { |
| set_tx(pbpctl_dev, 1); |
| } |
| } else if ((!link1) && (!tx_status(pbpctl_dev))) { |
| if ((link2) && (tx_status(pbpctl_dev_b))) { |
| set_tx(pbpctl_dev, 1); |
| } |
| } |
| |
| mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies + BP_LINK_MON_DELAY * HZ); |
| } |
| |
| void remove_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev) |
| { |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| if (!pbpctl_dev) |
| return; |
| pbpctl_dev_b = get_status_port_fn(pbpctl_dev); |
| |
| if (pbpctl_dev->bp_caps & TPL_CAP) { |
| del_timer_sync(&pbpctl_dev->bp_tpl_timer); |
| pbpctl_dev->bp_tpl_flag = 0; |
| pbpctl_dev_b = get_status_port_fn(pbpctl_dev); |
| if (pbpctl_dev_b) |
| set_tx(pbpctl_dev_b, 1); |
| set_tx(pbpctl_dev, 1); |
| } |
| return; |
| } |
| |
| int init_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| if (pbpctl_dev->bp_caps & TPL_CAP) { |
| init_timer(&pbpctl_dev->bp_tpl_timer); |
| pbpctl_dev->bp_tpl_timer.function = &bp_tpl_timer_fn; |
| pbpctl_dev->bp_tpl_timer.data = (unsigned long)pbpctl_dev; |
| return BP_OK; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int set_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev, unsigned int param) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| if (pbpctl_dev->bp_caps & TPL_CAP) { |
| if ((param) && (!pbpctl_dev->bp_tpl_flag)) { |
| pbpctl_dev->bp_tpl_flag = param; |
| mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies + 1); |
| return BP_OK; |
| }; |
| if ((!param) && (pbpctl_dev->bp_tpl_flag)) |
| remove_bypass_tpl_auto(pbpctl_dev); |
| |
| return BP_OK; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int get_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| if (pbpctl_dev->bp_caps & TPL_CAP) { |
| return pbpctl_dev->bp_tpl_flag; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int set_tpl_fn(bpctl_dev_t *pbpctl_dev, int tpl_mode) |
| { |
| |
| bpctl_dev_t *pbpctl_dev_b = NULL; |
| if (!pbpctl_dev) |
| return -1; |
| |
| pbpctl_dev_b = get_status_port_fn(pbpctl_dev); |
| |
| if (pbpctl_dev->bp_caps & TPL_CAP) { |
| if (tpl_mode) { |
| if ((pbpctl_dev_b = get_status_port_fn(pbpctl_dev))) |
| set_tx(pbpctl_dev_b, 1); |
| set_tx(pbpctl_dev, 1); |
| } |
| if ((TPL_IF_SERIES(pbpctl_dev->subdevice)) || |
| (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX)) { |
| pbpctl_dev->bp_tpl_flag = tpl_mode; |
| if (!tpl_mode) |
| tpl_hw_off(pbpctl_dev); |
| else |
| tpl_hw_on(pbpctl_dev); |
| } else |
| set_bypass_tpl_auto(pbpctl_dev, tpl_mode); |
| return 0; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int get_tpl_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = BP_NOT_CAP; |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (pbpctl_dev->bp_caps & TPL_CAP) { |
| if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX) |
| return tpl2_flag_status(pbpctl_dev); |
| ret = pbpctl_dev->bp_tpl_flag; |
| } |
| return ret; |
| } |
| |
| int set_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| /* bp_lock(pbp_device_block); */ |
| cmnd_on(pbpctl_dev); |
| if (!tap_mode) |
| bp_wait_at_pwup_dis(pbpctl_dev); |
| else |
| bp_wait_at_pwup_en(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| |
| /* bp_unlock(pbp_device_block); */ |
| return BP_OK; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int get_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| /* bp_lock(pbp_device_block); */ |
| ret = bp_wait_at_pwup_status(pbpctl_dev); |
| /* bp_unlock(pbp_device_block); */ |
| |
| return ret; |
| } |
| |
| int set_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev, int tap_mode) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| |
| if (pbpctl_dev->bp_caps & SW_CTL_CAP) { |
| /* bp_lock(pbp_device_block); */ |
| cmnd_on(pbpctl_dev); |
| |
| if (!tap_mode) |
| bp_hw_reset_dis(pbpctl_dev); |
| else |
| bp_hw_reset_en(pbpctl_dev); |
| cmnd_off(pbpctl_dev); |
| /* bp_unlock(pbp_device_block); */ |
| return BP_OK; |
| } |
| return BP_NOT_CAP; |
| } |
| |
| int get_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev) |
| { |
| int ret = 0; |
| if (!pbpctl_dev) |
| return -1; |
| |
| /* bp_lock(pbp_device_block); */ |
| ret = bp_hw_reset_status(pbpctl_dev); |
| |
| /* bp_unlock(pbp_device_block); */ |
| |
| return ret; |
| } |
| |
| |
| int get_bypass_info_fn(bpctl_dev_t *pbpctl_dev, char *dev_name, |
| char *add_param) |
| { |
| if (!pbpctl_dev) |
| return -1; |
| if (!is_bypass_fn(pbpctl_dev)) |
| return -1; |
| strcpy(dev_name, pbpctl_dev->name); |
| *add_param = pbpctl_dev->bp_fw_ver; |
| return 0; |
| } |
| |
| int get_dev_idx_bsf(int bus, int slot, int func) |
| { |
| int idx_dev = 0; |
| for (idx_dev = 0; |
| ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num)); |
| idx_dev++) { |
| if ((bus == bpctl_dev_arr[idx_dev].bus) |
| && (slot == bpctl_dev_arr[idx_dev].slot) |
| && (func == bpctl_dev_arr[idx_dev].func)) |
| |
| return idx_dev; |
| } |
| return -1; |
| } |
| |
| static void str_low(char *str) |
| { |
| int i; |
| |
| for (i = 0; i < strlen(str); i++) |
| if ((str[i] >= 65) && (str[i] <= 90)) |
| str[i] += 32; |
| } |
| |
| static unsigned long str_to_hex(char *p) |
| { |
| unsigned long hex = 0; |
| unsigned long length = strlen(p), shift = 0; |
| unsigned char dig = 0; |
| |
| str_low(p); |
| length = strlen(p); |
| |
| if (length == 0) |
| return 0; |
| |
| do { |
| dig = p[--length]; |
| dig = dig < 'a' ? (dig - '0') : (dig - 'a' + 0xa); |
| hex |= (dig << shift); |
| shift += 4; |
| } while (length); |
| return hex; |
| } |
| |
| static int get_dev_idx(int ifindex) |
| { |
| int idx_dev = 0; |
| |
| for (idx_dev = 0; |
| ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num)); |
| idx_dev++) { |
| if (ifindex == bpctl_dev_arr[idx_dev].ifindex) |
| return idx_dev; |
| } |
| |
| return -1; |
| } |
| |
| static bpctl_dev_t *get_dev_idx_p(int ifindex) |
| { |
| int idx_dev = 0; |
| |
| for (idx_dev = 0; |
| ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num)); |
| idx_dev++) { |
| if (ifindex == bpctl_dev_arr[idx_dev].ifindex) |
| return &bpctl_dev_arr[idx_dev]; |
| } |
| |
| return NULL; |
| } |
| |
| static void if_scan_init(void) |
| { |
| int idx_dev = 0; |
| struct net_device *dev; |
| int ifindex; |
| /* rcu_read_lock(); */ |
| /* rtnl_lock(); */ |
| /* rcu_read_lock(); */ |
| |
| for_each_netdev(&init_net, dev) { |
| |
| struct ethtool_drvinfo drvinfo; |
| char cbuf[32]; |
| char *buf = NULL; |
| char res[10]; |
| int i = 0; |
| int bus = 0, slot = 0, func = 0; |
| ifindex = dev->ifindex; |
| |
| memset(res, 0, 10); |
| memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo)); |
| |
| if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) { |
| memset(&drvinfo, 0, sizeof(drvinfo)); |
| dev->ethtool_ops->get_drvinfo(dev, &drvinfo); |
| } else |
| continue; |
| if (!strcmp(drvinfo.bus_info, "N/A")) |
| continue; |
| memcpy(&cbuf, drvinfo.bus_info, 32); |
| buf = &cbuf[0]; |
| |
| while (*buf++ != ':') ; |
| for (i = 0; i < 10; i++, buf++) { |
| if (*buf == ':') |
| break; |
| res[i] = *buf; |
| |
| } |
| buf++; |
| bus = str_to_hex(res); |
| memset(res, 0, 10); |
| |
| for (i = 0; i < 10; i++, buf++) { |
| if (*buf == '.') |
| break; |
| res[i] = *buf; |
| |
| } |
| buf++; |
| slot = str_to_hex(res); |
| func = str_to_hex(buf); |
| idx_dev = get_dev_idx_bsf(bus, slot, func); |
| |
| if (idx_dev != -1) { |
| |
| bpctl_dev_arr[idx_dev].ifindex = ifindex; |
| bpctl_dev_arr[idx_dev].ndev = dev; |
| |
| } |
| |
| } |
| /* rtnl_unlock(); */ |
| /* rcu_read_unlock(); */ |
| |
| } |
| |
| static long device_ioctl(struct file *file, /* see include/linux/fs.h */ |
| unsigned int ioctl_num, /* number and param for ioctl */ |
| unsigned long ioctl_param) |
| { |
| struct bpctl_cmd bpctl_cmd; |
| int dev_idx = 0; |
| bpctl_dev_t *pbpctl_dev_out; |
| void __user *argp = (void __user *)ioctl_param; |
| int ret = 0; |
| unsigned long flags; |
| |
| static bpctl_dev_t *pbpctl_dev; |
| |
| /* lock_kernel(); */ |
| lock_bpctl(); |
| /* local_irq_save(flags); */ |
| /* if(!spin_trylock_irqsave(&bpvm_lock)){ |
| local_irq_restore(flags); |
| unlock_bpctl(); |
| unlock_kernel(); |
| return -1; |
| } */ |
| /* spin_lock_irqsave(&bpvm_lock, flags); */ |
| |
| /* |
| * Switch according to the ioctl called |
| */ |
| if (ioctl_num == IOCTL_TX_MSG(IF_SCAN)) { |
| if_scan_init(); |
| ret = SUCCESS; |
| goto bp_exit; |
| } |
| if (copy_from_user(&bpctl_cmd, argp, sizeof(struct bpctl_cmd))) { |
| |
| ret = -EFAULT; |
| goto bp_exit; |
| } |
| |
| if (ioctl_num == IOCTL_TX_MSG(GET_DEV_NUM)) { |
| bpctl_cmd.out_param[0] = device_num; |
| if (copy_to_user |
| (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) { |
| ret = -EFAULT; |
| goto bp_exit; |
| } |
| ret = SUCCESS; |
| goto bp_exit; |
| |
| } |
| /* lock_bpctl(); */ |
| /* preempt_disable(); */ |
| local_irq_save(flags); |
| if (!spin_trylock(&bpvm_lock)) { |
| local_irq_restore(flags); |
| unlock_bpctl(); |
| return -1; |
| } |
| |
| /* preempt_disable(); |
| rcu_read_lock(); |
| spin_lock_irqsave(&bpvm_lock, flags); |
| */ |
| if ((bpctl_cmd.in_param[5]) || |
| (bpctl_cmd.in_param[6]) || (bpctl_cmd.in_param[7])) |
| dev_idx = get_dev_idx_bsf(bpctl_cmd.in_param[5], |
| bpctl_cmd.in_param[6], |
| bpctl_cmd.in_param[7]); |
| else if (bpctl_cmd.in_param[1] == 0) |
| dev_idx = bpctl_cmd.in_param[0]; |
| else |
| dev_idx = get_dev_idx(bpctl_cmd.in_param[1]); |
| |
| if (dev_idx < 0 || dev_idx > device_num) { |
| /* unlock_bpctl(); |
| preempt_enable(); */ |
| ret = -EOPNOTSUPP; |
| /* preempt_enable(); |
| rcu_read_unlock(); */ |
| spin_unlock_irqrestore(&bpvm_lock, flags); |
| goto bp_exit; |
| } |
| |
| bpctl_cmd.out_param[0] = bpctl_dev_arr[dev_idx].bus; |
| bpctl_cmd.out_param[1] = bpctl_dev_arr[dev_idx].slot; |
| bpctl_cmd.out_param[2] = bpctl_dev_arr[dev_idx].func; |
| bpctl_cmd.out_param[3] = bpctl_dev_arr[dev_idx].ifindex; |
| |
| if ((bpctl_dev_arr[dev_idx].bp_10gb) |
| && (!(bpctl_dev_arr[dev_idx].ifindex))) { |
| printk("Please load network driver for %s adapter!\n", |
| bpctl_dev_arr[dev_idx].name); |
| bpctl_cmd.status = -1; |
| ret = SUCCESS; |
| /* preempt_enable(); */ |
| /* rcu_read_unlock(); */ |
| spin_unlock_irqrestore(&bpvm_lock, flags); |
| goto bp_exit; |
| |
| } |
| if ((bpctl_dev_arr[dev_idx].bp_10gb) && (bpctl_dev_arr[dev_idx].ndev)) { |
| if (!(bpctl_dev_arr[dev_idx].ndev->flags & IFF_UP)) { |
| if (!(bpctl_dev_arr[dev_idx].ndev->flags & IFF_UP)) { |
| printk |
| ("Please bring up network interfaces for %s adapter!\n", |
| bpctl_dev_arr[dev_idx].name); |
| bpctl_cmd.status = -1; |
| ret = SUCCESS; |
| /* preempt_enable(); */ |
| /* rcu_read_unlock(); */ |
| spin_unlock_irqrestore(&bpvm_lock, flags); |
| goto bp_exit; |
| } |
| |
| } |
| } |
| |
| if ((dev_idx < 0) || (dev_idx > device_num) |
| || (bpctl_dev_arr[dev_idx].pdev == NULL)) { |
| bpctl_cmd.status = -1; |
| goto bpcmd_exit; |
| } |
| |
| pbpctl_dev = &bpctl_dev_arr[dev_idx]; |
| |
| switch (ioctl_num) { |
| case IOCTL_TX_MSG(SET_BYPASS_PWOFF): |
| bpctl_cmd.status = |
| set_bypass_pwoff_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_BYPASS_PWOFF): |
| bpctl_cmd.status = get_bypass_pwoff_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(SET_BYPASS_PWUP): |
| bpctl_cmd.status = |
| set_bypass_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_BYPASS_PWUP): |
| bpctl_cmd.status = get_bypass_pwup_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(SET_BYPASS_WD): |
| bpctl_cmd.status = |
| set_bypass_wd_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_BYPASS_WD): |
| bpctl_cmd.status = |
| get_bypass_wd_fn(pbpctl_dev, (int *)&(bpctl_cmd.data[0])); |
| break; |
| |
| case IOCTL_TX_MSG(GET_WD_EXPIRE_TIME): |
| bpctl_cmd.status = |
| get_wd_expire_time_fn(pbpctl_dev, |
| (int *)&(bpctl_cmd.data[0])); |
| break; |
| |
| case IOCTL_TX_MSG(RESET_BYPASS_WD_TIMER): |
| bpctl_cmd.status = reset_bypass_wd_timer_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(GET_WD_SET_CAPS): |
| bpctl_cmd.status = get_wd_set_caps_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(SET_STD_NIC): |
| bpctl_cmd.status = |
| set_std_nic_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_STD_NIC): |
| bpctl_cmd.status = get_std_nic_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(SET_TAP): |
| bpctl_cmd.status = |
| set_tap_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_TAP): |
| bpctl_cmd.status = get_tap_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(GET_TAP_CHANGE): |
| bpctl_cmd.status = get_tap_change_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(SET_DIS_TAP): |
| bpctl_cmd.status = |
| set_dis_tap_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_DIS_TAP): |
| bpctl_cmd.status = get_dis_tap_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(SET_TAP_PWUP): |
| bpctl_cmd.status = |
| set_tap_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_TAP_PWUP): |
| bpctl_cmd.status = get_tap_pwup_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(SET_WD_EXP_MODE): |
| bpctl_cmd.status = |
| set_wd_exp_mode_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_WD_EXP_MODE): |
| bpctl_cmd.status = get_wd_exp_mode_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(GET_DIS_BYPASS): |
| bpctl_cmd.status = get_dis_bypass_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(SET_DIS_BYPASS): |
| bpctl_cmd.status = |
| set_dis_bypass_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_BYPASS_CHANGE): |
| bpctl_cmd.status = get_bypass_change_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(GET_BYPASS): |
| bpctl_cmd.status = get_bypass_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(SET_BYPASS): |
| bpctl_cmd.status = |
| set_bypass_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_BYPASS_CAPS): |
| bpctl_cmd.status = get_bypass_caps_fn(pbpctl_dev); |
| /*preempt_enable(); */ |
| /*rcu_read_unlock();*/ |
| spin_unlock_irqrestore(&bpvm_lock, flags); |
| if (copy_to_user |
| (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) { |
| /*unlock_bpctl(); */ |
| /*preempt_enable(); */ |
| ret = -EFAULT; |
| goto bp_exit; |
| } |
| goto bp_exit; |
| |
| case IOCTL_TX_MSG(GET_BYPASS_SLAVE): |
| bpctl_cmd.status = |
| get_bypass_slave_fn(pbpctl_dev, &pbpctl_dev_out); |
| if (bpctl_cmd.status == 1) { |
| bpctl_cmd.out_param[4] = pbpctl_dev_out->bus; |
| bpctl_cmd.out_param[5] = pbpctl_dev_out->slot; |
| bpctl_cmd.out_param[6] = pbpctl_dev_out->func; |
| bpctl_cmd.out_param[7] = pbpctl_dev_out->ifindex; |
| } |
| break; |
| |
| case IOCTL_TX_MSG(IS_BYPASS): |
| bpctl_cmd.status = is_bypass(pbpctl_dev); |
| break; |
| case IOCTL_TX_MSG(SET_TX): |
| bpctl_cmd.status = set_tx_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| case IOCTL_TX_MSG(GET_TX): |
| bpctl_cmd.status = get_tx_fn(pbpctl_dev); |
| break; |
| case IOCTL_TX_MSG(SET_WD_AUTORESET): |
| bpctl_cmd.status = |
| set_wd_autoreset_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| |
| break; |
| case IOCTL_TX_MSG(GET_WD_AUTORESET): |
| |
| bpctl_cmd.status = get_wd_autoreset_fn(pbpctl_dev); |
| break; |
| case IOCTL_TX_MSG(SET_DISC): |
| bpctl_cmd.status = |
| set_disc_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| case IOCTL_TX_MSG(GET_DISC): |
| bpctl_cmd.status = get_disc_fn(pbpctl_dev); |
| break; |
| case IOCTL_TX_MSG(GET_DISC_CHANGE): |
| bpctl_cmd.status = get_disc_change_fn(pbpctl_dev); |
| break; |
| case IOCTL_TX_MSG(SET_DIS_DISC): |
| bpctl_cmd.status = |
| set_dis_disc_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| case IOCTL_TX_MSG(GET_DIS_DISC): |
| bpctl_cmd.status = get_dis_disc_fn(pbpctl_dev); |
| break; |
| case IOCTL_TX_MSG(SET_DISC_PWUP): |
| bpctl_cmd.status = |
| set_disc_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| case IOCTL_TX_MSG(GET_DISC_PWUP): |
| bpctl_cmd.status = get_disc_pwup_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(GET_BYPASS_INFO): |
| |
| bpctl_cmd.status = |
| get_bypass_info_fn(pbpctl_dev, (char *)&bpctl_cmd.data, |
| (char *)&bpctl_cmd.out_param[4]); |
| break; |
| |
| case IOCTL_TX_MSG(SET_TPL): |
| bpctl_cmd.status = |
| set_tpl_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_TPL): |
| bpctl_cmd.status = get_tpl_fn(pbpctl_dev); |
| break; |
| case IOCTL_TX_MSG(SET_BP_WAIT_AT_PWUP): |
| bpctl_cmd.status = |
| set_bp_wait_at_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_BP_WAIT_AT_PWUP): |
| bpctl_cmd.status = get_bp_wait_at_pwup_fn(pbpctl_dev); |
| break; |
| case IOCTL_TX_MSG(SET_BP_HW_RESET): |
| bpctl_cmd.status = |
| set_bp_hw_reset_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_BP_HW_RESET): |
| bpctl_cmd.status = get_bp_hw_reset_fn(pbpctl_dev); |
| break; |
| #ifdef BP_SELF_TEST |
| case IOCTL_TX_MSG(SET_BP_SELF_TEST): |
| bpctl_cmd.status = |
| set_bp_self_test_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| |
| break; |
| case IOCTL_TX_MSG(GET_BP_SELF_TEST): |
| bpctl_cmd.status = get_bp_self_test_fn(pbpctl_dev); |
| break; |
| |
| #endif |
| #if 0 |
| case IOCTL_TX_MSG(SET_DISC_PORT): |
| bpctl_cmd.status = |
| set_disc_port_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_DISC_PORT): |
| bpctl_cmd.status = get_disc_port_fn(pbpctl_dev); |
| break; |
| |
| case IOCTL_TX_MSG(SET_DISC_PORT_PWUP): |
| bpctl_cmd.status = |
| set_disc_port_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_DISC_PORT_PWUP): |
| bpctl_cmd.status = get_disc_port_pwup_fn(pbpctl_dev); |
| break; |
| #endif |
| case IOCTL_TX_MSG(SET_BP_FORCE_LINK): |
| bpctl_cmd.status = |
| set_bp_force_link_fn(dev_idx, bpctl_cmd.in_param[2]); |
| break; |
| |
| case IOCTL_TX_MSG(GET_BP_FORCE_LINK): |
| bpctl_cmd.status = get_bp_force_link_fn(dev_idx); |
| break; |
| |
| default: |
| /* unlock_bpctl(); */ |
| |
| ret = -EOPNOTSUPP; |
| /* preempt_enable(); */ |
| /* rcu_read_unlock();*/ |
| spin_unlock_irqrestore(&bpvm_lock, flags); |
| goto bp_exit; |
| } |
| /* unlock_bpctl(); */ |
| /* preempt_enable(); */ |
| bpcmd_exit: |
| /* rcu_read_unlock(); */ |
| spin_unlock_irqrestore(&bpvm_lock, flags); |
| if (copy_to_user(argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) |
| ret = -EFAULT; |
| ret = SUCCESS; |
| bp_exit: |
| /* unlock_kernel(); */ |
| /* spin_unlock_irqrestore(&bpvm_lock, flags); */ |
| unlock_bpctl(); |
| /* unlock_kernel(); */ |
| return ret; |
| } |
| |
| static const struct file_operations Fops = { |
| .owner = THIS_MODULE, |
| .unlocked_ioctl = device_ioctl, |
| }; |
| |
| #ifndef PCI_DEVICE |
| #define PCI_DEVICE(vend,dev) \ |
| .vendor = (vend), .device = (dev), \ |
| .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID |
| #endif |
| |
| #define SILICOM_E1000BP_ETHERNET_DEVICE(device_id) {\ |
| PCI_DEVICE(SILICOM_VID, device_id)} |
| |
| typedef enum { |
| PXG2BPFI, |
| PXG2BPFIL, |
| PXG2BPFILX, |
| PXG2BPFILLX, |
| PXGBPI, |
| PXGBPIG, |
| PXG2TBFI, |
| PXG4BPI, |
| PXG4BPFI, |
| PEG4BPI, |
| PEG2BPI, |
| PEG4BPIN, |
| PEG2BPFI, |
| PEG2BPFILX, |
| PMCXG2BPFI, |
| PMCXG2BPFIN, |
| PEG4BPII, |
| PEG4BPFII, |
| PXG4BPFILX, |
| PMCXG2BPIN, |
| PMCXG4BPIN, |
| PXG2BISC1, |
| PEG2TBFI, |
| PXG2TBI, |
| PXG4BPFID, |
| PEG4BPFI, |
| PEG4BPIPT, |
| PXG6BPI, |
| PEG4BPIL, |
| PMCXG2BPIN2, |
| PMCXG4BPIN2, |
| PMCX2BPI, |
| PEG2BPFID, |
| PEG2BPFIDLX, |
| PMCX4BPI, |
| MEG2BPFILN, |
| MEG2BPFINX, |
| PEG4BPFILX, |
| PE10G2BPISR, |
| PE10G2BPILR, |
| MHIO8AD, |
| PE10G2BPICX4, |
| PEG2BPI5, |
| PEG6BPI, |
| PEG4BPFI5, |
| PEG4BPFI5LX, |
| MEG2BPFILXLN, |
| PEG2BPIX1, |
| MEG2BPFILXNX, |
| XE10G2BPIT, |
| XE10G2BPICX4, |
| XE10G2BPISR, |
| XE10G2BPILR, |
| PEG4BPIIO, |
| XE10G2BPIXR, |
| PE10GDBISR, |
| PE10GDBILR, |
| PEG2BISC6, |
| PEG6BPIFC, |
| PE10G2BPTCX4, |
| PE10G2BPTSR, |
| PE10G2BPTLR, |
| PE10G2BPTT, |
| PEG4BPI6, |
| PEG4BPFI6, |
| PEG4BPFI6LX, |
| PEG4BPFI6ZX, |
| PEG2BPI6, |
| PEG2BPFI6, |
| PEG2BPFI6LX, |
| PEG2BPFI6ZX, |
| PEG2BPFI6FLXM, |
| PEG4BPI6FC, |
| PEG4BPFI6FC, |
| PEG4BPFI6FCLX, |
| PEG4BPFI6FCZX, |
| PEG6BPI6, |
| PEG2BPI6SC6, |
| MEG2BPI6, |
| XEG2BPI6, |
| MEG4BPI6, |
| PEG2BPFI5, |
| PEG2BPFI5LX, |
| PXEG4BPFI, |
| M1EG2BPI6, |
| M1EG2BPFI6, |
| M1EG2BPFI6LX, |
| M1EG2BPFI6ZX, |
| M1EG4BPI6, |
| M1EG4BPFI6, |
| M1EG4BPFI6LX, |
| M1EG4BPFI6ZX, |
| M1EG6BPI6, |
| M1E2G4BPi80, |
| M1E2G4BPFi80, |
| M1E2G4BPFi80LX, |
| M1E2G4BPFi80ZX, |
| PE210G2SPI9, |
| M1E10G2BPI9CX4, |
| M1E10G2BPI9SR, |
| M1E10G2BPI9LR, |
| M1E10G2BPI9T, |
| PE210G2BPI9CX4, |
| PE210G2BPI9SR, |
| PE210G2BPI9LR, |
| PE210G2BPI9T, |
| M2EG2BPFI6, |
| M2EG2BPFI6LX, |
| M2EG2BPFI6ZX, |
| M2EG4BPI6, |
| M2EG4BPFI6, |
| M2EG4BPFI6LX, |
| M2EG4BPFI6ZX, |
| M2EG6BPI6, |
| PEG2DBI6, |
| PEG2DBFI6, |
| PEG2DBFI6LX, |
| PEG2DBFI6ZX, |
| PE2G4BPi80, |
| PE2G4BPFi80, |
| PE2G4BPFi80LX, |
| PE2G4BPFi80ZX, |
| PE2G4BPi80L, |
| M6E2G8BPi80A, |
| |
| PE2G2BPi35, |
| PAC1200BPi35, |
| PE2G2BPFi35, |
| PE2G2BPFi35LX, |
| PE2G2BPFi35ZX, |
| PE2G4BPi35, |
| PE2G4BPi35L, |
| PE2G4BPFi35, |
| PE2G4BPFi35LX, |
| PE2G4BPFi35ZX, |
| |
| PE2G6BPi35, |
| PE2G6BPi35CX, |
| |
| PE2G2BPi80, |
| PE2G2BPFi80, |
| PE2G2BPFi80LX, |
| PE2G2BPFi80ZX, |
| M2E10G2BPI9CX4, |
| M2E10G2BPI9SR, |
| M2E10G2BPI9LR, |
| M2E10G2BPI9T, |
| M6E2G8BPi80, |
| PE210G2DBi9SR, |
| PE210G2DBi9SRRB, |
| PE210G2DBi9LR, |
| PE210G2DBi9LRRB, |
| PE310G4DBi940SR, |
| PE310G4BPi9T, |
| PE310G4BPi9SR, |
| PE310G4BPi9LR, |
| PE210G2BPi40, |
| } board_t; |
| |
| typedef struct _bpmod_info_t { |
| unsigned int vendor; |
| unsigned int device; |
| unsigned int subvendor; |
| unsigned int subdevice; |
| unsigned int index; |
| char *bp_name; |
| |
| } bpmod_info_t; |
| |
| typedef struct _dev_desc { |
| char *name; |
| } dev_desc_t; |
| |
| dev_desc_t dev_desc[] = { |
| {"Silicom Bypass PXG2BPFI-SD series adapter"}, |
| {"Silicom Bypass PXG2BPFIL-SD series adapter"}, |
| {"Silicom Bypass PXG2BPFILX-SD series adapter"}, |
| {"Silicom Bypass PXG2BPFILLX-SD series adapter"}, |
| {"Silicom Bypass PXG2BPI-SD series adapter"}, |
| {"Silicom Bypass PXG2BPIG-SD series adapter"}, |
| {"Silicom Bypass PXG2TBFI-SD series adapter"}, |
| {"Silicom Bypass PXG4BPI-SD series adapter"}, |
| {"Silicom Bypass PXG4BPFI-SD series adapter"}, |
| {"Silicom Bypass PEG4BPI-SD series adapter"}, |
| {"Silicom Bypass PEG2BPI-SD series adapter"}, |
| {"Silicom Bypass PEG4BPIN-SD series adapter"}, |
| {"Silicom Bypass PEG2BPFI-SD series adapter"}, |
| {"Silicom Bypass PEG2BPFI-LX-SD series adapter"}, |
| {"Silicom Bypass PMCX2BPFI-SD series adapter"}, |
| {"Silicom Bypass PMCX2BPFI-N series adapter"}, |
| {"Intel Bypass PEG2BPII series adapter"}, |
| {"Intel Bypass PEG2BPFII series adapter"}, |
| {"Silicom Bypass PXG4BPFILX-SD series adapter"}, |
| {"Silicom Bypass PMCX2BPI-N series adapter"}, |
| {"Silicom Bypass PMCX4BPI-N series adapter"}, |
| {"Silicom Bypass PXG2BISC1-SD series adapter"}, |
| {"Silicom Bypass PEG2TBFI-SD series adapter"}, |
| {"Silicom Bypass PXG2TBI-SD series adapter"}, |
| {"Silicom Bypass PXG4BPFID-SD series adapter"}, |
| {"Silicom Bypass PEG4BPFI-SD series adapter"}, |
| {"Silicom Bypass PEG4BPIPT-SD series adapter"}, |
| {"Silicom Bypass PXG6BPI-SD series adapter"}, |
| {"Silicom Bypass PEG4BPIL-SD series adapter"}, |
| {"Silicom Bypass PMCX2BPI-N2 series adapter"}, |
| {"Silicom Bypass PMCX4BPI-N2 series adapter"}, |
| {"Silicom Bypass PMCX2BPI-SD series adapter"}, |
| {"Silicom Bypass PEG2BPFID-SD series adapter"}, |
| {"Silicom Bypass PEG2BPFIDLX-SD series adapter"}, |
| {"Silicom Bypass PMCX4BPI-SD series adapter"}, |
| {"Silicom Bypass MEG2BPFILN-SD series adapter"}, |
| {"Silicom Bypass MEG2BPFINX-SD series adapter"}, |
| {"Silicom Bypass PEG4BPFILX-SD series adapter"}, |
| {"Silicom Bypass PE10G2BPISR-SD series adapter"}, |
| {"Silicom Bypass PE10G2BPILR-SD series adapter"}, |
| {"Silicom Bypass MHIO8AD-SD series adapter"}, |
| {"Silicom Bypass PE10G2BPICX4-SD series adapter"}, |
| {"Silicom Bypass PEG2BPI5-SD series adapter"}, |
| {"Silicom Bypass PEG6BPI5-SD series adapter"}, |
| {"Silicom Bypass PEG4BPFI5-SD series adapter"}, |
| {"Silicom Bypass PEG4BPFI5LX-SD series adapter"}, |
| {"Silicom Bypass MEG2BPFILXLN-SD series adapter"}, |
| {"Silicom Bypass PEG2BPIX1-SD series adapter"}, |
| {"Silicom Bypass MEG2BPFILXNX-SD series adapter"}, |
| {"Silicom Bypass XE10G2BPIT-SD series adapter"}, |
| {"Silicom Bypass XE10G2BPICX4-SD series adapter"}, |
| {"Silicom Bypass XE10G2BPISR-SD series adapter"}, |
| {"Silicom Bypass XE10G2BPILR-SD series adapter"}, |
| {"Intel Bypass PEG2BPFII0 series adapter"}, |
| {"Silicom Bypass XE10G2BPIXR series adapter"}, |
| {"Silicom Bypass PE10G2DBISR series adapter"}, |
| {"Silicom Bypass PEG2BI5SC6 series adapter"}, |
| {"Silicom Bypass PEG6BPI5FC series adapter"}, |
| |
| {"Silicom Bypass PE10G2BPTCX4 series adapter"}, |
| {"Silicom Bypass PE10G2BPTSR series adapter"}, |
| {"Silicom Bypass PE10G2BPTLR series adapter"}, |
| {"Silicom Bypass PE10G2BPTT series adapter"}, |
| {"Silicom Bypass PEG4BPI6 series adapter"}, |
| {"Silicom Bypass PEG4BPFI6 series adapter"}, |
| {"Silicom Bypass PEG4BPFI6LX series adapter"}, |
| {"Silicom Bypass PEG4BPFI6ZX series adapter"}, |
| {"Silicom Bypass PEG2BPI6 series adapter"}, |
| {"Silicom Bypass PEG2BPFI6 series adapter"}, |
| {"Silicom Bypass PEG2BPFI6LX series adapter"}, |
| {"Silicom Bypass PEG2BPFI6ZX series adapter"}, |
| {"Silicom Bypass PEG2BPFI6FLXM series adapter"}, |
| {"Silicom Bypass PEG4BPI6FC series adapter"}, |
| {"Silicom Bypass PEG4BPFI6FC series adapter"}, |
| {"Silicom Bypass PEG4BPFI6FCLX series adapter"}, |
| {"Silicom Bypass PEG4BPFI6FCZX series adapter"}, |
| {"Silicom Bypass PEG6BPI6 series adapter"}, |
| {"Silicom Bypass PEG2BPI6SC6 series adapter"}, |
| {"Silicom Bypass MEG2BPI6 series adapter"}, |
| {"Silicom Bypass XEG2BPI6 series adapter"}, |
| {"Silicom Bypass MEG4BPI6 series adapter"}, |
| {"Silicom Bypass PEG2BPFI5-SD series adapter"}, |
| {"Silicom Bypass PEG2BPFI5LX-SD series adapter"}, |
| {"Silicom Bypass PXEG4BPFI-SD series adapter"}, |
| {"Silicom Bypass MxEG2BPI6 series adapter"}, |
| {"Silicom Bypass MxEG2BPFI6 series adapter"}, |
| {"Silicom Bypass MxEG2BPFI6LX series adapter"}, |
| {"Silicom Bypass MxEG2BPFI6ZX series adapter"}, |
| {"Silicom Bypass MxEG4BPI6 series adapter"}, |
| {"Silicom Bypass MxEG4BPFI6 series adapter"}, |
| {"Silicom Bypass MxEG4BPFI6LX series adapter"}, |
| {"Silicom Bypass MxEG4BPFI6ZX series adapter"}, |
| {"Silicom Bypass MxEG6BPI6 series adapter"}, |
| {"Silicom Bypass MxE2G4BPi80 series adapter"}, |
| {"Silicom Bypass MxE2G4BPFi80 series adapter"}, |
| {"Silicom Bypass MxE2G4BPFi80LX series adapter"}, |
| {"Silicom Bypass MxE2G4BPFi80ZX series adapter"}, |
| |
| {"Silicom Bypass PE210G2SPI9 series adapter"}, |
| |
| {"Silicom Bypass MxE210G2BPI9CX4 series adapter"}, |
| {"Silicom Bypass MxE210G2BPI9SR series adapter"}, |
| {"Silicom Bypass MxE210G2BPI9LR series adapter"}, |
| {"Silicom Bypass MxE210G2BPI9T series adapter"}, |
| |
| {"Silicom Bypass PE210G2BPI9CX4 series adapter"}, |
| {"Silicom Bypass PE210G2BPI9SR series adapter"}, |
| {"Silicom Bypass PE210G2BPI9LR series adapter"}, |
| {"Silicom Bypass PE210G2BPI9T series adapter"}, |
| |
| {"Silicom Bypass M2EG2BPFI6 series adapter"}, |
| {"Silicom Bypass M2EG2BPFI6LX series adapter"}, |
| {"Silicom Bypass M2EG2BPFI6ZX series adapter"}, |
| {"Silicom Bypass M2EG4BPI6 series adapter"}, |
| {"Silicom Bypass M2EG4BPFI6 series adapter"}, |
| {"Silicom Bypass M2EG4BPFI6LX series adapter"}, |
| {"Silicom Bypass M2EG4BPFI6ZX series adapter"}, |
| {"Silicom Bypass M2EG6BPI6 series adapter"}, |
| |
| {"Silicom Bypass PEG2DBI6 series adapter"}, |
| {"Silicom Bypass PEG2DBFI6 series adapter"}, |
| {"Silicom Bypass PEG2DBFI6LX series adapter"}, |
| {"Silicom Bypass PEG2DBFI6ZX series adapter"}, |
| |
| {"Silicom Bypass PE2G4BPi80 series adapter"}, |
| {"Silicom Bypass PE2G4BPFi80 series adapter"}, |
| {"Silicom Bypass PE2G4BPFi80LX series adapter"}, |
| {"Silicom Bypass PE2G4BPFi80ZX series adapter"}, |
| |
| {"Silicom Bypass PE2G4BPi80L series adapter"}, |
| {"Silicom Bypass MxE2G8BPi80A series adapter"}, |
| |
| {"Silicom Bypass PE2G2BPi35 series adapter"}, |
| {"Silicom Bypass PAC1200BPi35 series adapter"}, |
| {"Silicom Bypass PE2G2BPFi35 series adapter"}, |
| {"Silicom Bypass PE2G2BPFi35LX series adapter"}, |
| {"Silicom Bypass PE2G2BPFi35ZX series adapter"}, |
| |
| {"Silicom Bypass PE2G4BPi35 series adapter"}, |
| {"Silicom Bypass PE2G4BPi35L series adapter"}, |
| {"Silicom Bypass PE2G4BPFi35 series adapter"}, |
| {"Silicom Bypass PE2G4BPFi35LX series adapter"}, |
| {"Silicom Bypass PE2G4BPFi35ZX series adapter"}, |
| |
| {"Silicom Bypass PE2G6BPi35 series adapter"}, |
| {"Silicom Bypass PE2G6BPi35CX series adapter"}, |
| |
| {"Silicom Bypass PE2G2BPi80 series adapter"}, |
| {"Silicom Bypass PE2G2BPFi80 series adapter"}, |
| {"Silicom Bypass PE2G2BPFi80LX series adapter"}, |
| {"Silicom Bypass PE2G2BPFi80ZX series adapter"}, |
| |
| {"Silicom Bypass M2E10G2BPI9CX4 series adapter"}, |
| {"Silicom Bypass M2E10G2BPI9SR series adapter"}, |
| {"Silicom Bypass M2E10G2BPI9LR series adapter"}, |
| {"Silicom Bypass M2E10G2BPI9T series adapter"}, |
| {"Silicom Bypass MxE2G8BPi80 series adapter"}, |
| {"Silicom Bypass PE210G2DBi9SR series adapter"}, |
| {"Silicom Bypass PE210G2DBi9SRRB series adapter"}, |
| {"Silicom Bypass PE210G2DBi9LR series adapter"}, |
| {"Silicom Bypass PE210G2DBi9LRRB series adapter"}, |
| {"Silicom Bypass PE310G4DBi9-SR series adapter"}, |
| {"Silicom Bypass PE310G4BPi9T series adapter"}, |
| {"Silicom Bypass PE310G4BPi9SR series adapter"}, |
| {"Silicom Bypass PE310G4BPi9LR series adapter"}, |
| {"Silicom Bypass PE210G2BPi40T series adapter"}, |
| {0}, |
| }; |
| |
| static bpmod_info_t tx_ctl_pci_tbl[] = { |
| {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFI_SSID, PXG2BPFI, |
| "PXG2BPFI-SD"}, |
| {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFIL_SSID, PXG2BPFIL, |
| "PXG2BPFIL-SD"}, |
| {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILX_SSID, PXG2BPFILX, |
| "PXG2BPFILX-SD"}, |
| {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2BPFILLX_SSID, PXG2BPFILLX, |
| "PXG2BPFILLXSD"}, |
| {0x8086, 0x1010, SILICOM_SVID, SILICOM_PXGBPI_SSID, PXGBPI, |
| "PXG2BPI-SD"}, |
| {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXGBPIG_SSID, PXGBPIG, |
| "PXG2BPIG-SD"}, |
| {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG2TBFI_SSID, PXG2TBFI, |
| "PXG2TBFI-SD"}, |
| {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI, |
| "PXG4BPI-SD"}, |
| {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI, |
| "PXG4BPFI-SD"}, |
| {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFILX_SSID, PXG4BPFILX, |
| "PXG4BPFILX-SD"}, |
| {0x8086, 0x1079, SILICOM_SVID, SILICOM_PEG4BPI_SSID, PEG4BPI, |
| "PEXG4BPI-SD"}, |
| {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPI_SSID, PEG2BPI, |
| "PEG2BPI-SD"}, |
| {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIN_SSID, PEG4BPIN, |
| "PEG4BPI-SD"}, |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFI_SSID, PEG2BPFI, |
| "PEG2BPFI-SD"}, |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFILX_SSID, PEG2BPFILX, |
| "PEG2BPFILX-SD"}, |
| {0x8086, 0x107a, SILICOM_SVID, SILICOM_PMCXG2BPFI_SSID, PMCXG2BPFI, |
| "PMCX2BPFI-SD"}, |
| {0x8086, 0x107a, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPFIN_SSID, |
| PMCXG2BPFIN, "PMCX2BPFI-N"}, |
| {0x8086, INTEL_PEG4BPII_PID, 0x8086, INTEL_PEG4BPII_SSID, PEG4BPII, |
| "PEG4BPII"}, |
| {0x8086, INTEL_PEG4BPIIO_PID, 0x8086, INTEL_PEG4BPIIO_SSID, PEG4BPIIO, |
| "PEG4BPII0"}, |
| {0x8086, INTEL_PEG4BPFII_PID, 0x8086, INTEL_PEG4BPFII_SSID, PEG4BPFII, |
| "PEG4BPFII"}, |
| {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN_SSID, |
| PMCXG2BPIN, "PMCX2BPI-N"}, |
| {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN_SSID, |
| PMCXG4BPIN, "PMCX4BPI-N"}, |
| {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1, |
| "PXG2BISC1-SD"}, |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2TBFI_SSID, PEG2TBFI, |
| "PEG2TBFI-SD"}, |
| {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI, |
| "PXG2TBI-SD"}, |
| {0x8086, 0x107a, SILICOM_SVID, SILICOM_PXG4BPFID_SSID, PXG4BPFID, |
| "PXG4BPFID-SD"}, |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI, |
| "PEG4BPFI-SD"}, |
| {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG4BPIPT_SSID, PEG4BPIPT, |
| "PEG4BPIPT-SD"}, |
| {0x8086, 0x1079, SILICOM_SVID, SILICOM_PXG6BPI_SSID, PXG6BPI, |
| "PXG6BPI-SD"}, |
| {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG4BPIL_SSID /*PCI_ANY_ID */ , PEG4BPIL, "PEG4BPIL-SD"}, |
| {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG2BPIN2_SSID, |
| PMCXG2BPIN2, "PMCX2BPI-N2"}, |
| {0x8086, 0x1079, NOKIA_PMCXG2BPFIN_SVID, NOKIA_PMCXG4BPIN2_SSID, |
| PMCXG4BPIN2, "PMCX4BPI-N2"}, |
| {0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX2BPI_SSID, PMCX2BPI, |
| "PMCX2BPI-SD"}, |
| {0x8086, 0x1079, SILICOM_SVID, SILICOM_PMCX4BPI_SSID, PMCX4BPI, |
| "PMCX4BPI-SD"}, |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFID_SSID, PEG2BPFID, |
| "PEG2BPFID-SD"}, |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG2BPFIDLX_SSID, PEG2BPFIDLX, |
| "PEG2BPFIDLXSD"}, |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILN_SSID, MEG2BPFILN, |
| "MEG2BPFILN-SD"}, |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFINX_SSID, MEG2BPFINX, |
| "MEG2BPFINX-SD"}, |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_PEG4BPFILX_SSID, PEG4BPFILX, |
| "PEG4BPFILX-SD"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPISR_SSID, |
| PE10G2BPISR, "PE10G2BPISR"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPILR_SSID, |
| PE10G2BPILR, "PE10G2BPILR"}, |
| {0x8086, 0x10a9, SILICOM_SVID, SILICOM_MHIO8AD_SSID, MHIO8AD, |
| "MHIO8AD-SD"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_PE10G2BPICX4_SSID, |
| PE10G2BPISR, "PE10G2BPICX4"}, |
| {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2BPI5_SSID /*PCI_ANY_ID */ , PEG2BPI5, "PEG2BPI5-SD"}, |
| {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG6BPI_SSID /*PCI_ANY_ID */ , PEG6BPI, "PEG6BPI5"}, |
| {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG4BPFI5_SSID, |
| PEG4BPFI5, "PEG4BPFI5"}, |
| {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG4BPFI5LX_SSID, PEG4BPFI5LX, "PEG4BPFI5LX"}, |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXLN_SSID, MEG2BPFILXLN, |
| "MEG2BPFILXLN"}, |
| {0x8086, 0x105e, SILICOM_SVID, SILICOM_PEG2BPIX1_SSID, PEG2BPIX1, |
| "PEG2BPIX1-SD"}, |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_MEG2BPFILXNX_SSID, MEG2BPFILXNX, |
| "MEG2BPFILXNX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPIT_SSID, XE10G2BPIT, |
| "XE10G2BPIT"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID, SILICOM_XE10G2BPICX4_SSID, |
| XE10G2BPICX4, "XE10G2BPICX4"}, |
| {0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPISR_SSID, XE10G2BPISR, |
| "XE10G2BPISR"}, |
| {0x8086, 0x10C6, SILICOM_SVID, SILICOM_XE10G2BPILR_SSID, XE10G2BPILR, |
| "XE10G2BPILR"}, |
| {0x8086, 0x10C6, NOKIA_XE10G2BPIXR_SVID, NOKIA_XE10G2BPIXR_SSID, |
| XE10G2BPIXR, "XE10G2BPIXR"}, |
| {0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBISR_SSID, PE10GDBISR, |
| "PE10G2DBISR"}, |
| {0x8086, 0x10C6, SILICOM_SVID, SILICOM_PE10GDBILR_SSID, PE10GDBILR, |
| "PE10G2DBILR"}, |
| {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2BISC6_SSID /*PCI_ANY_ID */ , PEG2BISC6, "PEG2BI5SC6"}, |
| {0x8086, 0x10a7, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG6BPIFC_SSID /*PCI_ANY_ID */ , PEG6BPIFC, "PEG6BPI5FC"}, |
| |
| {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID, |
| SILICOM_PE10G2BPTCX4_SSID, PE10G2BPTCX4, "PE10G2BPTCX4"}, |
| {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID, |
| SILICOM_PE10G2BPTSR_SSID, PE10G2BPTSR, "PE10G2BPTSR"}, |
| {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID, |
| SILICOM_PE10G2BPTLR_SSID, PE10G2BPTLR, "PE10G2BPTLR"}, |
| {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID, |
| SILICOM_PE10G2BPTT_SSID, PE10G2BPTT, "PE10G2BPTT"}, |
| |
| /* {BROADCOM_VID, BROADCOM_PE10G2_PID, PCI_ANY_ID, PCI_ANY_ID, PE10G2BPTCX4, "PE10G2BPTCX4"}, */ |
| |
| {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG4BPI6_SSID /*PCI_ANY_ID */ , PEG4BPI6, "PEG4BPI6"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG4BPFI6_SSID /*PCI_ANY_ID */ , PEG4BPFI6, "PEG4BPFI6"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG4BPFI6LX_SSID /*PCI_ANY_ID */ , PEG4BPFI6LX, "PEG4BPFI6LX"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG4BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6ZX, "PEG4BPFI6ZX"}, |
| {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2BPI6_SSID /*PCI_ANY_ID */ , PEG2BPI6, "PEG2BPI6"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2BPFI6_SSID /*PCI_ANY_ID */ , PEG2BPFI6, "PEG2BPFI6"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2BPFI6LX_SSID /*PCI_ANY_ID */ , PEG2BPFI6LX, "PEG2BPFI6LX"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2BPFI6ZX_SSID /*PCI_ANY_ID */ , PEG2BPFI6ZX, "PEG2BPFI6ZX"}, |
| {0x8086, 0x10e7, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2BPFI6FLXM_SSID /*PCI_ANY_ID */ , PEG2BPFI6FLXM, |
| "PEG2BPFI6FLXM"}, |
| {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG4BPI6FC_SSID /*PCI_ANY_ID */ , PEG4BPI6FC, "PEG4BPI6FC"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG4BPFI6FC_SSID /*PCI_ANY_ID */ , PEG4BPFI6FC, "PEG4BPFI6FC"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG4BPFI6FCLX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCLX, |
| "PEG4BPFI6FCLX"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG4BPFI6FCZX_SSID /*PCI_ANY_ID */ , PEG4BPFI6FCZX, |
| "PEG4BPFI6FCZX"}, |
| {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG6BPI6_SSID /*PCI_ANY_ID */ , PEG6BPI6, "PEG6BPI6"}, |
| {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2BPI6SC6_SSID /*PCI_ANY_ID */ , PEG2BPI6SC6, |
| "PEG6BPI62SC6"}, |
| {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_MEG2BPI6_SSID /*PCI_ANY_ID */ , MEG2BPI6, "MEG2BPI6"}, |
| {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID */ , XEG2BPI6, "XEG2BPI6"}, |
| {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_MEG4BPI6_SSID /*PCI_ANY_ID */ , MEG4BPI6, "MEG4BPI6"}, |
| |
| {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , SILICOM_PEG2BPFI5_SSID, |
| PEG2BPFI5, "PEG2BPFI5"}, |
| {0x8086, 0x10a9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2BPFI5LX_SSID, PEG2BPFI5LX, "PEG2BPFI5LX"}, |
| |
| {0x8086, 0x105f, SILICOM_SVID, SILICOM_PXEG4BPFI_SSID, PXEG4BPFI, |
| "PXEG4BPFI-SD"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1EG2BPI6_SSID /*PCI_ANY_ID */ , M1EG2BPI6, "MxEG2BPI6"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1EG2BPFI6_SSID /*PCI_ANY_ID */ , M1EG2BPFI6, "MxEG2BPFI6"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6LX, |
| "MxEG2BPFI6LX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG2BPFI6ZX, |
| "MxEG2BPFI6ZX"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1EG4BPI6_SSID /*PCI_ANY_ID */ , M1EG4BPI6, "MxEG4BPI6"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1EG4BPFI6_SSID /*PCI_ANY_ID */ , M1EG4BPFI6, "MxEG4BPFI6"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6LX, |
| "MxEG4BPFI6LX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M1EG4BPFI6ZX, |
| "MxEG4BPFI6ZX"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1EG6BPI6_SSID /*PCI_ANY_ID */ , M1EG6BPI6, "MxEG6BPI6"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1E2G4BPi80_SSID /*PCI_ANY_ID */ , M1E2G4BPi80, "MxE2G4BPi80"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1E2G4BPFi80_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80, |
| "MxE2G4BPFi80"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1E2G4BPFi80LX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80LX, |
| "MxE2G4BPFi80LX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1E2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , M1E2G4BPFi80ZX, |
| "MxE2G4BPFi80ZX"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2EG2BPFI6_SSID /*PCI_ANY_ID */ , M2EG2BPFI6, "M2EG2BPFI6"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2EG2BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6LX, |
| "M2EG2BPFI6LX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2EG2BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG2BPFI6ZX, |
| "M2EG2BPFI6ZX"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2EG4BPI6_SSID /*PCI_ANY_ID */ , M2EG4BPI6, "M2EG4BPI6"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2EG4BPFI6_SSID /*PCI_ANY_ID */ , M2EG4BPFI6, "M2EG4BPFI6"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2EG4BPFI6LX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6LX, |
| "M2EG4BPFI6LX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2EG4BPFI6ZX_SSID /*PCI_ANY_ID */ , M2EG4BPFI6ZX, |
| "M2EG4BPFI6ZX"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2EG6BPI6_SSID /*PCI_ANY_ID */ , M2EG6BPI6, "M2EG6BPI6"}, |
| |
| {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2DBI6_SSID /*PCI_ANY_ID */ , PEG2DBI6, "PEG2DBI6"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2DBFI6_SSID /*PCI_ANY_ID */ , PEG2DBFI6, "PEG2DBFI6"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2DBFI6LX_SSID /*PCI_ANY_ID */ , PEG2DBFI6LX, "PEG2DBFI6LX"}, |
| {0x8086, 0x10e6, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PEG2DBFI6ZX_SSID /*PCI_ANY_ID */ , PEG2DBFI6ZX, "PEG2DBFI6ZX"}, |
| |
| {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE210G2DBi9SR_SSID, PE210G2DBi9SR, "PE210G2DBi9SR"}, |
| {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE210G2DBi9LR_SSID, PE210G2DBi9LR, "PE210G2DBi9LR"}, |
| {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE310G4DBi940SR_SSID, PE310G4DBi940SR, "PE310G4DBi9SR"}, |
| |
| {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE310G4BPi9T_SSID, PE310G4BPi9T, "PE310G4BPi9T"}, |
| {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE310G4BPi9SR_SSID, PE310G4BPi9SR, "PE310G4BPi9SR"}, |
| {0x8086, 0x10Fb, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE310G4BPi9LR_SSID, PE310G4BPi9LR, "PE310G4BPi9LR"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G4BPi80_SSID /*PCI_ANY_ID */ , PE2G4BPi80, "PE2G4BPi80"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G4BPFi80_SSID /*PCI_ANY_ID */ , PE2G4BPFi80, "PE2G4BPFi80"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G4BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80LX, |
| "PE2G4BPFi80LX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G4BPFi80ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi80ZX, |
| "PE2G4BPFi80ZX"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G4BPi80L_SSID /*PCI_ANY_ID */ , PE2G4BPi80L, "PE2G4BPi80L"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M6E2G8BPi80A_SSID /*PCI_ANY_ID */ , M6E2G8BPi80A, |
| "MxE2G8BPi80A"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G2BPi35_SSID /*PCI_ANY_ID */ , PE2G2BPi35, "PE2G2BPi35"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PAC1200BPi35_SSID /*PCI_ANY_ID */ , PAC1200BPi35, |
| "PAC1200BPi35"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G2BPFi35_SSID /*PCI_ANY_ID */ , PE2G2BPFi35, "PE2G2BPFi35"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G2BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35LX, |
| "PE2G2BPFi35LX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G2BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G2BPFi35ZX, |
| "PE2G2BPFi35ZX"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G4BPi35_SSID /*PCI_ANY_ID */ , PE2G4BPi35, "PE2G4BPi35"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G4BPi35L_SSID /*PCI_ANY_ID */ , PE2G4BPi35L, "PE2G4BPi35L"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G4BPFi35_SSID /*PCI_ANY_ID */ , PE2G4BPFi35, "PE2G4BPFi35"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G4BPFi35LX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35LX, |
| "PE2G4BPFi35LX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G4BPFi35ZX_SSID /*PCI_ANY_ID */ , PE2G4BPFi35ZX, |
| "PE2G4BPFi35ZX"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G6BPi35_SSID /*PCI_ANY_ID */ , PE2G6BPi35, "PE2G6BPi35"}, |
| |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa0, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa1, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa2, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa3, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa4, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa5, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa6, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa7, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa8, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa9, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaa, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaab, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaac, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaad, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaae, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaaf, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab0, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab1, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab2, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab3, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab4, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab5, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab6, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab7, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab8, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xab9, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaba, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabb, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabc, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabd, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabe, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xabf, PE2G6BPi35CX, |
| "PE2G6BPi35CX"}, |
| |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G2BPi80_SSID /*PCI_ANY_ID */ , PE2G2BPi80, "PE2G2BPi80"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G2BPFi80_SSID /*PCI_ANY_ID */ , PE2G2BPFi80, "PE2G2BPFi80"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G2BPFi80LX_SSID /*PCI_ANY_ID */ , PE2G2BPFi80LX, |
| "PE2G2BPFi80LX"}, |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE2G2BPFi80ZX_SSID /*PCI_ANY_ID */ , PE2G2BPFi80ZX, |
| "PE2G2BPFi80ZX"}, |
| |
| {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_MEG2BPI6_SSID /*PCI_ANY_ID */ , MEG2BPI6, "MEG2BPI6"}, |
| {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_XEG2BPI6_SSID /*PCI_ANY_ID */ , XEG2BPI6, "XEG2BPI6"}, |
| |
| #if 0 |
| {0x8086, 0x10fb, 0x8086, INTEL_PE210G2SPI9_SSID, PE210G2SPI9, |
| "PE210G2SPI9"}, |
| #endif |
| {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1E10G2BPI9CX4_SSID /*PCI_ANY_ID */ , M1E10G2BPI9CX4, |
| "MxE210G2BPI9CX4"}, |
| {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1E10G2BPI9SR_SSID /*PCI_ANY_ID */ , M1E10G2BPI9SR, |
| "MxE210G2BPI9SR"}, |
| {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1E10G2BPI9LR_SSID /*PCI_ANY_ID */ , M1E10G2BPI9LR, |
| "MxE210G2BPI9LR"}, |
| {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M1E10G2BPI9T_SSID /*PCI_ANY_ID */ , M1E10G2BPI9T, |
| "MxE210G2BPI9T"}, |
| |
| {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2E10G2BPI9CX4_SSID /*PCI_ANY_ID */ , M2E10G2BPI9CX4, |
| "M2E10G2BPI9CX4"}, |
| {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2E10G2BPI9SR_SSID /*PCI_ANY_ID */ , M2E10G2BPI9SR, |
| "M2E10G2BPI9SR"}, |
| {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2E10G2BPI9LR_SSID /*PCI_ANY_ID */ , M2E10G2BPI9LR, |
| "M2E10G2BPI9LR"}, |
| {0x8086, 0x10fb, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M2E10G2BPI9T_SSID /*PCI_ANY_ID */ , M2E10G2BPI9T, |
| "M2E10G2BPI9T"}, |
| |
| {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9CX4_SSID, |
| PE210G2BPI9CX4, "PE210G2BPI9CX4"}, |
| {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9SR_SSID, |
| PE210G2BPI9SR, "PE210G2BPI9SR"}, |
| {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9LR_SSID, |
| PE210G2BPI9LR, "PE210G2BPI9LR"}, |
| {0x8086, 0x10fb, SILICOM_SVID, SILICOM_PE210G2BPI9T_SSID, PE210G2BPI9T, |
| "PE210G2BPI9T"}, |
| |
| #if 0 |
| {0x1374, 0x2c, SILICOM_SVID, SILICOM_PXG4BPI_SSID, PXG4BPI, |
| "PXG4BPI-SD"}, |
| |
| {0x1374, 0x2d, SILICOM_SVID, SILICOM_PXG4BPFI_SSID, PXG4BPFI, |
| "PXG4BPFI-SD"}, |
| |
| {0x1374, 0x3f, SILICOM_SVID, SILICOM_PXG2TBI_SSID, PXG2TBI, |
| "PXG2TBI-SD"}, |
| |
| {0x1374, 0x3d, SILICOM_SVID, SILICOM_PXG2BISC1_SSID, PXG2BISC1, |
| "PXG2BISC1-SD"}, |
| |
| {0x1374, 0x40, SILICOM_SVID, SILICOM_PEG4BPFI_SSID, PEG4BPFI, |
| "PEG4BPFI-SD"}, |
| |
| #ifdef BP_SELF_TEST |
| {0x1374, 0x28, SILICOM_SVID, 0x28, PXGBPI, "PXG2BPI-SD"}, |
| #endif |
| #endif |
| {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_M6E2G8BPi80_SSID /*PCI_ANY_ID */ , M6E2G8BPi80, "MxE2G8BPi80"}, |
| {0x8086, 0x1528, SILICOM_SVID /*PCI_ANY_ID */ , |
| SILICOM_PE210G2BPi40_SSID /*PCI_ANY_ID */ , PE210G2BPi40, |
| "PE210G2BPi40T"}, |
| |
| /* required last entry */ |
| {0,} |
| }; |
| |
| static void find_fw(bpctl_dev_t *dev) |
| { |
| unsigned long mmio_start, mmio_len; |
| struct pci_dev *pdev1 = dev->pdev; |
| |
| if ((OLD_IF_SERIES(dev->subdevice)) || |
| (INTEL_IF_SERIES(dev->subdevice))) |
| dev->bp_fw_ver = 0xff; |
| else |
| dev->bp_fw_ver = bypass_fw_ver(dev); |
| |
| if (dev->bp_10gb == 1 && dev->bp_fw_ver == 0xff) { |
| int cnt = 100; |
| while (cnt--) { |
| iounmap((void *)dev->mem_map); |
| mmio_start = pci_resource_start(pdev1, 0); |
| mmio_len = pci_resource_len(pdev1, 0); |
| |
| dev->mem_map = (unsigned long) |
| ioremap(mmio_start, mmio_len); |
| |
| dev->bp_fw_ver = bypass_fw_ver(dev); |
| if (dev-> bp_fw_ver == 0xa8) |
| break; |
| } |
| } |
| /* dev->bp_fw_ver=0xa8; */ |
| printk("firmware version: 0x%x\n", dev->bp_fw_ver); |
| } |
| |
| static int init_one(bpctl_dev_t *dev, bpmod_info_t *info, struct pci_dev *pdev1) |
| { |
| unsigned long mmio_start, mmio_len; |
| |
| dev->pdev = pdev1; |
| mmio_start = pci_resource_start(pdev1, 0); |
| mmio_len = pci_resource_len(pdev1, 0); |
| |
| dev->desc = dev_desc[info->index].name; |
| dev->name = info->bp_name; |
| dev->device = info->device; |
| dev->vendor = info->vendor; |
| dev->subdevice = info->subdevice; |
| dev->subvendor = info->subvendor; |
| dev->func = PCI_FUNC(pdev1->devfn); |
| dev->slot = PCI_SLOT(pdev1->devfn); |
| dev->bus = pdev1->bus->number; |
| dev->mem_map = (unsigned long)ioremap(mmio_start, mmio_len); |
| #ifdef BP_SYNC_FLAG |
| spin_lock_init(&dev->bypass_wr_lock); |
| #endif |
| if (BP10G9_IF_SERIES(dev->subdevice)) |
| dev->bp_10g9 = 1; |
| if (BP10G_IF_SERIES(dev->subdevice)) |
| dev->bp_10g = 1; |
| if (PEG540_IF_SERIES(dev->subdevice)) |
| dev->bp_540 = 1; |
| if (PEGF5_IF_SERIES(dev->subdevice)) |
| dev->bp_fiber5 = 1; |
| if (PEG80_IF_SERIES(dev->subdevice)) |
| dev->bp_i80 = 1; |
| if (PEGF80_IF_SERIES(dev->subdevice)) |
| dev->bp_i80 = 1; |
| if ((dev->subdevice & 0xa00) == 0xa00) |
| dev->bp_i80 = 1; |
| if (BP10GB_IF_SERIES(dev->subdevice)) { |
| if (dev->ifindex == 0) { |
| unregister_chrdev(major_num, DEVICE_NAME); |
| printk("Please load network driver for %s adapter!\n", |
| dev->name); |
| return -1; |
| } |
| |
| if (dev->ndev && !(dev->ndev->flags & IFF_UP)) { |
| unregister_chrdev(major_num, DEVICE_NAME); |
| printk("Please bring up network interfaces for %s adapter!\n", |
| dev->name); |
| return -1; |
| } |
| dev->bp_10gb = 1; |
| } |
| |
| if (!dev->bp_10g9) { |
| if (is_bypass_fn(dev)) { |
| printk(KERN_INFO "%s found, ", |
| dev->name); |
| find_fw(dev); |
| } |
| dev->wdt_status = WDT_STATUS_UNKNOWN; |
| dev->reset_time = 0; |
| atomic_set(&dev->wdt_busy, 0); |
| dev->bp_status_un = 1; |
| |
| bypass_caps_init(dev); |
| |
| init_bypass_wd_auto(dev); |
| init_bypass_tpl_auto(dev); |
| if (NOKIA_SERIES(dev->subdevice)) |
| reset_cont(dev); |
| } |
| #ifdef BP_SELF_TEST |
| if ((dev->bp_tx_data = kzalloc(BPTEST_DATA_LEN, GFP_KERNEL))) { |
| memset(dev->bp_tx_data, 0xff, 6); |
| memset(dev->bp_tx_data + 6, 0x0, 1); |
| memset(dev->bp_tx_data + 7, 0xaa, 5); |
| *(__be16 *)(dev->bp_tx_data + 12) = htons(ETH_P_BPTEST); |
| } else |
| printk("bp_ctl: Memory allocation error!\n"); |
| #endif |
| return 0; |
| } |
| |
| /* |
| * Initialize the module - Register the character device |
| */ |
| |
| static int __init bypass_init_module(void) |
| { |
| int ret_val, idx, idx_dev = 0; |
| struct pci_dev *pdev1 = NULL; |
| bpctl_dev_t *dev; |
| |
| printk(BP_MOD_DESCR " v" BP_MOD_VER "\n"); |
| ret_val = register_chrdev(major_num, DEVICE_NAME, &Fops); |
| if (ret_val < 0) { |
| printk("%s failed with %d\n", DEVICE_NAME, ret_val); |
| return ret_val; |
| } |
| major_num = ret_val; /* dynamic */ |
| for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) { |
| while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor, |
| tx_ctl_pci_tbl[idx].device, |
| tx_ctl_pci_tbl[idx].subvendor, |
| tx_ctl_pci_tbl[idx].subdevice, |
| pdev1))) { |
| |
| device_num++; |
| } |
| } |
| if (!device_num) { |
| printk("No such device\n"); |
| unregister_chrdev(major_num, DEVICE_NAME); |
| return -1; |
| } |
| |
| bpctl_dev_arr = kmalloc((device_num) * sizeof(bpctl_dev_t), GFP_KERNEL); |
| |
| if (!bpctl_dev_arr) { |
| printk("Allocation error\n"); |
| unregister_chrdev(major_num, DEVICE_NAME); |
| return -1; |
| } |
| memset(bpctl_dev_arr, 0, ((device_num) * sizeof(bpctl_dev_t))); |
| |
| pdev1 = NULL; |
| dev = bpctl_dev_arr; |
| for (idx = 0; tx_ctl_pci_tbl[idx].vendor; idx++) { |
| while ((pdev1 = pci_get_subsys(tx_ctl_pci_tbl[idx].vendor, |
| tx_ctl_pci_tbl[idx].device, |
| tx_ctl_pci_tbl[idx].subvendor, |
| tx_ctl_pci_tbl[idx].subdevice, |
| pdev1))) { |
| if (init_one(dev, &tx_ctl_pci_tbl[idx], pdev1) < 0) |
| return -1; |
| dev++; |
| } |
| } |
| if_scan_init(); |
| |
| sema_init(&bpctl_sema, 1); |
| spin_lock_init(&bpvm_lock); |
| { |
| |
| bpctl_dev_t *pbpctl_dev_c = NULL; |
| for (idx_dev = 0, dev = bpctl_dev_arr; |
| idx_dev < device_num && dev->pdev; |
| idx_dev++, dev++) { |
| if (dev->bp_10g9) { |
| pbpctl_dev_c = get_status_port_fn(dev); |
| if (is_bypass_fn(dev)) { |
| printk(KERN_INFO "%s found, ", |
| dev->name); |
| dev->bp_fw_ver = bypass_fw_ver(dev); |
| printk("firmware version: 0x%x\n", |
| dev->bp_fw_ver); |
| } |
| dev->wdt_status = WDT_STATUS_UNKNOWN; |
| dev->reset_time = 0; |
| atomic_set(&dev->wdt_busy, 0); |
| dev->bp_status_un = 1; |
| |
| bypass_caps_init(dev); |
| |
| init_bypass_wd_auto(dev); |
| init_bypass_tpl_auto(dev); |
| |
| } |
| |
| } |
| } |
| |
| register_netdevice_notifier(&bp_notifier_block); |
| #ifdef BP_PROC_SUPPORT |
| { |
| int i = 0; |
| /* unsigned long flags; */ |
| /* rcu_read_lock(); */ |
| bp_proc_create(); |
| for (i = 0; i < device_num; i++) { |
| if (bpctl_dev_arr[i].ifindex) { |
| /* spin_lock_irqsave(&bpvm_lock, flags); */ |
| bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]); |
| bypass_proc_create_dev_sd(&bpctl_dev_arr[i]); |
| /* spin_unlock_irqrestore(&bpvm_lock, flags); */ |
| } |
| |
| } |
| /* rcu_read_unlock(); */ |
| } |
| #endif |
| |
| return 0; |
| } |
| |
| /* |
| * Cleanup - unregister the appropriate file from /proc |
| */ |
| static void __exit bypass_cleanup_module(void) |
| { |
| int i; |
| unregister_netdevice_notifier(&bp_notifier_block); |
| |
| for (i = 0; i < device_num; i++) { |
| /* unsigned long flags; */ |
| #ifdef BP_PROC_SUPPORT |
| /* spin_lock_irqsave(&bpvm_lock, flags); |
| rcu_read_lock(); */ |
| bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]); |
| /* spin_unlock_irqrestore(&bpvm_lock, flags); |
| rcu_read_unlock(); */ |
| #endif |
| remove_bypass_wd_auto(&bpctl_dev_arr[i]); |
| bpctl_dev_arr[i].reset_time = 0; |
| |
| remove_bypass_tpl_auto(&bpctl_dev_arr[i]); |
| } |
| |
| /* unmap all devices */ |
| for (i = 0; i < device_num; i++) { |
| #ifdef BP_SELF_TEST |
| kfree(bpctl_dev_arr[i].bp_tx_data); |
| #endif |
| iounmap((void *)(bpctl_dev_arr[i].mem_map)); |
| } |
| |
| /* free all devices space */ |
| kfree(bpctl_dev_arr); |
| |
| /* |
| * Unregister the device |
| */ |
| unregister_chrdev(major_num, DEVICE_NAME); |
| } |
| |
| module_init(bypass_init_module); |
| module_exit(bypass_cleanup_module); |
| |
| int is_bypass_sd(int ifindex) |
| { |
| return is_bypass(get_dev_idx_p(ifindex)); |
| } |
| |
| int set_bypass_sd(int ifindex, int bypass_mode) |
| { |
| |
| return set_bypass_fn(get_dev_idx_p(ifindex), bypass_mode); |
| } |
| |
| int get_bypass_sd(int ifindex) |
| { |
| |
| return get_bypass_fn(get_dev_idx_p(ifindex)); |
| } |
| |
| int get_bypass_change_sd(int ifindex) |
| { |
| |
| return get_bypass_change_fn(get_dev_idx_p(ifindex)); |
| } |
| |
| int set_dis_bypass_sd(int ifindex, int dis_param) |
| { |
| return set_dis_bypass_fn(get_dev_idx_p(ifindex), dis_param); |
| } |
| |
| int get_dis_bypass_sd(int ifindex) |
| { |
| |
| return get_dis_bypass_fn(get_dev_idx_p(ifindex)); |
| } |
| |
| int set_bypass_pwoff_sd(int ifindex, int bypass_mode) |
| { |
| return set_bypass_pwoff_fn(get_dev_idx_p(ifindex), bypass_mode); |
| |
| } |
| |
| int get_bypass_pwoff_sd(int ifindex) |
| { |
| return get_bypass_pwoff_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int set_bypass_pwup_sd(int ifindex, int bypass_mode) |
| { |
| return set_bypass_pwup_fn(get_dev_idx_p(ifindex), bypass_mode); |
| |
| } |
| |
| int get_bypass_pwup_sd(int ifindex) |
| { |
| return get_bypass_pwup_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set) |
| { |
| if ((is_bypass(get_dev_idx_p(if_index))) <= 0) |
| return BP_NOT_CAP; |
| *ms_timeout_set = set_bypass_wd_fn(get_dev_idx_p(if_index), ms_timeout); |
| return 0; |
| } |
| |
| int get_bypass_wd_sd(int ifindex, int *timeout) |
| { |
| return get_bypass_wd_fn(get_dev_idx_p(ifindex), timeout); |
| |
| } |
| |
| int get_wd_expire_time_sd(int ifindex, int *time_left) |
| { |
| return get_wd_expire_time_fn(get_dev_idx_p(ifindex), time_left); |
| } |
| |
| int reset_bypass_wd_timer_sd(int ifindex) |
| { |
| return reset_bypass_wd_timer_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int get_wd_set_caps_sd(int ifindex) |
| { |
| return get_wd_set_caps_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int set_std_nic_sd(int ifindex, int nic_mode) |
| { |
| return set_std_nic_fn(get_dev_idx_p(ifindex), nic_mode); |
| |
| } |
| |
| int get_std_nic_sd(int ifindex) |
| { |
| return get_std_nic_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int set_tap_sd(int ifindex, int tap_mode) |
| { |
| return set_tap_fn(get_dev_idx_p(ifindex), tap_mode); |
| |
| } |
| |
| int get_tap_sd(int ifindex) |
| { |
| return get_tap_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int set_tap_pwup_sd(int ifindex, int tap_mode) |
| { |
| return set_tap_pwup_fn(get_dev_idx_p(ifindex), tap_mode); |
| |
| } |
| |
| int get_tap_pwup_sd(int ifindex) |
| { |
| return get_tap_pwup_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int get_tap_change_sd(int ifindex) |
| { |
| return get_tap_change_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int set_dis_tap_sd(int ifindex, int dis_param) |
| { |
| return set_dis_tap_fn(get_dev_idx_p(ifindex), dis_param); |
| |
| } |
| |
| int get_dis_tap_sd(int ifindex) |
| { |
| return get_dis_tap_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int set_bp_disc_sd(int ifindex, int disc_mode) |
| { |
| return set_disc_fn(get_dev_idx_p(ifindex), disc_mode); |
| |
| } |
| |
| int get_bp_disc_sd(int ifindex) |
| { |
| return get_disc_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int set_bp_disc_pwup_sd(int ifindex, int disc_mode) |
| { |
| return set_disc_pwup_fn(get_dev_idx_p(ifindex), disc_mode); |
| |
| } |
| |
| int get_bp_disc_pwup_sd(int ifindex) |
| { |
| return get_disc_pwup_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int get_bp_disc_change_sd(int ifindex) |
| { |
| return get_disc_change_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int set_bp_dis_disc_sd(int ifindex, int dis_param) |
| { |
| return set_dis_disc_fn(get_dev_idx_p(ifindex), dis_param); |
| |
| } |
| |
| int get_bp_dis_disc_sd(int ifindex) |
| { |
| return get_dis_disc_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int get_wd_exp_mode_sd(int ifindex) |
| { |
| return get_wd_exp_mode_fn(get_dev_idx_p(ifindex)); |
| } |
| |
| int set_wd_exp_mode_sd(int ifindex, int param) |
| { |
| return set_wd_exp_mode_fn(get_dev_idx_p(ifindex), param); |
| |
| } |
| |
| int reset_cont_sd(int ifindex) |
| { |
| return reset_cont_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int set_tx_sd(int ifindex, int tx_state) |
| { |
| return set_tx_fn(get_dev_idx_p(ifindex), tx_state); |
| |
| } |
| |
| int set_tpl_sd(int ifindex, int tpl_state) |
| { |
| return set_tpl_fn(get_dev_idx_p(ifindex), tpl_state); |
| |
| } |
| |
| int set_bp_hw_reset_sd(int ifindex, int status) |
| { |
| return set_bp_hw_reset_fn(get_dev_idx_p(ifindex), status); |
| |
| } |
| |
| int set_wd_autoreset_sd(int ifindex, int param) |
| { |
| return set_wd_autoreset_fn(get_dev_idx_p(ifindex), param); |
| |
| } |
| |
| int get_wd_autoreset_sd(int ifindex) |
| { |
| return get_wd_autoreset_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int get_bypass_caps_sd(int ifindex) |
| { |
| return get_bypass_caps_fn(get_dev_idx_p(ifindex)); |
| } |
| |
| int get_bypass_slave_sd(int ifindex) |
| { |
| bpctl_dev_t *pbpctl_dev_out; |
| int ret = get_bypass_slave_fn(get_dev_idx_p(ifindex), &pbpctl_dev_out); |
| if (ret == 1) |
| return pbpctl_dev_out->ifindex; |
| return -1; |
| |
| } |
| |
| int get_tx_sd(int ifindex) |
| { |
| return get_tx_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int get_tpl_sd(int ifindex) |
| { |
| return get_tpl_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int get_bp_hw_reset_sd(int ifindex) |
| { |
| return get_bp_hw_reset_fn(get_dev_idx_p(ifindex)); |
| |
| } |
| |
| int get_bypass_info_sd(int ifindex, struct bp_info *bp_info) |
| { |
| return get_bypass_info_fn(get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver); |
| } |
| |
| int bp_if_scan_sd(void) |
| { |
| if_scan_init(); |
| return 0; |
| } |
| |
| EXPORT_SYMBOL_NOVERS(is_bypass_sd); |
| EXPORT_SYMBOL_NOVERS(get_bypass_slave_sd); |
| EXPORT_SYMBOL_NOVERS(get_bypass_caps_sd); |
| EXPORT_SYMBOL_NOVERS(get_wd_set_caps_sd); |
| EXPORT_SYMBOL_NOVERS(set_bypass_sd); |
| EXPORT_SYMBOL_NOVERS(get_bypass_sd); |
| EXPORT_SYMBOL_NOVERS(get_bypass_change_sd); |
| EXPORT_SYMBOL_NOVERS(set_dis_bypass_sd); |
| EXPORT_SYMBOL_NOVERS(get_dis_bypass_sd); |
| EXPORT_SYMBOL_NOVERS(set_bypass_pwoff_sd); |
| EXPORT_SYMBOL_NOVERS(get_bypass_pwoff_sd); |
| EXPORT_SYMBOL_NOVERS(set_bypass_pwup_sd); |
| EXPORT_SYMBOL_NOVERS(get_bypass_pwup_sd); |
| EXPORT_SYMBOL_NOVERS(set_bypass_wd_sd); |
| EXPORT_SYMBOL_NOVERS(get_bypass_wd_sd); |
| EXPORT_SYMBOL_NOVERS(get_wd_expire_time_sd); |
| EXPORT_SYMBOL_NOVERS(reset_bypass_wd_timer_sd); |
| EXPORT_SYMBOL_NOVERS(set_std_nic_sd); |
| EXPORT_SYMBOL_NOVERS(get_std_nic_sd); |
| EXPORT_SYMBOL_NOVERS(set_tx_sd); |
| EXPORT_SYMBOL_NOVERS(get_tx_sd); |
| EXPORT_SYMBOL_NOVERS(set_tpl_sd); |
| EXPORT_SYMBOL_NOVERS(get_tpl_sd); |
| EXPORT_SYMBOL_NOVERS(set_bp_hw_reset_sd); |
| EXPORT_SYMBOL_NOVERS(get_bp_hw_reset_sd); |
| EXPORT_SYMBOL_NOVERS(set_tap_sd); |
| EXPORT_SYMBOL_NOVERS(get_tap_sd); |
| EXPORT_SYMBOL_NOVERS(get_tap_change_sd); |
| EXPORT_SYMBOL_NOVERS(set_dis_tap_sd); |
| EXPORT_SYMBOL_NOVERS(get_dis_tap_sd); |
| EXPORT_SYMBOL_NOVERS(set_tap_pwup_sd); |
| EXPORT_SYMBOL_NOVERS(get_tap_pwup_sd); |
| EXPORT_SYMBOL_NOVERS(set_wd_exp_mode_sd); |
| EXPORT_SYMBOL_NOVERS(get_wd_exp_mode_sd); |
| EXPORT_SYMBOL_NOVERS(set_wd_autoreset_sd); |
| EXPORT_SYMBOL_NOVERS(get_wd_autoreset_sd); |
| EXPORT_SYMBOL_NOVERS(set_bp_disc_sd); |
| EXPORT_SYMBOL_NOVERS(get_bp_disc_sd); |
| EXPORT_SYMBOL_NOVERS(get_bp_disc_change_sd); |
| EXPORT_SYMBOL_NOVERS(set_bp_dis_disc_sd); |
| EXPORT_SYMBOL_NOVERS(get_bp_dis_disc_sd); |
| EXPORT_SYMBOL_NOVERS(set_bp_disc_pwup_sd); |
| EXPORT_SYMBOL_NOVERS(get_bp_disc_pwup_sd); |
| EXPORT_SYMBOL_NOVERS(get_bypass_info_sd); |
| EXPORT_SYMBOL_NOVERS(bp_if_scan_sd); |
| |
| #define BP_PROC_DIR "bypass" |
| |
| static struct proc_dir_entry *bp_procfs_dir; |
| |
| int bp_proc_create(void) |
| { |
| bp_procfs_dir = proc_mkdir(BP_PROC_DIR, init_net.proc_net); |
| if (bp_procfs_dir == (struct proc_dir_entry *)0) { |
| printk(KERN_DEBUG |
| "Could not create procfs nicinfo directory %s\n", |
| BP_PROC_DIR); |
| return -1; |
| } |
| return 0; |
| } |
| |
| static int procfs_add(char *proc_name, const struct file_operations *fops, |
| bpctl_dev_t *dev) |
| { |
| struct bypass_pfs_sd *pfs = &dev->bypass_pfs_set; |
| if (!proc_create_data(proc_name, 0644, pfs->bypass_entry, fops, dev)) |
| return -1; |
| return 0; |
| } |
| |
| #define RO_FOPS(name) \ |
| static int name##_open(struct inode *inode, struct file *file) \ |
| { \ |
| return single_open(file, show_##name, PDE_DATA(inode));\ |
| } \ |
| static const struct file_operations name##_ops = { \ |
| .open = name##_open, \ |
| .read = seq_read, \ |
| .llseek = seq_lseek, \ |
| .release = single_release, \ |
| }; |
| |
| #define RW_FOPS(name) \ |
| static int name##_open(struct inode *inode, struct file *file) \ |
| { \ |
| return single_open(file, show_##name, PDE_DATA(inode));\ |
| } \ |
| static const struct file_operations name##_ops = { \ |
| .open = name##_open, \ |
| .read = seq_read, \ |
| .write = name##_write, \ |
| .llseek = seq_lseek, \ |
| .release = single_release, \ |
| }; |
| |
| static int show_bypass_info(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| |
| seq_printf(m, "Name\t\t\t%s\n", dev->name); |
| seq_printf(m, "Firmware version\t0x%x\n", dev->bp_fw_ver); |
| return 0; |
| } |
| RO_FOPS(bypass_info) |
| |
| static int show_bypass_slave(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| bpctl_dev_t *slave = get_status_port_fn(dev); |
| if (!slave) |
| slave = dev; |
| if (!slave) |
| seq_printf(m, "fail\n"); |
| else if (slave->ndev) |
| seq_printf(m, "%s\n", slave->ndev->name); |
| return 0; |
| } |
| RO_FOPS(bypass_slave) |
| |
| static int show_bypass_caps(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_bypass_caps_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "-1\n"); |
| else |
| seq_printf(m, "0x%x\n", ret); |
| return 0; |
| } |
| RO_FOPS(bypass_caps) |
| |
| static int show_wd_set_caps(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_wd_set_caps_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "-1\n"); |
| else |
| seq_printf(m, "0x%x\n", ret); |
| return 0; |
| } |
| RO_FOPS(wd_set_caps) |
| |
| static int user_on_off(const void __user *buffer, size_t count) |
| { |
| |
| char kbuf[256]; |
| int length = 0; |
| |
| if (count > (sizeof(kbuf) - 1)) |
| return -1; |
| |
| if (copy_from_user(&kbuf, buffer, count)) |
| return -1; |
| |
| kbuf[count] = '\0'; |
| length = strlen(kbuf); |
| if (kbuf[length - 1] == '\n') |
| kbuf[--length] = '\0'; |
| |
| if (strcmp(kbuf, "on") == 0) |
| return 1; |
| if (strcmp(kbuf, "off") == 0) |
| return 0; |
| return 0; |
| } |
| |
| static ssize_t bypass_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int bypass_param = user_on_off(buffer, count); |
| if (bypass_param < 0) |
| return -1; |
| |
| set_bypass_fn(PDE_DATA(file_inode(file)), bypass_param); |
| return count; |
| } |
| static int show_bypass(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_bypass_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 1) |
| seq_printf(m, "on\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| return 0; |
| } |
| RW_FOPS(bypass) |
| |
| static ssize_t tap_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int tap_param = user_on_off(buffer, count); |
| if (tap_param < 0) |
| return -1; |
| |
| set_tap_fn(PDE_DATA(file_inode(file)), tap_param); |
| return count; |
| } |
| static int show_tap(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_tap_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 1) |
| seq_printf(m, "on\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| return 0; |
| } |
| RW_FOPS(tap) |
| |
| static ssize_t disc_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int tap_param = user_on_off(buffer, count); |
| if (tap_param < 0) |
| return -1; |
| |
| set_disc_fn(PDE_DATA(file_inode(file)), tap_param); |
| return count; |
| } |
| static int show_disc(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_disc_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 1) |
| seq_printf(m, "on\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| return 0; |
| } |
| RW_FOPS(disc) |
| |
| static int show_bypass_change(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_bypass_change_fn(dev); |
| if (ret == 1) |
| seq_printf(m, "on\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| else |
| seq_printf(m, "fail\n"); |
| return 0; |
| } |
| RO_FOPS(bypass_change) |
| |
| static int show_tap_change(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_tap_change_fn(dev); |
| if (ret == 1) |
| seq_printf(m, "on\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| else |
| seq_printf(m, "fail\n"); |
| return 0; |
| } |
| RO_FOPS(tap_change) |
| |
| static int show_disc_change(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_disc_change_fn(dev); |
| if (ret == 1) |
| seq_printf(m, "on\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| else |
| seq_printf(m, "fail\n"); |
| return 0; |
| } |
| RO_FOPS(disc_change) |
| |
| static ssize_t bypass_wd_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| bpctl_dev_t *dev = PDE_DATA(file_inode(file)); |
| int timeout; |
| int ret = kstrtoint_from_user(buffer, count, 10, &timeout); |
| if (ret) |
| return ret; |
| set_bypass_wd_fn(dev, timeout); |
| return count; |
| } |
| static int show_bypass_wd(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = 0, timeout = 0; |
| |
| ret = get_bypass_wd_fn(dev, &timeout); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (timeout == -1) |
| seq_printf(m, "unknown\n"); |
| else if (timeout == 0) |
| seq_printf(m, "disable\n"); |
| else |
| seq_printf(m, "%d\n", timeout); |
| return 0; |
| } |
| RW_FOPS(bypass_wd) |
| |
| static int show_wd_expire_time(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = 0, timeout = 0; |
| ret = get_wd_expire_time_fn(dev, &timeout); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (timeout == -1) |
| seq_printf(m, "expire\n"); |
| else if (timeout == 0) |
| seq_printf(m, "disable\n"); |
| else |
| seq_printf(m, "%d\n", timeout); |
| return 0; |
| } |
| RO_FOPS(wd_expire_time) |
| |
| static ssize_t tpl_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| bpctl_dev_t *dev = PDE_DATA(file_inode(file)); |
| int tpl_param = user_on_off(buffer, count); |
| if (tpl_param < 0) |
| return -1; |
| |
| set_tpl_fn(dev, tpl_param); |
| return count; |
| } |
| static int show_tpl(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_tpl_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 1) |
| seq_printf(m, "on\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| return 0; |
| } |
| RW_FOPS(tpl) |
| |
| #ifdef PMC_FIX_FLAG |
| static ssize_t wait_at_pwup_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| bpctl_dev_t *dev = PDE_DATA(file_inode(file)); |
| int tpl_param = user_on_off(buffer, count); |
| if (tpl_param < 0) |
| return -1; |
| |
| set_bp_wait_at_pwup_fn(dev, tpl_param); |
| return count; |
| } |
| static int show_wait_at_pwup(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_bp_wait_at_pwup_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 1) |
| seq_printf(m, "on\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| return 0; |
| } |
| RW_FOPS(wait_at_pwup) |
| |
| static ssize_t hw_reset_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| bpctl_dev_t *dev = PDE_DATA(file_inode(file)); |
| int tpl_param = user_on_off(buffer, count); |
| if (tpl_param < 0) |
| return -1; |
| |
| set_bp_hw_reset_fn(dev, tpl_param); |
| return count; |
| } |
| static int show_hw_reset(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_bp_hw_reset_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 1) |
| seq_printf(m, "on\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| return 0; |
| } |
| RW_FOPS(hw_reset) |
| |
| #endif /*PMC_WAIT_FLAG */ |
| |
| static int show_reset_bypass_wd(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = reset_bypass_wd_timer_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 0) |
| seq_printf(m, "disable\n"); |
| else if (ret == 1) |
| seq_printf(m, "success\n"); |
| return 0; |
| } |
| RO_FOPS(reset_bypass_wd) |
| |
| static ssize_t dis_bypass_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int bypass_param = user_on_off(buffer, count); |
| if (bypass_param < 0) |
| return -EINVAL; |
| |
| set_dis_bypass_fn(PDE_DATA(file_inode(file)), bypass_param); |
| return count; |
| } |
| static int show_dis_bypass(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_dis_bypass_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| else |
| seq_printf(m, "on\n"); |
| return 0; |
| } |
| RW_FOPS(dis_bypass) |
| |
| static ssize_t dis_tap_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int tap_param = user_on_off(buffer, count); |
| if (tap_param < 0) |
| return -EINVAL; |
| |
| set_dis_tap_fn(PDE_DATA(file_inode(file)), tap_param); |
| return count; |
| } |
| static int show_dis_tap(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_dis_tap_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| else |
| seq_printf(m, "on\n"); |
| return 0; |
| } |
| RW_FOPS(dis_tap) |
| |
| static ssize_t dis_disc_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int tap_param = user_on_off(buffer, count); |
| if (tap_param < 0) |
| return -EINVAL; |
| |
| set_dis_disc_fn(PDE_DATA(file_inode(file)), tap_param); |
| return count; |
| } |
| static int show_dis_disc(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_dis_disc_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| else |
| seq_printf(m, "on\n"); |
| return 0; |
| } |
| RW_FOPS(dis_disc) |
| |
| static ssize_t bypass_pwup_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int bypass_param = user_on_off(buffer, count); |
| if (bypass_param < 0) |
| return -EINVAL; |
| |
| set_bypass_pwup_fn(PDE_DATA(file_inode(file)), bypass_param); |
| return count; |
| } |
| static int show_bypass_pwup(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_bypass_pwup_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| else |
| seq_printf(m, "on\n"); |
| return 0; |
| } |
| RW_FOPS(bypass_pwup) |
| |
| static ssize_t bypass_pwoff_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int bypass_param = user_on_off(buffer, count); |
| if (bypass_param < 0) |
| return -EINVAL; |
| |
| set_bypass_pwoff_fn(PDE_DATA(file_inode(file)), bypass_param); |
| return count; |
| } |
| static int show_bypass_pwoff(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_bypass_pwoff_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| else |
| seq_printf(m, "on\n"); |
| return 0; |
| } |
| RW_FOPS(bypass_pwoff) |
| |
| static ssize_t tap_pwup_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int tap_param = user_on_off(buffer, count); |
| if (tap_param < 0) |
| return -EINVAL; |
| |
| set_tap_pwup_fn(PDE_DATA(file_inode(file)), tap_param); |
| return count; |
| } |
| static int show_tap_pwup(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_tap_pwup_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| else |
| seq_printf(m, "on\n"); |
| return 0; |
| } |
| RW_FOPS(tap_pwup) |
| |
| static ssize_t disc_pwup_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int tap_param = user_on_off(buffer, count); |
| if (tap_param < 0) |
| return -EINVAL; |
| |
| set_disc_pwup_fn(PDE_DATA(file_inode(file)), tap_param); |
| return count; |
| } |
| static int show_disc_pwup(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_disc_pwup_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| else |
| seq_printf(m, "on\n"); |
| return 0; |
| } |
| RW_FOPS(disc_pwup) |
| |
| static ssize_t std_nic_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int bypass_param = user_on_off(buffer, count); |
| if (bypass_param < 0) |
| return -EINVAL; |
| |
| set_std_nic_fn(PDE_DATA(file_inode(file)), bypass_param); |
| return count; |
| } |
| static int show_std_nic(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_std_nic_fn(dev); |
| if (ret == BP_NOT_CAP) |
| seq_printf(m, "fail\n"); |
| else if (ret == 0) |
| seq_printf(m, "off\n"); |
| else |
| seq_printf(m, "on\n"); |
| return 0; |
| } |
| RW_FOPS(std_nic) |
| |
| static ssize_t wd_exp_mode_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| char kbuf[256]; |
| int bypass_param = 0, length = 0; |
| |
| if (count > (sizeof(kbuf) - 1)) |
| return -1; |
| |
| if (copy_from_user(&kbuf, buffer, count)) |
| return -1; |
| |
| kbuf[count] = '\0'; |
| length = strlen(kbuf); |
| if (kbuf[length - 1] == '\n') |
| kbuf[--length] = '\0'; |
| |
| if (strcmp(kbuf, "tap") == 0) |
| bypass_param = 1; |
| else if (strcmp(kbuf, "bypass") == 0) |
| bypass_param = 0; |
| else if (strcmp(kbuf, "disc") == 0) |
| bypass_param = 2; |
| |
| set_wd_exp_mode_fn(PDE_DATA(file_inode(file)), bypass_param); |
| |
| return count; |
| } |
| static int show_wd_exp_mode(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_wd_exp_mode_fn(dev); |
| if (ret == 1) |
| seq_printf(m, "tap\n"); |
| else if (ret == 0) |
| seq_printf(m, "bypass\n"); |
| else if (ret == 2) |
| seq_printf(m, "disc\n"); |
| else |
| seq_printf(m, "fail\n"); |
| return 0; |
| } |
| RW_FOPS(wd_exp_mode) |
| |
| static ssize_t wd_autoreset_write(struct file *file, const char __user *buffer, |
| size_t count, loff_t *pos) |
| { |
| int timeout; |
| int ret = kstrtoint_from_user(buffer, count, 10, &timeout); |
| if (ret) |
| return ret; |
| set_wd_autoreset_fn(PDE_DATA(file_inode(file)), timeout); |
| return count; |
| } |
| static int show_wd_autoreset(struct seq_file *m, void *v) |
| { |
| bpctl_dev_t *dev = m->private; |
| int ret = get_wd_autoreset_fn(dev); |
| if (ret >= 0) |
| seq_printf(m, "%d\n", ret); |
| else |
| seq_printf(m, "fail\n"); |
| return 0; |
| } |
| RW_FOPS(wd_autoreset) |
| |
| int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block) |
| { |
| struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set); |
| static struct proc_dir_entry *procfs_dir = NULL; |
| int ret = 0; |
| |
| if (!pbp_device_block->ndev) |
| return -1; |
| sprintf(current_pfs->dir_name, "bypass_%s", |
| pbp_device_block->ndev->name); |
| |
| if (!bp_procfs_dir) |
| return -1; |
| |
| /* create device proc dir */ |
| procfs_dir = proc_mkdir(current_pfs->dir_name, bp_procfs_dir); |
| if (!procfs_dir) { |
| printk(KERN_DEBUG "Could not create procfs directory %s\n", |
| current_pfs->dir_name); |
| return -1; |
| } |
| current_pfs->bypass_entry = procfs_dir; |
| |
| #define ENTRY(x) ret |= procfs_add(#x, &x##_ops, pbp_device_block) |
| ENTRY(bypass_info); |
| if (pbp_device_block->bp_caps & SW_CTL_CAP) { |
| /* Create set param proc's */ |
| ENTRY(bypass_slave); |
| ENTRY(bypass_caps); |
| ENTRY(wd_set_caps); |
| ENTRY(bypass_wd); |
| ENTRY(wd_expire_time); |
| ENTRY(reset_bypass_wd); |
| ENTRY(std_nic); |
| if (pbp_device_block->bp_caps & BP_CAP) { |
| ENTRY(bypass); |
| ENTRY(dis_bypass); |
| ENTRY(bypass_pwup); |
| ENTRY(bypass_pwoff); |
| ENTRY(bypass_change); |
| } |
| if (pbp_device_block->bp_caps & TAP_CAP) { |
| ENTRY(tap); |
| ENTRY(dis_tap); |
| ENTRY(tap_pwup); |
| ENTRY(tap_change); |
| } |
| if (pbp_device_block->bp_caps & DISC_CAP) { |
| ENTRY(disc); |
| ENTRY(dis_disc); |
| ENTRY(disc_pwup); |
| ENTRY(disc_change); |
| } |
| |
| ENTRY(wd_exp_mode); |
| ENTRY(wd_autoreset); |
| ENTRY(tpl); |
| #ifdef PMC_FIX_FLAG |
| ENTRY(wait_at_pwup); |
| ENTRY(hw_reset); |
| #endif |
| } |
| #undef ENTRY |
| if (ret < 0) |
| printk(KERN_DEBUG "Create proc entry failed\n"); |
| |
| return ret; |
| } |
| |
| int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block) |
| { |
| |
| struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set; |
| remove_proc_subtree(current_pfs->dir_name, bp_procfs_dir); |
| current_pfs->bypass_entry = NULL; |
| return 0; |
| } |