6657 lines
153 KiB
C
Executable file
6657 lines
153 KiB
C
Executable file
/**************************************************************************
|
|
|
|
Copyright (c) 2005-2015, Silicom
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright notice,
|
|
this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
3. Neither the name of the Silicom nor the names of its
|
|
contributors may be used to endorse or promote products derived from
|
|
this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
***************************************************************************/
|
|
#include <linux/version.h>
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
|
|
#include <linux/config.h>
|
|
#endif
|
|
#if defined(CONFIG_SMP) && ! defined(__SMP__)
|
|
#define __SMP__
|
|
#endif
|
|
|
|
|
|
|
|
#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>
|
|
#ifdef BP_SELF_TEST
|
|
#include <linux/etherdevice.h>
|
|
#endif
|
|
|
|
#include <asm/uaccess.h> /* for get_user and put_user */
|
|
#include <linux/sched.h>
|
|
#include <linux/ethtool.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/reboot.h>
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/sched.h>
|
|
|
|
|
|
#include "bprd_ioctl.h"
|
|
#include "bprd_mod.h"
|
|
#include "bypass.h"
|
|
#include "libbp_rd.h"
|
|
#include "bp_cmd.h"
|
|
|
|
|
|
#define SUCCESS 0
|
|
#define BP_MOD_VER VER_STR_SET
|
|
#define BP_MOD_DESCR "Silicom Bypass-RD Control driver"
|
|
|
|
static int Device_Open = 0;
|
|
static int major_num=0;
|
|
spinlock_t bypass_wr_lock;
|
|
|
|
MODULE_AUTHOR("Anna Lukin, annal@silicom.co.il");
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_DESCRIPTION(BP_MOD_DESCR);
|
|
MODULE_VERSION(BP_MOD_VER);
|
|
|
|
enum ies_port_state {
|
|
/* NOTE! Order is important. See the table in ies_port_set_state. */
|
|
|
|
/* The port is in working order (symbol lock, alignment done) and
|
|
* ready to receive a frame.
|
|
*/
|
|
IES_PORT_STATE_UP = 0,
|
|
|
|
/* Deprecated. Use ''IES_PORT_MODE_ADMIN_DOWN'' instead. */
|
|
IES_PORT_STATE_ADMIN_DOWN,
|
|
|
|
/* Deprecated. Use ''IES_PORT_MODE_ADMIN_PWRDOWN'' instead. */
|
|
IES_PORT_STATE_ADMIN_PWRDOWN,
|
|
|
|
/* Deprecated. Use ''IES_PORT_MODE_BIST'' instead. */
|
|
IES_PORT_STATE_BIST,
|
|
|
|
/* The SERDES transmits remote fault constantly and the receiver is
|
|
* disabled.
|
|
*/
|
|
IES_PORT_STATE_REMOTE_FAULT,
|
|
|
|
/* Indicates the absence of any signal on any lane. */
|
|
IES_PORT_STATE_DOWN,
|
|
|
|
/* Some lanes have either signal or partial synchronization. */
|
|
IES_PORT_STATE_PARTIALLY_UP,
|
|
|
|
/* Indicates continuous reception of a local fault condition. A remote
|
|
* fault is automatically sent continuously.
|
|
*/
|
|
IES_PORT_STATE_LOCAL_FAULT,
|
|
|
|
/* Indicates that DFE tuning is still in progress. */
|
|
IES_PORT_STATE_DFE_TUNING
|
|
};
|
|
|
|
enum ies_port_mode {
|
|
/* NOTE! Order is important. See the table in ies_port_set_state. */
|
|
|
|
/* The port is in working order (symbol lock, alignment done) and
|
|
* ready to receive a frame.
|
|
*/
|
|
IES_PORT_MODE_UP = IES_PORT_STATE_UP,
|
|
|
|
/* The port is administratively set down with the SERDES
|
|
* transmitting an idle pattern but the receiver disabled.
|
|
*/
|
|
IES_PORT_MODE_ADMIN_DOWN = IES_PORT_STATE_ADMIN_DOWN,
|
|
|
|
/* The port is administratively set down with the SERDES
|
|
* shut down and no signal transmitted.
|
|
*/
|
|
IES_PORT_MODE_ADMIN_PWRDOWN = IES_PORT_STATE_ADMIN_PWRDOWN,
|
|
|
|
/* The receiver is expecting a Built In Self Test sequence. The subMode
|
|
* argument to ies_port_set_state or ies_set_port_state_v2 is used to
|
|
* specify the test pattern.
|
|
*/
|
|
IES_PORT_MODE_BIST = IES_PORT_STATE_BIST,
|
|
|
|
/* The SERDES transmits remote fault constantly and the receiver is
|
|
* disabled.
|
|
*/
|
|
IES_PORT_MODE_REMOTE_FAULT = IES_PORT_STATE_REMOTE_FAULT,
|
|
|
|
/* Indicates continuous reception of a local fault condition. A remote
|
|
* fault is automatically sent continuously.
|
|
*/
|
|
IES_PORT_MODE_LOCAL_FAULT = IES_PORT_STATE_LOCAL_FAULT
|
|
};
|
|
|
|
#define IES10K_EPL_BASE (0x0E0000)
|
|
|
|
/* MAC and Reconciliation Sublayer configuration */
|
|
#define IES10K_MAC_CFG(index1, index0, word) \
|
|
(0x000400 * (index1) + 0x000080 * (index0) + \
|
|
(word) + 0x000010 + IES10K_EPL_BASE)
|
|
#define IES10K_MAC_CFG_WIDTH 7
|
|
#define IES10K_MAC_CFG_ENTRIES_0 4
|
|
#define IES10K_MAC_CFG_ENTRIES_1 9
|
|
|
|
#define IES10K_MAC_CFG_L_TXANTIBUBBLEWATERMARK 0
|
|
#define IES10K_MAC_CFG_H_TXANTIBUBBLEWATERMARK 5
|
|
#define IES10K_MAC_CFG_L_TXRATEFIFOWATERMARK 6
|
|
#define IES10K_MAC_CFG_H_TXRATEFIFOWATERMARK 9
|
|
#define IES10K_MAC_CFG_L_TXRATEFIFOFASTINC 10
|
|
#define IES10K_MAC_CFG_H_TXRATEFIFOFASTINC 17
|
|
#define IES10K_MAC_CFG_L_TXRATEFIFOSLOWINC 18
|
|
#define IES10K_MAC_CFG_H_TXRATEFIFOSLOWINC 25
|
|
#define IES10K_MAC_CFG_L_TXIDLEMINIFGBYTES 26
|
|
#define IES10K_MAC_CFG_H_TXIDLEMINIFGBYTES 31
|
|
#define IES10K_MAC_CFG_L_TXCLOCKCOMPENSATIONTIMEOUT 32
|
|
#define IES10K_MAC_CFG_H_TXCLOCKCOMPENSATIONTIMEOUT 47
|
|
#define IES10K_MAC_CFG_B_TXCLOCKCOMPENSATIONENABLE 48
|
|
#define IES10K_MAC_CFG_L_TXFAULTMODE 49
|
|
#define IES10K_MAC_CFG_H_TXFAULTMODE 51
|
|
#define IES10K_MAC_CFG_L_TXPCACTTIMESCALE 52
|
|
#define IES10K_MAC_CFG_H_TXPCACTTIMESCALE 55
|
|
#define IES10K_MAC_CFG_L_TXPCACTTIMEOUT 56
|
|
#define IES10K_MAC_CFG_H_TXPCACTTIMEOUT 63
|
|
#define IES10K_MAC_CFG_L_TXDRAINMODE 64
|
|
#define IES10K_MAC_CFG_H_TXDRAINMODE 65
|
|
#define IES10K_MAC_CFG_L_TXMINCOLUMNS 66
|
|
#define IES10K_MAC_CFG_H_TXMINCOLUMNS 71
|
|
#define IES10K_MAC_CFG_B_TXLPIDLEREQUEST 108
|
|
#define IES10K_MAC_CFG_B_TXLPIAUTOMATIC 109
|
|
#define IES10K_MAC_CFG_L_TXLPITIMEOUT 110
|
|
#define IES10K_MAC_CFG_H_TXLPITIMEOUT 117
|
|
#define IES10K_MAC_CFG_L_TXLPITIMESCALE 118
|
|
#define IES10K_MAC_CFG_H_TXLPITIMESCALE 119
|
|
#define IES10K_MAC_CFG_L_TXLPIHOLDTIMEOUT 120
|
|
#define IES10K_MAC_CFG_H_TXLPIHOLDTIMEOUT 127
|
|
#define IES10K_MAC_CFG_L_TXLPIHOLDTIMESCALE 128
|
|
#define IES10K_MAC_CFG_H_TXLPIHOLDTIMESCALE 129
|
|
#define IES10K_MAC_CFG_L_TXFCSMODE 130
|
|
#define IES10K_MAC_CFG_H_TXFCSMODE 132
|
|
#define IES10K_MAC_CFG_B_TXIDLEENABLEDIC 134
|
|
#define IES10K_MAC_CFG_L_RXMINFRAMELENGTH 136
|
|
#define IES10K_MAC_CFG_H_RXMINFRAMELENGTH 143
|
|
#define IES10K_MAC_CFG_L_RXMAXFRAMELENGTH 144
|
|
#define IES10K_MAC_CFG_H_RXMAXFRAMELENGTH 159
|
|
#define IES10K_MAC_CFG_B_IEEE1588ENABLE 168
|
|
#define IES10K_MAC_CFG_B_PREAMBLEMODE 170
|
|
#define IES10K_MAC_CFG_B_RXDRAIN 173
|
|
#define IES10K_MAC_CFG_B_RXIGNOREIFGERRORS 180
|
|
|
|
|
|
#define DBI410_IF_SERIES(pid) \
|
|
((pid==0x01B0)|| \
|
|
(pid==0x01B1)|| \
|
|
(pid==0x01B2)|| \
|
|
(pid==0x01B3)|| \
|
|
(pid==0x01B4))
|
|
|
|
#define DBI410T_IF_SERIES(pid) \
|
|
(pid==0x01B0)
|
|
|
|
#define DBI240_IF_SERIES(pid) \
|
|
((pid==0x01B8)|| \
|
|
(pid==0x01B9)|| \
|
|
(pid==0x01BC)|| \
|
|
(pid==0x01BA))
|
|
|
|
|
|
#define DBI100H_IF_SERIES(pid) \
|
|
((pid==0x01C0)|| \
|
|
(pid==0x01C2))
|
|
|
|
#define DBI100L_IF_SERIES(pid) \
|
|
(pid==0x01C1)
|
|
|
|
#define DBI25_IF_SERIES(pid) \
|
|
(pid==0x01C8)
|
|
|
|
#define DBI410_IF_SERIES(pid) \
|
|
((pid==0x01B0)|| \
|
|
(pid==0x01B1)|| \
|
|
(pid==0x01B2)|| \
|
|
(pid==0x01B3)|| \
|
|
(pid==0x01B4))
|
|
|
|
#define BPCTL_WRITE_REG(a, reg, value) \
|
|
(writel((value), (void *)(((a)->mem_map) + reg*4)))
|
|
|
|
#define BPCTL_READ_REG(a, reg) ( \
|
|
readl((void *)((a)->mem_map) + reg*4))
|
|
|
|
inline static u32 ies_bitfield_get32_multi32(const u32 *array, int hi_bit, int lo_bit)
|
|
{
|
|
u32 result = 0;
|
|
int result_pos = 0;
|
|
int word = lo_bit / 32;
|
|
int rel_lo_bit = lo_bit % 32;
|
|
int rel_hi_bit = rel_lo_bit + (hi_bit - lo_bit);
|
|
u32 mask = (2 << (hi_bit - lo_bit)) - 1;
|
|
|
|
do {
|
|
result |= (array[word++] >> rel_lo_bit) << result_pos;
|
|
result_pos += (32 - rel_lo_bit);
|
|
rel_hi_bit -= 32;
|
|
rel_lo_bit = 0;
|
|
} while (rel_hi_bit >= 0);
|
|
|
|
return result & mask;
|
|
}
|
|
|
|
|
|
inline static void ies_bitfield_set32_multi32(u32 *array, int hi_bit, int lo_bit,
|
|
u32 value)
|
|
{
|
|
int value_pos = 0;
|
|
int word = lo_bit / 32;
|
|
int rel_lo_bit = lo_bit % 32;
|
|
int rel_hi_bit = rel_lo_bit + (hi_bit - lo_bit);
|
|
|
|
do {
|
|
u32 mask;
|
|
|
|
mask = (rel_hi_bit < 31 ? (2 << rel_hi_bit) : 0) - 1;
|
|
mask >>= rel_lo_bit;
|
|
mask <<= rel_lo_bit;
|
|
array[word] = ((array[word] & ~mask) |
|
|
(((value >> value_pos) << rel_lo_bit) & mask));
|
|
value_pos += (32 - rel_lo_bit);
|
|
rel_hi_bit -= 32;
|
|
rel_lo_bit = 0;
|
|
++word;
|
|
} while (rel_hi_bit >= 0);
|
|
}
|
|
|
|
|
|
/* Get a named field of 2-32 bits within an array of 32-bit values. */
|
|
#define IES_ARRAY_GET_FIELD(array, regname, fieldname) \
|
|
ies_bitfield_get32_multi32(array, regname ## _H_ ## fieldname, \
|
|
regname ## _L_ ## fieldname)
|
|
|
|
/* Set a named field of 2-32 bits within an array of 32-bit values. */
|
|
#define IES_ARRAY_SET_FIELD(array, regname, fieldname, fieldvalue) \
|
|
ies_bitfield_set32_multi32(array, regname ## _H_ ## fieldname, \
|
|
regname ## _L_ ## fieldname, fieldvalue)
|
|
|
|
inline static int convert_adminmode_txlinkfault(int mode)
|
|
{
|
|
int link_fault;
|
|
|
|
/* Program the output pattern based on the TxFaultMode */
|
|
switch (mode) {
|
|
case IES_PORT_MODE_ADMIN_DOWN:
|
|
link_fault = 1;
|
|
break;
|
|
|
|
case IES_PORT_MODE_LOCAL_FAULT:
|
|
link_fault = 2;
|
|
break;
|
|
|
|
case IES_PORT_MODE_REMOTE_FAULT:
|
|
link_fault = 3;
|
|
break;
|
|
|
|
default:
|
|
link_fault = 0;
|
|
break;
|
|
}
|
|
|
|
return link_fault;
|
|
}
|
|
|
|
|
|
#define lock_bpctl() \
|
|
if (down_interruptible(&bpctl_sema)) { \
|
|
return -ERESTARTSYS; \
|
|
} \
|
|
|
|
#define unlock_bpctl() \
|
|
up(&bpctl_sema);
|
|
|
|
static int bp_shutdown = 0;
|
|
/* Media Types */
|
|
typedef enum {
|
|
bp_copper = 0,
|
|
bp_fiber,
|
|
bp_cx4,
|
|
bp_none,
|
|
} bp_media_type;
|
|
|
|
struct pfs_unit_rd {
|
|
struct proc_dir_entry *proc_entry;
|
|
char proc_name[32];
|
|
} ;
|
|
|
|
typedef struct _bpctl_dev_mng {
|
|
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;
|
|
uint8_t bus_p;
|
|
uint8_t slot_p;
|
|
uint8_t func_p;
|
|
u_int32_t device;
|
|
u_int32_t vendor;
|
|
u_int32_t subvendor;
|
|
u_int32_t subdevice;
|
|
int ifindex;
|
|
spinlock_t bypass_wr_lock;
|
|
int port_num;
|
|
int sw_num;
|
|
struct mutex i2c_bus_lock;
|
|
int mutex_owner_module;
|
|
|
|
/* #endif */
|
|
|
|
} bpctl_dev_mng_t;
|
|
|
|
#ifdef BP_PROC_SUPPORT
|
|
struct pfs_unit_rd {
|
|
struct proc_dir_entry *proc_entry;
|
|
char proc_name[32];
|
|
} ;
|
|
|
|
struct bypass_pfs_rd {
|
|
char dir_name[32];
|
|
struct proc_dir_entry *bypass_entry;
|
|
struct pfs_unit_rd bypass_info;
|
|
struct pfs_unit_rd bypass_slave;
|
|
struct pfs_unit_rd bypass_caps;
|
|
struct pfs_unit_rd wd_set_caps;
|
|
struct pfs_unit_rd bypass;
|
|
struct pfs_unit_rd bypass_change;
|
|
struct pfs_unit_rd bypass_wd;
|
|
struct pfs_unit_rd wd_expire_time;
|
|
struct pfs_unit_rd reset_bypass_wd;
|
|
struct pfs_unit_rd dis_bypass;
|
|
struct pfs_unit_rd bypass_pwup;
|
|
struct pfs_unit_rd bypass_pwoff;
|
|
struct pfs_unit_rd std_nic;
|
|
struct pfs_unit_rd tap;
|
|
struct pfs_unit_rd dis_tap;
|
|
struct pfs_unit_rd tap_pwup;
|
|
struct pfs_unit_rd tap_change;
|
|
struct pfs_unit_rd wd_exp_mode;
|
|
struct pfs_unit_rd wd_autoreset;
|
|
struct pfs_unit_rd tpl;
|
|
|
|
};
|
|
#endif
|
|
|
|
|
|
typedef struct _bpctl_dev {
|
|
char *name;
|
|
char *desc;
|
|
struct pci_dev *pdev; /* PCI device */
|
|
struct net_device *ndev; /* net device */
|
|
bpctl_dev_mng_t *pbpctl_dev_c;
|
|
struct pci_dev *pdev_mng;
|
|
struct pci_dev *pdev_pf_master;
|
|
struct pci_dev *pdev_pf_slave;
|
|
unsigned long mem_map;
|
|
uint8_t bus;
|
|
uint8_t slot;
|
|
uint8_t func;
|
|
uint8_t bus_p;
|
|
uint8_t slot_p;
|
|
uint8_t func_p;
|
|
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_master_flag;
|
|
int bp_tpl_flag;
|
|
struct timer_list bp_tpl_timer;
|
|
int tpl_wait;
|
|
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31))
|
|
const struct net_device_ops *old_ops;
|
|
struct net_device_ops new_ops;
|
|
#endif
|
|
int bp_self_test_flag;
|
|
char *bp_tx_data;
|
|
uint8_t rb_oem;
|
|
uint8_t oem_data[20];
|
|
uint32_t ledctl_default;
|
|
uint32_t ledctl_mode1;
|
|
uint32_t ledctl_mode2;
|
|
uint32_t led_status;
|
|
//#endif
|
|
struct timer_list blink_timer;
|
|
struct timer_list wait_timer;
|
|
#ifdef BP_PROC_SUPPORT
|
|
struct bypass_pfs_rd bypass_pfs_set;
|
|
char proc_dir[128];
|
|
#endif
|
|
int port_num;
|
|
int epl_num;
|
|
int epl;
|
|
int lane_num;
|
|
int sw_num;
|
|
/* #endif */
|
|
|
|
} bpctl_dev_t;
|
|
|
|
inline static int iespl_read_mult_u32(bpctl_dev_mng_t *interface, u32 addr, int n, u32 *val)
|
|
{
|
|
u32 value;
|
|
int i;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
value = BPCTL_READ_REG(interface, (addr + i));
|
|
val[i] = value;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
inline static int iespl_write_mult_u32(bpctl_dev_mng_t *interface, u32 addr, int n, u32 *val)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
BPCTL_WRITE_REG(interface, (addr + i), val[i]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static bpctl_dev_t *bpctl_dev_arr;
|
|
static bpctl_dev_mng_t *bpctl_dev_mng_arr;
|
|
|
|
static int device_num=0;
|
|
static int mng_device_num=0;
|
|
|
|
static struct semaphore bpctl_sema;
|
|
|
|
|
|
|
|
static int usec_delay_bp1(unsigned long x);
|
|
static void usec_delay_bp(unsigned long x);
|
|
static void msec_delay_bp(unsigned long x);
|
|
|
|
static int get_dev_idx_bsf(int bus, int slot, int func);
|
|
|
|
static int get_dev_mng_idx_bsf(int bus, int slot, int func);
|
|
|
|
static int get_dev_idx(int ifindex);
|
|
static void if_scan_init(void);
|
|
|
|
static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev);
|
|
static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev);
|
|
|
|
|
|
#ifdef BP_PROC_SUPPORT
|
|
int bypass_proc_create_dev_rd(bpctl_dev_t * pbp_device_block);
|
|
int bypass_proc_remove_dev_rd(bpctl_dev_t * pbp_device_block);
|
|
|
|
int bp_proc_create(void);
|
|
#endif
|
|
|
|
int get_tx_rd_fn(bpctl_dev_t *pbpctl_dev);
|
|
int set_tx_rd_fn(bpctl_dev_t *pbpctl_dev, int tx_state);
|
|
|
|
int is_bypass_rd_fn(bpctl_dev_t *pbpctl_dev);
|
|
int get_bypass_caps_rd_fn(bpctl_dev_t *pbpctl_dev);
|
|
int get_wd_expire_rd_fn (bpctl_dev_t *pbpctl_dev);
|
|
|
|
int wdt_on(bpctl_dev_t *pbpctl_dev, unsigned int timeout);
|
|
|
|
static int TAKE_PLAT_I2C_BUS_LOCK_IDX(struct file * file, int dev_idx){
|
|
int rc;
|
|
rc = mutex_lock_interruptible(&bpctl_dev_mng_arr[dev_idx].i2c_bus_lock);
|
|
bpctl_dev_mng_arr[dev_idx].mutex_owner_module = 0;
|
|
file->private_data = &bpctl_dev_mng_arr[dev_idx].i2c_bus_lock;
|
|
return(rc) ? -ERESTARTSYS: 0;
|
|
}
|
|
|
|
static void DROP_PLAT_I2C_BUS_LOCK_IDX(struct file * file, int dev_idx){
|
|
mutex_unlock(&bpctl_dev_mng_arr[dev_idx].i2c_bus_lock);
|
|
file->private_data = NULL;
|
|
}
|
|
|
|
static void TAKE_PLAT_I2C_BUS_LOCK(bpctl_dev_mng_t *pbpctl_dev_c) {
|
|
int rc= mutex_lock_interruptible( &pbpctl_dev_c->i2c_bus_lock);
|
|
pbpctl_dev_c->mutex_owner_module = (rc) ? 1 :0;
|
|
}
|
|
|
|
static void DROP_PLAT_I2C_BUS_LOCK(bpctl_dev_mng_t *pbpctl_dev_c){
|
|
pbpctl_dev_c->mutex_owner_module = 0;
|
|
mutex_unlock( &pbpctl_dev_c->i2c_bus_lock);
|
|
}
|
|
|
|
|
|
int usec_delay_bp1(unsigned long x) {
|
|
struct timeval tv, tv_end;
|
|
do_gettimeofday(&tv);
|
|
udelay(x);
|
|
do_gettimeofday(&tv_end);
|
|
if (tv_end.tv_usec>tv.tv_usec) {
|
|
if ((tv_end.tv_usec-tv.tv_usec)<(x))
|
|
return 0;
|
|
}
|
|
else if ((~tv.tv_usec+tv_end.tv_usec)<(x))
|
|
return 0;
|
|
return 1;
|
|
|
|
}
|
|
void usec_delay_bp(unsigned long x) {
|
|
#if 1
|
|
int i=2;
|
|
while (i--) {
|
|
if (usec_delay_bp1(x))
|
|
return;
|
|
}
|
|
#else
|
|
udelay(x);
|
|
#endif
|
|
}
|
|
|
|
|
|
void msec_delay_bp(unsigned long x){
|
|
#ifdef BP_NDELAY_MODE
|
|
return;
|
|
#else
|
|
int i;
|
|
if (in_interrupt()) {
|
|
for (i = 0; i < 1000; i++) {
|
|
usec_delay_bp(x) ;
|
|
}
|
|
}
|
|
else {
|
|
msleep(x);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#define FM_SET_FIELD(lvalue, regname, fieldname, fieldvalue) \
|
|
(lvalue ^= ( ( (lvalue >> regname ## _l_ ## fieldname) ^ fieldvalue ) & \
|
|
( ( 2 << (regname ## _h_ ## fieldname - regname ## _l_ ## fieldname) ) - 1 ) ) \
|
|
<< regname ## _l_ ## fieldname)
|
|
|
|
#define FM_GET_FIELD(rvalue, regname, fieldname) \
|
|
( (rvalue >> regname ## _l_ ## fieldname) & \
|
|
( ( 2 << (regname ## _h_ ## fieldname - regname ## _l_ ## fieldname) ) - 1 ) )
|
|
|
|
#define FM_GET_BIT(rvalue, regname, bitname) \
|
|
( (rvalue >> regname ## _b_ ## bitname) & 1 )
|
|
|
|
#define FM_SET_BIT(lvalue, regname, bitname, bitvalue) \
|
|
( lvalue = ( lvalue & ~(1 << regname ## _b_ ## bitname) ) | \
|
|
( (bitvalue & 1) << regname ## _b_ ## bitname ) )
|
|
|
|
|
|
#define FM10000_I2C_DATA(index) ((0x000001) * ((index) - 0) + (0x000C1C))
|
|
#define FM10000_I2C_CTRL 0x000C20
|
|
#define FM10000_GPIO_CFG 0x000C15
|
|
#define FM10000_GPIO_DATA 0x000C16
|
|
|
|
#define FM10000_I2C_CTRL_l_Addr 0
|
|
#define FM10000_I2C_CTRL_h_Addr 7
|
|
#define FM10000_I2C_CTRL_l_Command 8
|
|
#define FM10000_I2C_CTRL_h_Command 9
|
|
#define FM10000_I2C_CTRL_l_LengthW 10
|
|
#define FM10000_I2C_CTRL_h_LengthW 13
|
|
#define FM10000_I2C_CTRL_l_LengthR 14
|
|
#define FM10000_I2C_CTRL_h_LengthR 17
|
|
#define FM10000_I2C_CTRL_l_LengthSent 18
|
|
#define FM10000_I2C_CTRL_h_LengthSent 21
|
|
#define FM10000_I2C_CTRL_l_CommandCompleted 22
|
|
#define FM10000_I2C_CTRL_h_CommandCompleted 25
|
|
#define FM10000_I2C_CTRL_b_InterruptPending 26
|
|
|
|
|
|
|
|
|
|
static int I2cWriteRead(bpctl_dev_mng_t *pbpctl_dev_c,
|
|
unsigned int device,
|
|
unsigned char *data,
|
|
unsigned int wl,
|
|
unsigned int rl)
|
|
{
|
|
uint32_t regValue;
|
|
unsigned int i;
|
|
unsigned int j;
|
|
|
|
uint i2c_try = 40;
|
|
uint32_t tmp;
|
|
|
|
|
|
/*printk("I2cWriteRead device=0x%x wl=%d rl=%d\n",
|
|
device, wl, rl);*/
|
|
|
|
if (rl > 12)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if (wl > 12)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if (data == NULL)
|
|
{
|
|
return -1;
|
|
}
|
|
if (!pbpctl_dev_c)
|
|
return -1;
|
|
|
|
for (i = 0 ; i < (wl+3)/4 ; i++)
|
|
{
|
|
regValue = 0;
|
|
for (j = 0 ; j < 4 ; j++)
|
|
{
|
|
if ((i*4 + j) < wl)
|
|
{
|
|
regValue |= (data[i*4 + j] << ((3 - j)*8));
|
|
}
|
|
}
|
|
BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_I2C_DATA(i), regValue);
|
|
|
|
/*printk("WRITEDATA#%d : 0x%08x\n",i, regValue); */
|
|
}
|
|
|
|
regValue = 0;
|
|
FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Addr, (device << 1));
|
|
FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 0);
|
|
FM_SET_FIELD(regValue, FM10000_I2C_CTRL, LengthW, wl);
|
|
FM_SET_FIELD(regValue, FM10000_I2C_CTRL, LengthR, rl);
|
|
|
|
/* printk("WRITE: eg 0x%08x Cmd %d wl %d rl %d "
|
|
"Comp %x LenSent %d intr %d\n",
|
|
regValue,
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, Command),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthW),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthR),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthSent),
|
|
FM_GET_BIT(regValue, FM10000_I2C_CTRL, InterruptPending));*/
|
|
|
|
BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_I2C_CTRL, regValue);
|
|
|
|
tmp = BPCTL_READ_REG(pbpctl_dev_c, FM10000_I2C_CTRL);
|
|
|
|
/*printk("READ: reg 0x%08x Cmd %d wl %d rl %d "
|
|
"Comp %x LenSent %d intr %d\n", tmp,
|
|
FM_GET_FIELD(tmp, FM10000_I2C_CTRL, Command),
|
|
FM_GET_FIELD(tmp, FM10000_I2C_CTRL, LengthW),
|
|
FM_GET_FIELD(tmp, FM10000_I2C_CTRL, LengthR),
|
|
FM_GET_FIELD(tmp, FM10000_I2C_CTRL, CommandCompleted),
|
|
FM_GET_FIELD(tmp, FM10000_I2C_CTRL, LengthSent),
|
|
FM_GET_BIT(tmp, FM10000_I2C_CTRL, InterruptPending));*/
|
|
|
|
/* Now change command to start the transaction */
|
|
if (rl == 0)
|
|
{
|
|
/* Write only allow write of 0 length */
|
|
FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 1);
|
|
}
|
|
else if ((wl > 0) && (rl > 0))
|
|
{
|
|
/* Write Read */
|
|
FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 2);
|
|
}
|
|
else
|
|
{
|
|
/* Read */
|
|
FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 3);
|
|
}
|
|
|
|
/*printk("WRITE2: reg 0x%08x Cmd %d wl %d rl %d "
|
|
"Comp %x LenSent %d intr %d\n", regValue,
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, Command),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthW),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthR),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthSent),
|
|
FM_GET_BIT(regValue, FM10000_I2C_CTRL, InterruptPending));*/
|
|
|
|
BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_I2C_CTRL, regValue);
|
|
|
|
regValue = BPCTL_READ_REG(pbpctl_dev_c, FM10000_I2C_CTRL);
|
|
|
|
/*printk("READ2: reg 0x%08x Cmd %d wl %d rl %d "
|
|
"Comp %x LenSent %d intr %d\n", regValue,
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, Command),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthW),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthR),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted),
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthSent),
|
|
FM_GET_BIT(regValue, FM10000_I2C_CTRL, InterruptPending));*/
|
|
|
|
/* Poll to check for command done */
|
|
do
|
|
{
|
|
msec_delay_bp(1);
|
|
|
|
regValue = BPCTL_READ_REG(pbpctl_dev_c, FM10000_I2C_CTRL);
|
|
|
|
} while ((FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted) == 0)&&(i2c_try--));
|
|
|
|
if (FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted) != 1)
|
|
{
|
|
/*printk("Dev=0x%02x: I2C Command completed with error 0x%x. "
|
|
"I2C_CTRL(0x%x)=0x%x\n",
|
|
device,
|
|
FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted),
|
|
FM10000_I2C_CTRL,
|
|
regValue);*/
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0 ; i < (rl+3)/4 ; i++)
|
|
{
|
|
regValue = BPCTL_READ_REG(pbpctl_dev_c, FM10000_I2C_DATA(i));
|
|
|
|
|
|
for (j = 0 ; j < 4 ; j++)
|
|
{
|
|
if ((i*4 + j) < rl)
|
|
{
|
|
data[i*4 + j] = (regValue >> ((3 - j)*8)) & 0xFF;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
} /* end I2cWriteRead */
|
|
|
|
|
|
static int WriteBypass(bpctl_dev_mng_t *pbpctl_dev_c,
|
|
unsigned int device,
|
|
unsigned char *data,
|
|
unsigned int wl,
|
|
unsigned int rl)
|
|
{
|
|
int status;
|
|
|
|
if (!pbpctl_dev_c)
|
|
return -1;
|
|
#if 0
|
|
{
|
|
int num, i;
|
|
num = rl?rl:wl;
|
|
printk("data ");
|
|
for (i = 0; i < num; i++){
|
|
printk("%x ", data[i]);
|
|
}
|
|
printk("\n");
|
|
}
|
|
#endif
|
|
|
|
status = I2cWriteRead(pbpctl_dev_c, device, data, wl, rl);
|
|
|
|
|
|
return status;
|
|
|
|
} /* end WriteSfppPhy */
|
|
|
|
int fmPlatformFm10000BypassWriteRead(bpctl_dev_mng_t *pbpctl_dev_c,
|
|
unsigned int device,
|
|
unsigned char *data,
|
|
unsigned int wl,
|
|
unsigned int rl)
|
|
|
|
{
|
|
int status = 0;
|
|
unsigned char mux_pin = 2;
|
|
|
|
if (!pbpctl_dev_c)
|
|
return -1;
|
|
|
|
|
|
TAKE_PLAT_I2C_BUS_LOCK(pbpctl_dev_c);
|
|
|
|
if (!DBI410T_IF_SERIES(pbpctl_dev_c->subdevice)) {
|
|
if (DBI410_IF_SERIES(pbpctl_dev_c->subdevice))
|
|
status = I2cWriteRead(pbpctl_dev_c, 0x75, &mux_pin, 1, 0);
|
|
else
|
|
status = I2cWriteRead(pbpctl_dev_c, 0x70, &mux_pin, 1, 0);
|
|
}
|
|
if (status == 0)
|
|
status = WriteBypass(pbpctl_dev_c, device, data, wl, rl);
|
|
|
|
DROP_PLAT_I2C_BUS_LOCK(pbpctl_dev_c);
|
|
return status;
|
|
|
|
} /* end fmPlatformPhyEnable1000BaseTAutoNeg */
|
|
|
|
|
|
/*static bpctl_dev_t *bpctl_dev_a;
|
|
static bpctl_dev_t *bpctl_dev_b;*/
|
|
|
|
|
|
|
|
static int bp_get_dev_idx_bsf(struct net_device *dev, int *index)
|
|
{
|
|
struct ethtool_drvinfo drvinfo = {0};
|
|
char *buf;
|
|
int bus, slot, func;
|
|
|
|
if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo)
|
|
dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
|
|
else
|
|
return -EOPNOTSUPP;
|
|
|
|
if (!drvinfo.bus_info)
|
|
return -ENODATA;
|
|
if (!strcmp(drvinfo.bus_info, "N/A"))
|
|
return -ENODATA;
|
|
|
|
buf = strchr(drvinfo.bus_info, ':');
|
|
if (!buf)
|
|
return -EINVAL;
|
|
buf++;
|
|
if (sscanf(buf, "%x:%x.%x", &bus, &slot, &func) != 3)
|
|
return -EINVAL;
|
|
|
|
*index = get_dev_idx_bsf(bus, slot, func);
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int bp_get_dev_mng_idx_bsf(struct net_device *dev, int *index)
|
|
{
|
|
struct ethtool_drvinfo drvinfo = {0};
|
|
char *buf;
|
|
int bus, slot, func;
|
|
|
|
if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo)
|
|
dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
|
|
else
|
|
return -EOPNOTSUPP;
|
|
|
|
if (!drvinfo.bus_info)
|
|
return -ENODATA;
|
|
if (!strcmp(drvinfo.bus_info, "N/A"))
|
|
return -ENODATA;
|
|
|
|
buf = strchr(drvinfo.bus_info, ':');
|
|
if (!buf)
|
|
return -EINVAL;
|
|
buf++;
|
|
if (sscanf(buf, "%x:%x.%x", &bus, &slot, &func) != 3)
|
|
return -EINVAL;
|
|
|
|
*index = get_dev_mng_idx_bsf(bus, slot, func);
|
|
return 0;
|
|
}
|
|
|
|
|
|
static bpctl_dev_mng_t *get_mng_port_rd_fn(bpctl_dev_t *pbpctl_dev) {
|
|
int idx_dev=0;
|
|
|
|
if (pbpctl_dev==NULL)
|
|
return NULL;
|
|
|
|
for (idx_dev = 0; ((bpctl_dev_mng_arr[idx_dev].pdev != NULL)&&(idx_dev < mng_device_num)); idx_dev++) {
|
|
if (DBI410_IF_SERIES(pbpctl_dev->subdevice)) {
|
|
if ((bpctl_dev_mng_arr[idx_dev].bus == pbpctl_dev->bus) &&
|
|
(bpctl_dev_mng_arr[idx_dev].slot == pbpctl_dev->slot) &&
|
|
(bpctl_dev_mng_arr[idx_dev].func == 0)) {
|
|
|
|
return(&(bpctl_dev_mng_arr[idx_dev]));
|
|
}
|
|
}
|
|
else {
|
|
if (bpctl_dev_mng_arr[idx_dev].pdev == pbpctl_dev->pdev_mng)
|
|
return(&(bpctl_dev_mng_arr[idx_dev]));
|
|
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* This routine tries to find the Master/Slave NICs base on the following
|
|
* hardware configuration.
|
|
*
|
|
* GrandParent--+--Uncle1
|
|
* +--Parent/Uncle--+--Me?(Slave)
|
|
* |
|
|
* +--Parent/Uncle--+-Me?(Master)
|
|
* +--Uncle3
|
|
* Input:
|
|
* me - pci_dev pointer to the Broadcom device
|
|
* Output:
|
|
* pdev_master - pci_dev pointer to Master(NIC Controler1)
|
|
* pdev_slave - pci_dev pointer to Slave(NIC Controler2)
|
|
*/
|
|
static void
|
|
rdi_find_master_slave_plx(struct pci_dev *me,
|
|
struct pci_dev **pdev_master,
|
|
struct pci_dev **pdev_slave)
|
|
{
|
|
struct pci_bus *grand_parent, *uncle, *parent;
|
|
struct list_head *tmp, *tmp2;
|
|
struct pci_dev *pdev;
|
|
|
|
*pdev_master = NULL;
|
|
*pdev_slave = NULL;
|
|
|
|
if ((parent = me->bus) == NULL) {
|
|
pr_err("rdi cannot find its parent\n");
|
|
return;
|
|
}
|
|
|
|
|
|
if ((grand_parent = parent->parent) == NULL) {
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
list_for_each(tmp, &grand_parent->children) {
|
|
uncle = list_entry(tmp, struct pci_bus, node);
|
|
if (uncle == parent)
|
|
continue;
|
|
if (uncle) {
|
|
list_for_each(tmp2, &uncle->devices) {
|
|
pdev = list_entry(tmp2, struct pci_dev, bus_list);
|
|
if (pdev == NULL || pdev->bus == NULL) {
|
|
pr_err("%s:%d: t not found\n", __FUNCTION__, __LINE__);
|
|
continue;
|
|
}
|
|
|
|
if (pdev->bus->number > me->bus->number) {
|
|
*pdev_master = pdev;
|
|
*pdev_slave = me;
|
|
}
|
|
else {
|
|
*pdev_master = me;
|
|
*pdev_slave = pdev;
|
|
}
|
|
return;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#if 1
|
|
static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev) {
|
|
int idx_dev=0;
|
|
|
|
|
|
if ( pbpctl_dev == NULL ) {
|
|
return NULL;
|
|
}
|
|
|
|
|
|
if ((pbpctl_dev->epl_num == 2) ||
|
|
(pbpctl_dev->epl_num == 4)) {
|
|
return pbpctl_dev;
|
|
}
|
|
for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev != NULL)&&(idx_dev < device_num)); idx_dev++) {
|
|
if (DBI410_IF_SERIES(pbpctl_dev->subdevice)) {
|
|
if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)&&
|
|
(bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)&&
|
|
((bpctl_dev_arr[idx_dev].epl_num == 2)&&(pbpctl_dev->epl_num == 1))) {
|
|
|
|
return(&(bpctl_dev_arr[idx_dev]));
|
|
}
|
|
|
|
if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)&&
|
|
(bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)&&
|
|
((bpctl_dev_arr[idx_dev].epl_num == 4)&&(pbpctl_dev->epl_num == 3))) {
|
|
|
|
return(&(bpctl_dev_arr[idx_dev]));
|
|
}
|
|
}
|
|
else {
|
|
if ((bpctl_dev_arr[idx_dev].pdev == pbpctl_dev->pdev_pf_slave)&&
|
|
((bpctl_dev_arr[idx_dev].epl_num == 2)&&(pbpctl_dev->epl_num == 1))) {
|
|
|
|
return(&(bpctl_dev_arr[idx_dev]));
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev) {
|
|
int idx_dev=0;
|
|
|
|
|
|
if (pbpctl_dev==NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
|
|
if ((pbpctl_dev->epl_num == 1) ||
|
|
(pbpctl_dev->epl_num == 3)) {
|
|
return pbpctl_dev;
|
|
}
|
|
for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev != NULL)&&(idx_dev < device_num)); idx_dev++) {
|
|
if (DBI410_IF_SERIES(pbpctl_dev->subdevice)) {
|
|
if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)&&
|
|
(bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)&&
|
|
((bpctl_dev_arr[idx_dev].epl_num == 1)&&(pbpctl_dev->epl_num == 2))) {
|
|
|
|
return(&(bpctl_dev_arr[idx_dev]));
|
|
}
|
|
|
|
if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)&&
|
|
(bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)&&
|
|
((bpctl_dev_arr[idx_dev].epl_num == 3)&&(pbpctl_dev->epl_num == 4))) {
|
|
|
|
return(&(bpctl_dev_arr[idx_dev]));
|
|
}
|
|
}
|
|
else {
|
|
if ((bpctl_dev_arr[idx_dev].pdev == pbpctl_dev->pdev_pf_master)&&
|
|
((bpctl_dev_arr[idx_dev].epl_num == 1)&&(pbpctl_dev->epl_num == 2))) {
|
|
|
|
return(&(bpctl_dev_arr[idx_dev]));
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static int
|
|
bp_reboot_event(struct notifier_block *nb,
|
|
unsigned long event,
|
|
void *ptr)
|
|
{
|
|
bp_shutdown = 1;
|
|
return NOTIFY_DONE;
|
|
}
|
|
static int bp_device_event(struct notifier_block *unused,
|
|
unsigned long event, void *ptr)
|
|
{
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0))
|
|
struct net_device *dev = ptr;
|
|
#else
|
|
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
|
#endif
|
|
static bpctl_dev_t *pbpctl_dev, *pbpctl_dev_m, *pbpctl_dev2;
|
|
int dev_num = 0;
|
|
#if 0
|
|
static bpctl_dev_t *pbpctl_dev_m;
|
|
int ret = 0;
|
|
#endif
|
|
/*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) {
|
|
int idx_dev;
|
|
|
|
if (bp_get_dev_idx_bsf(dev, &idx_dev))
|
|
return NOTIFY_DONE;
|
|
|
|
if (idx_dev == -1)
|
|
return NOTIFY_DONE;
|
|
|
|
bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
|
|
bpctl_dev_arr[idx_dev].ndev = dev;
|
|
|
|
|
|
if ((!bp_get_dev_mng_idx_bsf(dev, &idx_dev)) &&
|
|
(idx_dev != -1)) {
|
|
bpctl_dev_mng_arr[idx_dev].ifindex = dev->ifindex;
|
|
bpctl_dev_mng_arr[idx_dev].ndev = dev;
|
|
}
|
|
|
|
#ifdef BP_PROC_SUPPORT
|
|
bypass_proc_remove_dev_rd(&bpctl_dev_arr[idx_dev]);
|
|
bypass_proc_create_dev_rd(&bpctl_dev_arr[idx_dev]);
|
|
#endif
|
|
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) {
|
|
#ifdef BP_PROC_SUPPORT
|
|
bypass_proc_remove_dev_rd(&bpctl_dev_arr
|
|
[idx_dev]);
|
|
#endif
|
|
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) {
|
|
#ifdef BP_PROC_SUPPORT
|
|
bypass_proc_remove_dev_rd(&bpctl_dev_arr
|
|
[idx_dev]);
|
|
bypass_proc_create_dev_rd(&bpctl_dev_arr
|
|
[idx_dev]);
|
|
#endif
|
|
|
|
return NOTIFY_DONE;
|
|
|
|
}
|
|
|
|
}
|
|
return NOTIFY_DONE;
|
|
|
|
}
|
|
|
|
switch (event) {
|
|
|
|
case NETDEV_CHANGE:{
|
|
|
|
if (((dev_num = get_dev_idx(dev->ifindex)) == -1) ||
|
|
(!(pbpctl_dev = &bpctl_dev_arr[dev_num])))
|
|
return NOTIFY_DONE;
|
|
|
|
if (bp_shutdown == 1)
|
|
return NOTIFY_DONE;
|
|
if ((is_bypass_rd_fn(pbpctl_dev)) == 1){
|
|
pbpctl_dev_m = pbpctl_dev;
|
|
pbpctl_dev2 = get_status_port_fn(pbpctl_dev);
|
|
}
|
|
else {
|
|
pbpctl_dev2 = pbpctl_dev_m = get_master_port_fn(pbpctl_dev);
|
|
}
|
|
|
|
|
|
if ((!pbpctl_dev_m)||(!pbpctl_dev2))
|
|
return NOTIFY_DONE;
|
|
|
|
|
|
if (netif_carrier_ok(dev)) {
|
|
if (pbpctl_dev_m->bp_tpl_flag){
|
|
if (get_tx_rd_fn(pbpctl_dev)) {
|
|
pbpctl_dev->tpl_wait = 0;
|
|
if (!get_tx_rd_fn(pbpctl_dev2)) {
|
|
pbpctl_dev2->tpl_wait = 1;
|
|
set_tx_rd_fn(pbpctl_dev2, 1);
|
|
}
|
|
}
|
|
}
|
|
return NOTIFY_DONE;
|
|
}
|
|
if (pbpctl_dev_m->bp_tpl_flag){
|
|
if (get_tx_rd_fn(pbpctl_dev)) {
|
|
if (get_tx_rd_fn(pbpctl_dev2)) {
|
|
set_tx_rd_fn(pbpctl_dev2, 0);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return NOTIFY_DONE;
|
|
|
|
}
|
|
|
|
default:
|
|
return NOTIFY_DONE;
|
|
|
|
}
|
|
return NOTIFY_DONE;
|
|
|
|
}
|
|
|
|
static struct notifier_block bp_notifier_block = {
|
|
.notifier_call = bp_device_event,
|
|
};
|
|
static struct notifier_block bp_reboot_block = {
|
|
.notifier_call = bp_reboot_event,
|
|
};
|
|
|
|
|
|
|
|
static int device_open(struct inode *inode, struct file *file)
|
|
{
|
|
|
|
file->private_data = NULL;
|
|
|
|
#ifdef DEBUG
|
|
printk("device_open(%p)\n", file);
|
|
#endif
|
|
Device_Open++;
|
|
/*
|
|
* Initialize the message
|
|
*/
|
|
return SUCCESS;
|
|
}
|
|
static int device_release(struct inode *inode, struct file *file)
|
|
{
|
|
int i;
|
|
|
|
#ifdef DEBUG
|
|
printk("device_release(%p,%p)\n", inode, file);
|
|
#endif
|
|
Device_Open--;
|
|
|
|
if ( file->private_data != NULL )
|
|
{
|
|
mutex_unlock((struct mutex *) file->private_data);
|
|
for (i=0; i< mng_device_num; i++) {
|
|
if (! bpctl_dev_mng_arr[i].mutex_owner_module) {
|
|
/*if (bpctl_dev_mng_arr[i].i2c_bus_lock.owner == current )*/
|
|
mutex_unlock(&bpctl_dev_mng_arr[i].i2c_bus_lock);
|
|
}
|
|
}
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
|
|
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 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 int get_dev_mng_idx(int ifindex){
|
|
int idx_dev=0;
|
|
|
|
for (idx_dev = 0; ((bpctl_dev_mng_arr[idx_dev].pdev!=NULL)&&(idx_dev<mng_device_num)); idx_dev++) {
|
|
if (ifindex == bpctl_dev_mng_arr[idx_dev].ifindex)
|
|
return idx_dev;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
#if 0
|
|
static bpctl_dev_mng_t *get_dev_mng_idx_p(int ifindex){
|
|
int idx_dev=0;
|
|
|
|
for (idx_dev = 0; ((bpctl_dev_mng_arr[idx_dev].pdev!=NULL)&&(idx_dev<mng_device_num)); idx_dev++) {
|
|
if (ifindex==bpctl_dev_mng_arr[idx_dev].ifindex)
|
|
return &bpctl_dev_mng_arr[idx_dev];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
|
|
static int get_dev_mng_idx_bsf(int bus, int slot, int func){
|
|
int idx_dev=0;
|
|
|
|
for (idx_dev = 0; ((bpctl_dev_mng_arr[idx_dev].pdev!=NULL)&&(idx_dev<mng_device_num)); idx_dev++) {
|
|
|
|
if ((bus==bpctl_dev_mng_arr[idx_dev].bus) &&
|
|
(slot==bpctl_dev_mng_arr[idx_dev].slot) &&
|
|
(func==bpctl_dev_mng_arr[idx_dev].func) ) {
|
|
return idx_dev;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static void if_scan_init(void)
|
|
{
|
|
struct net_device *dev;
|
|
|
|
#if (LINUX_VERSION_CODE >= 0x020618)
|
|
for_each_netdev(&init_net, dev)
|
|
#elif (LINUX_VERSION_CODE >= 0x20616)
|
|
for_each_netdev(dev)
|
|
#else
|
|
for (dev = dev_base; dev; dev = dev->next)
|
|
#endif
|
|
|
|
{
|
|
int idx_dev;
|
|
|
|
if (bp_get_dev_idx_bsf(dev, &idx_dev))
|
|
continue;
|
|
|
|
if (idx_dev == -1)
|
|
continue;
|
|
|
|
bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
|
|
bpctl_dev_arr[idx_dev].ndev = dev;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void if_scan_mng_init(void)
|
|
{
|
|
struct net_device *dev;
|
|
|
|
#if (LINUX_VERSION_CODE >= 0x020618)
|
|
for_each_netdev(&init_net, dev)
|
|
#elif (LINUX_VERSION_CODE >= 0x20616)
|
|
for_each_netdev(dev)
|
|
#else
|
|
for (dev = dev_base; dev; dev = dev->next)
|
|
#endif
|
|
|
|
{
|
|
int idx_dev;
|
|
|
|
if (bp_get_dev_mng_idx_bsf(dev, &idx_dev))
|
|
continue;
|
|
|
|
if (idx_dev == -1)
|
|
continue;
|
|
|
|
bpctl_dev_mng_arr[idx_dev].ifindex = dev->ifindex;
|
|
bpctl_dev_mng_arr[idx_dev].ndev = dev;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define FM10K_UC_ADDR_START 0x000000 /* start of standard regs */
|
|
#define FM10K_WC_ADDR_START 0x100000 /* start of Tx Desc Cache */
|
|
#define FM10K_DBI_ADDR_START 0x200000 /* start of debug registers */
|
|
#define FM10K_UC_ADDR_SIZE (FM10K_WC_ADDR_START - FM10K_UC_ADDR_START)
|
|
#define FM10K_WC_ADDR_SIZE (FM10K_DBI_ADDR_START - FM10K_WC_ADDR_START)
|
|
|
|
static int bp_cmd_request(bpctl_dev_mng_t *pbpctl_dev_c, bp_cmd_t *bp_cmd_buf, bp_cmd_rsp_t *bp_rsp_buf);
|
|
|
|
static int bp_cmd_request(bpctl_dev_mng_t *pbpctl_dev_c, bp_cmd_t *bp_cmd_buf, bp_cmd_rsp_t *bp_rsp_buf) {
|
|
int ret_val;
|
|
int try_num = 10;
|
|
|
|
/* atomic_set(&pbpctl_dev->wdt_busy,1); */
|
|
/*
|
|
* Send command
|
|
*/
|
|
|
|
if (!pbpctl_dev_c)
|
|
return -1;
|
|
|
|
while (try_num--) {
|
|
memset(bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
|
|
usec_delay_bp(CMND_INTERVAL);
|
|
|
|
if ((ret_val = fmPlatformFm10000BypassWriteRead(pbpctl_dev_c,
|
|
0x57,
|
|
(unsigned char *)bp_cmd_buf,
|
|
sizeof(bp_cmd_t),
|
|
0))) {
|
|
printk("bp_cmd_request(write): Not supported!\n");
|
|
continue;
|
|
// return 0;
|
|
}
|
|
|
|
usec_delay_bp(CMND_INTERVAL);
|
|
#if 1
|
|
/*
|
|
* Receive replay
|
|
*/
|
|
|
|
if ((ret_val = fmPlatformFm10000BypassWriteRead(pbpctl_dev_c, 0x57,
|
|
(unsigned char *)bp_rsp_buf, 0,
|
|
sizeof(bp_cmd_rsp_t))) < 0) {
|
|
printk("bp_cmd_request(read): Not supported!\n");
|
|
continue;
|
|
//return 0;
|
|
}
|
|
#endif
|
|
|
|
// if (bp_rsp_buf->rsp.rsp_id != BP_ERR_OK)
|
|
// continue;
|
|
if (bp_rsp_buf->rsp.rsp_id != BP_ERR_OK)
|
|
continue;
|
|
|
|
#if 1
|
|
if (bp_rsp_buf->rsp.rsp_id != BP_ERR_OK)
|
|
printk("bp_cmd_request(got err code or corrupted data!) (%x %x %x %x %x %x)\n",
|
|
bp_rsp_buf->cmd_bytes[0],bp_rsp_buf->cmd_bytes[1],bp_rsp_buf->cmd_bytes[2],
|
|
bp_rsp_buf->cmd_bytes[3],bp_rsp_buf->cmd_bytes[4],bp_rsp_buf->cmd_bytes[5]);
|
|
|
|
#endif
|
|
|
|
break;
|
|
}
|
|
/*atomic_set(&pbpctl_dev->wdt_busy,0);*/
|
|
|
|
if (!try_num) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
int is_bypass_port_rd_fn(int port){
|
|
|
|
return(((port == 1)||(port == 3)) ? 1:0);
|
|
}
|
|
|
|
|
|
int is_bypass_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
|
|
if (!pbpctl_dev) {
|
|
return -1;
|
|
}
|
|
return(pbpctl_dev->bp_master_flag);
|
|
|
|
}
|
|
|
|
|
|
int set_bypass_rd_fn (bpctl_dev_t *pbpctl_dev, int bypass_mode){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev) {
|
|
return ret;
|
|
}
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c) {
|
|
return ret;
|
|
}
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port)) {
|
|
return ret;
|
|
}
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num= (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id=CMD_SET_BYPASS;
|
|
bp_cmd_buf.cmd.cmd_data.bypass_mode=bypass_mode?1:0;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(LATCH_DELAY);
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
int get_wd_expire_rd_fn (bpctl_dev_t *pbpctl_dev){
|
|
|
|
int ret = -1, gpio = 0, port = 0;
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
uint32_t cfg;
|
|
|
|
if (!pbpctl_dev) {
|
|
return -1;
|
|
}
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c) {
|
|
return ret;
|
|
}
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port)) {
|
|
return ret;
|
|
}
|
|
|
|
gpio = (port == 1)?9:10;
|
|
|
|
cfg = BPCTL_READ_REG(pbpctl_dev_c, FM10000_GPIO_CFG);
|
|
cfg &= ~(1 << gpio);
|
|
BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_CFG, cfg);
|
|
cfg = 0;
|
|
cfg = BPCTL_READ_REG(pbpctl_dev_c, FM10000_GPIO_DATA);
|
|
ret = cfg & (1 << gpio);
|
|
|
|
return(ret==0?1:0);
|
|
}
|
|
|
|
int get_bypass_rd_fn (bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret=-1, port = 0;
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev) {
|
|
return ret;
|
|
}
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c) {
|
|
return ret;
|
|
}
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port)) {
|
|
return ret;
|
|
}
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
if (bp_rsp_buf.rsp.rsp_data.bypass_pwoff == BYPASS_PWOFF_EN) {
|
|
ret = 1;
|
|
}
|
|
else if (bp_rsp_buf.rsp.rsp_data.bypass_pwoff == BYPASS_PWOFF_DIS) {
|
|
ret = 0;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_bypass_change_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1;
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
int port = 0;
|
|
|
|
if (!pbpctl_dev) {
|
|
return ret;
|
|
}
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c) {
|
|
return ret;
|
|
}
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port)) {
|
|
return ret;
|
|
}
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;;
|
|
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_CHANGE;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_data.bypass_change == BYPASS_CHANGED) {
|
|
ret = 1;
|
|
}
|
|
else if (bp_rsp_buf.rsp.rsp_data.bypass_change == BYPASS_NOT_CHANGED) {
|
|
ret = 0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int set_dis_bypass_rd_fn(bpctl_dev_t *pbpctl_dev, int dis_bypass){
|
|
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret=-1;
|
|
int port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev) {
|
|
return ret;
|
|
}
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c) {
|
|
return ret;
|
|
}
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port)) {
|
|
return ret;
|
|
}
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_DIS_BYPASS;
|
|
bp_cmd_buf.cmd.cmd_data.dis_bypass =
|
|
dis_bypass?DIS_BYPASS_DISABLE:DIS_BYPASS_ENABLE;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(BYPASS_CAP_DELAY);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_dis_bypass_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret=-1;
|
|
int port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev) {
|
|
return ret;
|
|
}
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c) {
|
|
return ret;
|
|
}
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port)) {
|
|
return ret;
|
|
}
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_DIS_BYPASS;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_data.dis_bypass==DIS_BYPASS_DISABLE) {
|
|
ret=1;
|
|
}
|
|
else if (bp_rsp_buf.rsp.rsp_data.dis_bypass==DIS_BYPASS_ENABLE) {
|
|
ret=0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int set_bypass_pwoff_rd_fn (bpctl_dev_t *pbpctl_dev, int bypass_mode){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port =0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev) {
|
|
return ret;
|
|
}
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c) {
|
|
return ret;
|
|
}
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port)) {
|
|
return ret;
|
|
}
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_BYPASS_PWOFF;
|
|
bp_cmd_buf.cmd.cmd_data.bypass_pwoff =
|
|
bypass_mode?BYPASS_PWOFF_EN:BYPASS_PWOFF_DIS;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(EEPROM_WR_DELAY);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_bypass_pwoff_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev) {
|
|
return ret;
|
|
}
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c) {
|
|
return ret;
|
|
}
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port)) {
|
|
return ret;
|
|
}
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_PWOFF;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
if (bp_rsp_buf.rsp.rsp_data.bypass_pwoff == BYPASS_PWOFF_EN) {
|
|
ret = 1;
|
|
}
|
|
else if (bp_rsp_buf.rsp.rsp_data.bypass_pwoff == BYPASS_PWOFF_DIS) {
|
|
ret = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
int set_bypass_pwup_rd_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode){
|
|
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev) {
|
|
return ret;
|
|
}
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c) {
|
|
return ret;
|
|
}
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port)) {
|
|
return ret;
|
|
}
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_BYPASS_PWUP;
|
|
bp_cmd_buf.cmd.cmd_data.bypass_pwup =
|
|
bypass_mode?BYPASS_PWUP_EN:BYPASS_PWUP_DIS;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(EEPROM_WR_DELAY);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_bypass_pwup_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev) {
|
|
return ret;
|
|
}
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c) {
|
|
return ret;
|
|
}
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port)) {
|
|
return ret;
|
|
}
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_PWUP;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
if (bp_rsp_buf.rsp.rsp_data.bypass_pwup == BYPASS_PWUP_EN)
|
|
ret=1;
|
|
else if (bp_rsp_buf.rsp.rsp_data.bypass_pwup == BYPASS_PWUP_DIS)
|
|
ret=0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int set_bypass_wd_rd_fn(bpctl_dev_t *pbpctl_dev, int timeout){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_BYPASS_WD;
|
|
bp_cmd_buf.cmd.cmd_data.timeout = htonl(timeout);
|
|
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret = ntohl(bp_rsp_buf.rsp.rsp_data.timeout_set);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_bypass_wd_rd_fn(bpctl_dev_t *pbpctl_dev, int *timeout){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_WD;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
*timeout = ntohl(bp_rsp_buf.rsp.rsp_data.timeout_set);
|
|
ret = 0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_wd_expire_time_rd_fn(bpctl_dev_t *pbpctl_dev, int *time_left){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id=CMD_GET_WD_EXPIRE_TIME;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
*time_left = ntohl(bp_rsp_buf.rsp.rsp_data.time_left);
|
|
if (*time_left == 0)
|
|
ret = 0;
|
|
else ret = 1;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int reset_bypass_wd_timer_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
int ret=-1, gpio = 0, port = 0;
|
|
uint32_t cfg = 0, data = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
gpio = (port==1)?9:10;
|
|
|
|
cfg = BPCTL_READ_REG(pbpctl_dev_c, FM10000_GPIO_CFG);
|
|
|
|
cfg |= (1 << gpio);
|
|
cfg &= ~( 1 << (gpio + 16) );
|
|
BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_CFG, cfg);
|
|
|
|
data = BPCTL_READ_REG(pbpctl_dev_c, FM10000_GPIO_DATA);
|
|
data |= (1 << gpio);
|
|
BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_DATA, data);
|
|
data &= ~(1 << gpio);
|
|
BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_DATA, data);
|
|
usec_delay_bp(WDT_INTERVAL);
|
|
data |= (1 << gpio);
|
|
BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_DATA, data);
|
|
cfg &= ~(1 << gpio);
|
|
BPCTL_WRITE_REG(pbpctl_dev_c, FM10000_GPIO_CFG, cfg);
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
int get_wd_set_caps_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_WD_SET_CAPS;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK)
|
|
ret=ntohl(bp_rsp_buf.rsp.rsp_data.wd_set_caps);
|
|
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int set_std_nic_rd_fn(bpctl_dev_t *pbpctl_dev, int nic_mode){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id=CMD_SET_STD_NIC;
|
|
bp_cmd_buf.cmd.cmd_data.std_nic =
|
|
nic_mode?STD_NIC_EN:STD_NIC_DIS;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(BYPASS_CAP_DELAY);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_std_nic_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_STD_NIC;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
if (bp_rsp_buf.rsp.rsp_data.std_nic==STD_NIC_EN)
|
|
ret=1;
|
|
else if (bp_rsp_buf.rsp.rsp_data.std_nic==STD_NIC_DIS)
|
|
ret=0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int set_disc_rd_fn (bpctl_dev_t *pbpctl_dev, int disc_mode){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_DISC;
|
|
bp_cmd_buf.cmd.cmd_data.disc_mode=disc_mode?1:0;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(LATCH_DELAY);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_disc_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_DISC;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
if (bp_rsp_buf.rsp.rsp_data.disc_mode==1)
|
|
ret=1;
|
|
else if (bp_rsp_buf.rsp.rsp_data.disc_mode==0)
|
|
ret=0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int set_disc_pwup_rd_fn(bpctl_dev_t *pbpctl_dev, int disc_mode){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_DISC_PWUP;
|
|
bp_cmd_buf.cmd.cmd_data.disc_pwup =
|
|
disc_mode?DISC_PWUP_EN:DISC_PWUP_DIS;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(EEPROM_WR_DELAY);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_disc_pwup_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_DISC_PWUP;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
if (bp_rsp_buf.rsp.rsp_data.disc_pwup==DISC_PWUP_EN)
|
|
ret=1;
|
|
else if (bp_rsp_buf.rsp.rsp_data.disc_pwup==DISC_PWUP_DIS)
|
|
ret=0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_disc_change_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_DISC_CHANGE;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
if (bp_rsp_buf.rsp.rsp_data.disc_change==DISC_CHANGED)
|
|
ret=1;
|
|
else if (bp_rsp_buf.rsp.rsp_data.disc_change==DISC_NOT_CHANGED)
|
|
ret=0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int set_dis_disc_rd_fn(bpctl_dev_t *pbpctl_dev, int dis_param){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_DIS_DISC;
|
|
bp_cmd_buf.cmd.cmd_data.dis_disc =
|
|
dis_param?DIS_DISC_DISABLE:DIS_DISC_ENABLE;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(BYPASS_CAP_DELAY);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_dis_disc_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_DIS_DISC;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
if (bp_rsp_buf.rsp.rsp_data.dis_disc == DIS_DISC_DISABLE)
|
|
ret=1;
|
|
else if (bp_rsp_buf.rsp.rsp_data.dis_disc == DIS_DISC_ENABLE)
|
|
ret=0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_wd_exp_mode_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_WD_EXP_MODE;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=bp_rsp_buf.rsp.rsp_data.wd_exp_mode;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int set_wd_exp_mode_rd_fn(bpctl_dev_t *pbpctl_dev, int param){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_WD_EXP_MODE;
|
|
bp_cmd_buf.cmd.cmd_data.wd_exp_mode = param;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(BYPASS_CAP_DELAY);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int set_tx_rd_fn(bpctl_dev_t *pbpctl_dev, int tx_state){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
|
|
if ((!port) || (port > 4))
|
|
return -1;
|
|
|
|
if (DBI240_IF_SERIES(pbpctl_dev_c->subdevice)) {
|
|
unsigned int mac_cfg[IES10K_MAC_CFG_WIDTH];
|
|
|
|
memset(mac_cfg, 0, IES10K_MAC_CFG_WIDTH*4);
|
|
|
|
if (tx_state) {
|
|
iespl_read_mult_u32(pbpctl_dev_c, IES10K_MAC_CFG(pbpctl_dev->epl, pbpctl_dev->lane_num, 0 ),
|
|
IES10K_MAC_CFG_WIDTH, mac_cfg);
|
|
IES_ARRAY_SET_FIELD(mac_cfg, IES10K_MAC_CFG, TXFAULTMODE, 0);
|
|
iespl_write_mult_u32(pbpctl_dev_c, IES10K_MAC_CFG(pbpctl_dev->epl, pbpctl_dev->lane_num, 0 ), IES10K_MAC_CFG_WIDTH, mac_cfg);
|
|
}
|
|
else {
|
|
iespl_read_mult_u32(pbpctl_dev_c, IES10K_MAC_CFG(pbpctl_dev->epl, pbpctl_dev->lane_num, 0 ),
|
|
IES10K_MAC_CFG_WIDTH, mac_cfg);
|
|
IES_ARRAY_SET_FIELD(mac_cfg, IES10K_MAC_CFG, TXFAULTMODE,
|
|
convert_adminmode_txlinkfault(IES_PORT_MODE_LOCAL_FAULT));
|
|
iespl_write_mult_u32(pbpctl_dev_c, IES10K_MAC_CFG(pbpctl_dev->epl, pbpctl_dev->lane_num, 0 ), IES10K_MAC_CFG_WIDTH, mac_cfg);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
if (is_bypass_port_rd_fn(port)) {
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_data.tx_dis.port_num = 0;
|
|
}
|
|
else {
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 2)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_data.tx_dis.port_num = 1;
|
|
}
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_TX;
|
|
bp_cmd_buf.cmd.cmd_data.tx_dis.mode = tx_state?TX_OFF:TX_ON;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_tx_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
|
|
if ((!port) || (port > 4))
|
|
return -1;
|
|
|
|
if (DBI240_IF_SERIES(pbpctl_dev_c->subdevice)) {
|
|
unsigned int mac_cfg[IES10K_MAC_CFG_WIDTH];
|
|
int tx_fault = 0;
|
|
|
|
memset(mac_cfg, 0, IES10K_MAC_CFG_WIDTH*4);
|
|
|
|
iespl_read_mult_u32(pbpctl_dev_c, IES10K_MAC_CFG(pbpctl_dev->epl, pbpctl_dev->lane_num, 0 ),
|
|
IES10K_MAC_CFG_WIDTH, mac_cfg);
|
|
tx_fault = IES_ARRAY_GET_FIELD(mac_cfg, IES10K_MAC_CFG, TXFAULTMODE);
|
|
|
|
ret = (tx_fault == 2) ? 0:1;
|
|
return ret;
|
|
}
|
|
|
|
if (is_bypass_port_rd_fn(port)) {
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_data.tx_dis.port_num = 0;
|
|
}
|
|
else {
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 2)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_data.tx_dis.port_num = 1;
|
|
}
|
|
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_TX;
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
if (bp_rsp_buf.rsp.rsp_data.tx_dis.mode==TX_ON)
|
|
ret=0;
|
|
else if (bp_rsp_buf.rsp.rsp_data.tx_dis.mode==TX_OFF)
|
|
ret=1;
|
|
}
|
|
else return -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int set_bp_force_link_rd_fn(int dev_num, int tx_state){
|
|
return -1;
|
|
}
|
|
|
|
|
|
int get_bp_force_link_rd_fn(int dev_num){
|
|
return -1;
|
|
}
|
|
|
|
int set_bypass_wd_rd_auto(bpctl_dev_t *pbpctl_dev, unsigned int param){
|
|
if (pbpctl_dev->bp_caps&WD_CTL_CAP) {
|
|
if (pbpctl_dev->reset_time!=param) {
|
|
pbpctl_dev->reset_time=param;
|
|
if (param)
|
|
mod_timer(&pbpctl_dev->bp_timer, jiffies);
|
|
}
|
|
return 0;
|
|
}
|
|
return BP_NOT_CAP;
|
|
}
|
|
|
|
int get_bypass_wd_rd_auto(bpctl_dev_t *pbpctl_dev){
|
|
|
|
if (pbpctl_dev->bp_caps&WD_CTL_CAP) {
|
|
return pbpctl_dev->reset_time;
|
|
}
|
|
return BP_NOT_CAP;
|
|
}
|
|
|
|
|
|
int set_wd_autoreset_rd_fn(bpctl_dev_t *pbpctl_dev, int param){
|
|
if (!pbpctl_dev)
|
|
return -1;
|
|
|
|
return(set_bypass_wd_rd_auto(pbpctl_dev, param));
|
|
}
|
|
|
|
int get_wd_autoreset_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
if (!pbpctl_dev)
|
|
return -1;
|
|
|
|
return(get_bypass_wd_rd_auto(pbpctl_dev));
|
|
}
|
|
|
|
|
|
int get_bypass_caps_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
|
|
if ((!port) || (port > 4))
|
|
return -1;
|
|
|
|
if (is_bypass_port_rd_fn(port)) {
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
}
|
|
else {
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 2)? 0:1;
|
|
}
|
|
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_CAPS;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=(ntohl(bp_rsp_buf.rsp.rsp_data.bypass_caps));
|
|
if (!(is_bypass_port_rd_fn(port))){
|
|
int ret1 = 0;
|
|
if (ret&TX_CTL_CAP)
|
|
ret1 = (TX_CTL_CAP|TX_STATUS_CAP);
|
|
return ret1;
|
|
|
|
}
|
|
if (DBI240_IF_SERIES(pbpctl_dev_c->subdevice)) {
|
|
ret |= TX_CTL_CAP;
|
|
if (is_bypass_port_rd_fn(port))
|
|
ret |= TPL_CAP;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_bypass_caps_ex_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_CAPS_EX;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=ntohl(bp_rsp_buf.rsp.rsp_data.bypass_caps);
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int get_bypass_slave_rd_fn(bpctl_dev_t *pbpctl_dev,bpctl_dev_t **pbpctl_dev_out){
|
|
int idx_dev=0;
|
|
|
|
if (!pbpctl_dev)
|
|
return -1;
|
|
|
|
if ((pbpctl_dev->epl_num == 1)||(pbpctl_dev->epl_num == 3)) {
|
|
for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev != NULL)&&(idx_dev<device_num)); idx_dev++) {
|
|
|
|
if (DBI410_IF_SERIES(pbpctl_dev->subdevice)) {
|
|
|
|
if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus)&&
|
|
(bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot)) {
|
|
if ((pbpctl_dev->epl_num == 1) &&
|
|
(bpctl_dev_arr[idx_dev].epl_num == 2)) {
|
|
*pbpctl_dev_out = &bpctl_dev_arr[idx_dev];
|
|
return 1;
|
|
}
|
|
if ((pbpctl_dev->epl_num == 3) &&
|
|
(bpctl_dev_arr[idx_dev].epl_num == 4)) {
|
|
*pbpctl_dev_out = &bpctl_dev_arr[idx_dev];
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (bpctl_dev_arr[idx_dev].pdev == pbpctl_dev->pdev_pf_slave) {
|
|
if ((pbpctl_dev->epl_num == 1) &&
|
|
(bpctl_dev_arr[idx_dev].epl_num == 2)) {
|
|
*pbpctl_dev_out = &bpctl_dev_arr[idx_dev];
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
else return 0;
|
|
}
|
|
|
|
|
|
int set_tpl_rd_fn(bpctl_dev_t *pbpctl_dev, int tpl_mode){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
if (DBI240_IF_SERIES(pbpctl_dev_c->subdevice)) {
|
|
uint32_t link1, link2;
|
|
bpctl_dev_t *pbpctl_dev_m, *pbpctl_dev2;
|
|
|
|
pbpctl_dev_m = pbpctl_dev;
|
|
pbpctl_dev2 = get_status_port_fn(pbpctl_dev);
|
|
|
|
if ((!pbpctl_dev_m)||(!pbpctl_dev2))
|
|
return -1;
|
|
|
|
if ((!pbpctl_dev->ndev)||(!pbpctl_dev2->ndev))
|
|
return -1;
|
|
|
|
pbpctl_dev->bp_tpl_flag = tpl_mode;
|
|
|
|
set_tx_rd_fn(pbpctl_dev2, 1);
|
|
set_tx_rd_fn(pbpctl_dev, 1);
|
|
|
|
if (!tpl_mode)
|
|
return 0;
|
|
|
|
link1 = netif_carrier_ok(pbpctl_dev->ndev);
|
|
link2 = netif_carrier_ok(pbpctl_dev2->ndev);
|
|
|
|
if ((!link1)&&(link2))
|
|
set_tx_rd_fn(pbpctl_dev2, 0);
|
|
if ((link1)&&(!link2))
|
|
set_tx_rd_fn(pbpctl_dev, 0);
|
|
|
|
mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*HZ);
|
|
|
|
return 0;
|
|
}
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_TPL;
|
|
bp_cmd_buf.cmd.cmd_data.tpl_mode = tpl_mode?TPL_ON:TPL_OFF;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret = 0;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_tpl_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
if (DBI240_IF_SERIES(pbpctl_dev_c->subdevice)) {
|
|
return pbpctl_dev->bp_tpl_flag;
|
|
}
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_TPL;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_data.tpl_mode == TPL_ON)
|
|
ret = 1;
|
|
else if (bp_rsp_buf.rsp.rsp_data.tpl_mode == TPL_OFF)
|
|
ret = 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int set_bp_wait_at_pwup_rd_fn(bpctl_dev_t *pbpctl_dev, int bp_wait_at_pwup){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_BP_WAIT_AT_PWUP;
|
|
bp_cmd_buf.cmd.cmd_data.bp_wait_at_pwup = bp_wait_at_pwup?1:0;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(EEPROM_WR_DELAY);
|
|
return ret;
|
|
}
|
|
|
|
int get_bp_wait_at_pwup_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_BP_WAIT_AT_PWUP;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_data.bp_wait_at_pwup == 1)
|
|
ret = 1;
|
|
else if (bp_rsp_buf.rsp.rsp_data.bp_wait_at_pwup == 0)
|
|
ret = 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
int set_bp_hw_reset_rd_fn(bpctl_dev_t *pbpctl_dev, int bp_hw_reset){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_BP_HW_RESET;
|
|
bp_cmd_buf.cmd.cmd_data.bp_hw_reset = bp_hw_reset?1:0;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(EEPROM_WR_DELAY);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int get_bp_hw_reset_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_BP_HW_RESET;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_data.bp_hw_reset == 1)
|
|
ret = 1;
|
|
else if (bp_rsp_buf.rsp.rsp_data.bp_hw_reset == 0)
|
|
ret = 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int get_bypass_info_rd_fn(bpctl_dev_t *pbpctl_dev, char *dev_name, unsigned char *add_param){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_GET_BYPASS_INFO;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
strcpy(dev_name, pbpctl_dev->name);
|
|
/**add_param = bp_rsp_buf.rsp.rsp_data.bypass_info.fw_ver;*/
|
|
memcpy(add_param,(char *)&(bp_rsp_buf.rsp.rsp_data.bypass_info.fw_ver), 1);
|
|
ret=0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
int set_bp_manuf_rd_fn(bpctl_dev_t *pbpctl_dev){
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret = -1, port = 0;
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
|
|
if (!pbpctl_dev)
|
|
return ret;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return ret;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return ret;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num = (port == 1)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id = CMD_SET_BP_MANUF;
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
if (bp_rsp_buf.rsp.rsp_id == BP_ERR_OK) {
|
|
ret=0;
|
|
}
|
|
}
|
|
msec_delay_bp(BYPASS_CAP_DELAY);
|
|
return ret;
|
|
|
|
}
|
|
|
|
int bypass_fw_ver_rd(bpctl_dev_t *pbpctl_dev){
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
bp_cmd_t bp_cmd_buf;
|
|
bp_cmd_rsp_t bp_rsp_buf;
|
|
int ret=-1, port = 0;
|
|
|
|
if (!pbpctl_dev)
|
|
return -1;
|
|
|
|
pbpctl_dev_c = pbpctl_dev->pbpctl_dev_c;
|
|
if (!pbpctl_dev_c)
|
|
return -1;
|
|
|
|
port = pbpctl_dev->epl_num;
|
|
|
|
|
|
if (!is_bypass_port_rd_fn(port))
|
|
return -1;
|
|
|
|
memset(&bp_cmd_buf, 0, sizeof(bp_cmd_buf));
|
|
memset(&bp_rsp_buf, 0, sizeof(bp_cmd_rsp_t));
|
|
bp_cmd_buf.cmd.cmd_dev_num= (pbpctl_dev->func == 0)? 0:1;
|
|
bp_cmd_buf.cmd.cmd_id=CMD_GET_BYPASS_INFO;
|
|
|
|
|
|
if (bp_cmd_request(pbpctl_dev_c, &bp_cmd_buf, &bp_rsp_buf)) {
|
|
ret = bp_rsp_buf.rsp.rsp_data.bypass_info.fw_ver;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
static int wdt_timer_reload(bpctl_dev_t *pbpctl_dev){
|
|
|
|
if (pbpctl_dev->bp_caps&WD_CTL_CAP) {
|
|
reset_bypass_wd_timer_rd_fn(pbpctl_dev);
|
|
return 1;
|
|
}
|
|
else return BP_NOT_CAP;
|
|
}
|
|
|
|
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0))
|
|
static void wd_reset_timer(unsigned long param){
|
|
bpctl_dev_t *pbpctl_dev= (bpctl_dev_t *) param;
|
|
#else
|
|
static void wd_reset_timer(struct timer_list *t){
|
|
bpctl_dev_t *pbpctl_dev= from_timer(pbpctl_dev, t, bp_timer);
|
|
#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;
|
|
}
|
|
wdt_timer_reload(pbpctl_dev);
|
|
|
|
if (pbpctl_dev->reset_time) {
|
|
mod_timer(&pbpctl_dev->bp_timer, jiffies+(HZ*pbpctl_dev->reset_time)/1000);
|
|
}
|
|
}
|
|
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0))
|
|
static void bp_tpl_timer_fn(unsigned long param){
|
|
bpctl_dev_t *pbpctl_dev=(bpctl_dev_t *) param;
|
|
#else
|
|
static void bp_tpl_timer_fn(struct timer_list *t){
|
|
bpctl_dev_t *pbpctl_dev=from_timer(pbpctl_dev, t, bp_tpl_timer);
|
|
#endif
|
|
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) {
|
|
return;
|
|
}
|
|
|
|
if ((!pbpctl_dev->ndev)||(!pbpctl_dev_b->ndev))
|
|
return;
|
|
|
|
link1 = netif_carrier_ok(pbpctl_dev->ndev);
|
|
link2 = netif_carrier_ok(pbpctl_dev_b->ndev);
|
|
|
|
if (link1)
|
|
pbpctl_dev->tpl_wait = 0;
|
|
if (link2)
|
|
pbpctl_dev_b->tpl_wait = 0;
|
|
|
|
if ((link1) && (!link2)) {
|
|
if (!get_tx_rd_fn(pbpctl_dev_b)) {
|
|
set_tx_rd_fn(pbpctl_dev_b, 1);
|
|
mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*2*HZ);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ((link2) && (!link1)) {
|
|
if (!get_tx_rd_fn(pbpctl_dev)) {
|
|
set_tx_rd_fn(pbpctl_dev, 1);
|
|
mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*2*HZ);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ((link1)&&(get_tx_rd_fn(pbpctl_dev))) {
|
|
if ((!link2)&&(get_tx_rd_fn(pbpctl_dev_b))) {
|
|
if (pbpctl_dev_b->tpl_wait){
|
|
pbpctl_dev_b->tpl_wait = 0;
|
|
mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*2*HZ);
|
|
return;
|
|
}
|
|
set_tx_rd_fn(pbpctl_dev,0);
|
|
}
|
|
else if (!get_tx_rd_fn(pbpctl_dev_b)) {
|
|
pbpctl_dev_b->tpl_wait = 1;
|
|
set_tx_rd_fn(pbpctl_dev_b,1);
|
|
}
|
|
}
|
|
else if ((!link1)&&(get_tx_rd_fn(pbpctl_dev))) {
|
|
if ((link2)&&(get_tx_rd_fn(pbpctl_dev_b))) {
|
|
if (pbpctl_dev->tpl_wait){
|
|
pbpctl_dev->tpl_wait = 0;
|
|
mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*2*HZ);
|
|
return;
|
|
}
|
|
set_tx_rd_fn(pbpctl_dev_b,0);
|
|
}
|
|
}
|
|
else if ((link1)&&(!get_tx_rd_fn(pbpctl_dev))) {
|
|
if ((link2)&&(get_tx_rd_fn(pbpctl_dev_b))) {
|
|
pbpctl_dev->tpl_wait = 1;
|
|
set_tx_rd_fn(pbpctl_dev,1);
|
|
}
|
|
}
|
|
else if ((!link1)&&(!get_tx_rd_fn(pbpctl_dev))) {
|
|
if ((link2)&&(get_tx_rd_fn(pbpctl_dev_b))) {
|
|
pbpctl_dev->tpl_wait = 1;
|
|
set_tx_rd_fn(pbpctl_dev,1);
|
|
}
|
|
}
|
|
|
|
mod_timer(&pbpctl_dev->bp_tpl_timer, jiffies+BP_LINK_MON_DELAY*HZ);
|
|
}
|
|
|
|
|
|
static void remove_bypass_wd_auto(bpctl_dev_t *pbpctl_dev){
|
|
if (pbpctl_dev->bp_caps&WD_CTL_CAP) {
|
|
del_timer_sync(&pbpctl_dev->bp_timer);
|
|
}
|
|
}
|
|
|
|
void remove_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev){
|
|
if ((is_bypass_rd_fn(pbpctl_dev)) &&
|
|
(DBI240_IF_SERIES(pbpctl_dev->subdevice)))
|
|
{
|
|
set_tpl_rd_fn(pbpctl_dev, 0);
|
|
del_timer_sync(&pbpctl_dev->bp_tpl_timer);
|
|
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
static int init_bypass_wd_auto(bpctl_dev_t *pbpctl_dev){
|
|
if (pbpctl_dev->bp_caps&WD_CTL_CAP) {
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0))
|
|
init_timer(&pbpctl_dev->bp_timer);
|
|
pbpctl_dev->bp_timer.function=&wd_reset_timer;
|
|
pbpctl_dev->bp_timer.data=(unsigned long)pbpctl_dev;
|
|
#else
|
|
timer_setup(&pbpctl_dev->bp_timer, wd_reset_timer, 0);
|
|
#endif
|
|
return 1;
|
|
}
|
|
return BP_NOT_CAP;
|
|
}
|
|
|
|
|
|
int init_bypass_tpl_auto(bpctl_dev_t *pbpctl_dev){
|
|
if (!pbpctl_dev)
|
|
return BP_NOT_CAP;
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0))
|
|
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;
|
|
#else
|
|
timer_setup(&pbpctl_dev->bp_tpl_timer, bp_tpl_timer_fn, 0);
|
|
#endif
|
|
return BP_OK;
|
|
}
|
|
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
|
|
static int device_ioctl(struct inode *inode, /* see include/linux/fs.h */
|
|
struct file *file, /* ditto */
|
|
unsigned int ioctl_num, /* number and param for ioctl */
|
|
unsigned long ioctl_param)
|
|
#else
|
|
static long device_ioctl(struct file *file, /* ditto */
|
|
unsigned int ioctl_num, /* number and param for ioctl */
|
|
unsigned long ioctl_param)
|
|
|
|
#endif
|
|
{
|
|
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;
|
|
bpctl_dev_t *pbpctl_dev;
|
|
|
|
if (ioctl_num == IOCTL_TX_MSG(EXCLUSIVE_LOCK)) {
|
|
dev_idx = get_dev_mng_idx(ioctl_param);
|
|
if ( dev_idx < 0 || dev_idx > mng_device_num) {
|
|
return -1;
|
|
}
|
|
TAKE_PLAT_I2C_BUS_LOCK_IDX(file, dev_idx);
|
|
return SUCCESS;
|
|
}
|
|
|
|
if (ioctl_num == IOCTL_TX_MSG(DROP_EXCLUSIVE)) {
|
|
dev_idx = get_dev_mng_idx(ioctl_param);
|
|
if ( dev_idx < 0 || dev_idx > mng_device_num) {
|
|
return -1;
|
|
}
|
|
DROP_PLAT_I2C_BUS_LOCK_IDX(file, dev_idx);
|
|
return SUCCESS;
|
|
}
|
|
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
|
|
//lock_kernel();
|
|
#endif
|
|
lock_bpctl();
|
|
|
|
/*
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
|
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) {
|
|
ret= -EOPNOTSUPP;
|
|
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 ((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_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_BYPASS_PWOFF) :
|
|
bpctl_cmd.status= get_bypass_pwoff_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(SET_BYPASS_PWUP) :
|
|
bpctl_cmd.status= set_bypass_pwup_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_BYPASS_PWUP) :
|
|
bpctl_cmd.status= get_bypass_pwup_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(SET_BYPASS_WD) :
|
|
bpctl_cmd.status= set_bypass_wd_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_BYPASS_WD) :
|
|
bpctl_cmd.status= get_bypass_wd_rd_fn(pbpctl_dev,(int *)&(bpctl_cmd.data[0]));
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_WD_EXPIRE_TIME) :
|
|
bpctl_cmd.status= get_wd_expire_time_rd_fn(pbpctl_dev, (int *)&(bpctl_cmd.data[0]));
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(RESET_BYPASS_WD_TIMER) :
|
|
bpctl_cmd.status= reset_bypass_wd_timer_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_WD_SET_CAPS) :
|
|
bpctl_cmd.status= get_wd_set_caps_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(SET_STD_NIC) :
|
|
bpctl_cmd.status= set_std_nic_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_STD_NIC) :
|
|
bpctl_cmd.status= get_std_nic_rd_fn(pbpctl_dev);
|
|
break;
|
|
#if 0
|
|
|
|
case IOCTL_TX_MSG(SET_TAP) :
|
|
bpctl_cmd.status= set_tap_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_TAP) :
|
|
bpctl_cmd.status= get_tap_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_TAP_CHANGE) :
|
|
bpctl_cmd.status= get_tap_change_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(SET_DIS_TAP) :
|
|
bpctl_cmd.status= set_dis_tap_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_DIS_TAP) :
|
|
bpctl_cmd.status= get_dis_tap_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(SET_TAP_PWUP) :
|
|
bpctl_cmd.status= set_tap_pwup_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_TAP_PWUP) :
|
|
bpctl_cmd.status= get_tap_pwup_rd_fn(pbpctl_dev);
|
|
break;
|
|
#endif
|
|
|
|
case IOCTL_TX_MSG(SET_WD_EXP_MODE):
|
|
bpctl_cmd.status= set_wd_exp_mode_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_WD_EXP_MODE):
|
|
bpctl_cmd.status= get_wd_exp_mode_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_DIS_BYPASS):
|
|
bpctl_cmd.status= get_dis_bypass_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(SET_DIS_BYPASS):
|
|
bpctl_cmd.status= set_dis_bypass_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_BYPASS_CHANGE):
|
|
bpctl_cmd.status= get_bypass_change_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_WD_EXPIRE):
|
|
bpctl_cmd.status= get_wd_expire_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_BYPASS):
|
|
bpctl_cmd.status= get_bypass_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(SET_BYPASS):
|
|
bpctl_cmd.status= set_bypass_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_BYPASS_CAPS):
|
|
bpctl_cmd.status= get_bypass_caps_rd_fn(pbpctl_dev);
|
|
if (copy_to_user(argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) {
|
|
ret= -EFAULT;
|
|
goto bp_exit;
|
|
}
|
|
goto bp_exit;
|
|
|
|
case IOCTL_TX_MSG(GET_BYPASS_SLAVE):
|
|
bpctl_cmd.status = get_bypass_slave_rd_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_rd_fn(pbpctl_dev);
|
|
break;
|
|
case IOCTL_TX_MSG(SET_TX):
|
|
bpctl_cmd.status= set_tx_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
case IOCTL_TX_MSG(GET_TX):
|
|
bpctl_cmd.status= get_tx_rd_fn(pbpctl_dev);
|
|
break;
|
|
case IOCTL_TX_MSG(SET_WD_AUTORESET):
|
|
bpctl_cmd.status= set_wd_autoreset_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
|
|
break;
|
|
case IOCTL_TX_MSG(GET_WD_AUTORESET):
|
|
|
|
bpctl_cmd.status= get_wd_autoreset_rd_fn(pbpctl_dev);
|
|
break;
|
|
case IOCTL_TX_MSG(SET_DISC) :
|
|
bpctl_cmd.status=set_disc_rd_fn(pbpctl_dev,bpctl_cmd.in_param[2]);
|
|
break;
|
|
case IOCTL_TX_MSG(GET_DISC) :
|
|
bpctl_cmd.status=get_disc_rd_fn(pbpctl_dev);
|
|
break;
|
|
case IOCTL_TX_MSG(GET_DISC_CHANGE) :
|
|
bpctl_cmd.status=get_disc_change_rd_fn(pbpctl_dev);
|
|
break;
|
|
case IOCTL_TX_MSG(SET_DIS_DISC) :
|
|
bpctl_cmd.status=set_dis_disc_rd_fn(pbpctl_dev,bpctl_cmd.in_param[2]);
|
|
break;
|
|
case IOCTL_TX_MSG(GET_DIS_DISC) :
|
|
bpctl_cmd.status=get_dis_disc_rd_fn(pbpctl_dev);
|
|
break;
|
|
case IOCTL_TX_MSG(SET_DISC_PWUP) :
|
|
bpctl_cmd.status=set_disc_pwup_rd_fn(pbpctl_dev,bpctl_cmd.in_param[2]);
|
|
break;
|
|
case IOCTL_TX_MSG(GET_DISC_PWUP) :
|
|
bpctl_cmd.status=get_disc_pwup_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_BYPASS_INFO):
|
|
|
|
bpctl_cmd.status= get_bypass_info_rd_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_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_TPL) :
|
|
bpctl_cmd.status= get_tpl_rd_fn(pbpctl_dev);
|
|
break;
|
|
//#ifdef PMC_FIX_FLAG
|
|
case IOCTL_TX_MSG(SET_BP_WAIT_AT_PWUP) :
|
|
bpctl_cmd.status= set_bp_wait_at_pwup_rd_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_rd_fn(pbpctl_dev);
|
|
break;
|
|
case IOCTL_TX_MSG(SET_BP_HW_RESET) :
|
|
bpctl_cmd.status= set_bp_hw_reset_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_BP_HW_RESET) :
|
|
bpctl_cmd.status= get_bp_hw_reset_rd_fn(pbpctl_dev);
|
|
break;
|
|
//#endif
|
|
#ifdef BP_SELF_TEST
|
|
case IOCTL_TX_MSG(SET_BP_SELF_TEST):
|
|
bpctl_cmd.status= set_bp_self_test_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
|
|
break;
|
|
case IOCTL_TX_MSG(GET_BP_SELF_TEST):
|
|
bpctl_cmd.status= get_bp_self_test_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
|
|
#endif
|
|
#if 0
|
|
case IOCTL_TX_MSG(SET_DISC_PORT) :
|
|
bpctl_cmd.status= set_disc_port_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_DISC_PORT) :
|
|
bpctl_cmd.status= get_disc_port_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(SET_DISC_PORT_PWUP) :
|
|
bpctl_cmd.status= set_disc_port_pwup_rd_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_DISC_PORT_PWUP) :
|
|
bpctl_cmd.status= get_disc_port_pwup_rd_fn(pbpctl_dev);
|
|
break;
|
|
#endif
|
|
case IOCTL_TX_MSG(SET_BP_FORCE_LINK):
|
|
bpctl_cmd.status= set_bp_force_link_rd_fn(dev_idx, bpctl_cmd.in_param[2]);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(GET_BP_FORCE_LINK):
|
|
bpctl_cmd.status= get_bp_force_link_rd_fn(dev_idx);
|
|
break;
|
|
|
|
case IOCTL_TX_MSG(SET_BP_MANUF) :
|
|
bpctl_cmd.status= set_bp_manuf_rd_fn(pbpctl_dev);
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
ret= -EOPNOTSUPP;
|
|
goto bp_exit;
|
|
}
|
|
bpcmd_exit:
|
|
if (copy_to_user(argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd)))
|
|
ret= -EFAULT;
|
|
ret= SUCCESS;
|
|
bp_exit:
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
|
|
#endif
|
|
unlock_bpctl();
|
|
return ret;
|
|
}
|
|
|
|
|
|
static struct file_operations Fops = {
|
|
.owner = THIS_MODULE,
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
|
|
.ioctl = device_ioctl,
|
|
#else
|
|
.unlocked_ioctl = device_ioctl,
|
|
#endif
|
|
|
|
.open = device_open,
|
|
.release = device_release, /* a.k.a. close */
|
|
};
|
|
|
|
|
|
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;
|
|
|
|
|
|
#define SILICOM_SVID 0x1374
|
|
|
|
static bpmod_info_t tx_ctl_pci_tbl[] = {
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01B0, 0, "PE310G4DBiR-T"},
|
|
{0x8086, 0x15A4, 0x1B2E, 0x01B0, 0, "PE310G4DBiR-T-RB2"},
|
|
|
|
{0x8086, 0x15A4, 0x8086, 0x000, 0, "PE310G4DBiR"},
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01B1, 0, "PE310G4DBiR-SRD"},
|
|
{0x8086, 0x15A4, 0x1B2E, 0x01B1, 0, "PE310G4DBiR-SRD-RB2"},
|
|
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01B2, 0, "PE310G4DBiR-LRD"},
|
|
{0x8086, 0x15A4, 0x1B2E, 0x01B2, 0, "PE310G4DBiR-LRD-RB2"},
|
|
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01B3, 0, "PE310G4DBiR-ERD"},
|
|
{0x8086, 0x15A4, 0x1B2E, 0x01B3, 0, "PE310G4DBiR-ERD-RB2"},
|
|
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01B4, 0, "PE310G4DBiR-DA"},
|
|
{0x8086, 0x15A4, 0x1B2E, 0x01B4, 0, "PE310G4DBiR-DA-RB2"},
|
|
|
|
|
|
|
|
{0x8086, 0x15A5, SILICOM_SVID, 0x01B0, 0, "PE310G4DBiR-T"},
|
|
{0x8086, 0x15A5, 0x1B2E, 0x01B0, 0, "PE310G4DBiR-T-RB2"},
|
|
|
|
{0x8086, 0x15A5, 0x8086, 0x000, 0, "PE310G4DBiR"},
|
|
{0x8086, 0x15A5, SILICOM_SVID, 0x01B1, 0, "PE310G4DBiR-SRD"},
|
|
{0x8086, 0x15A5, 0x1B2E, 0x01B1, 0, "PE310G4DBiR-SRD-RB2"},
|
|
|
|
{0x8086, 0x15A5, SILICOM_SVID, 0x01B2, 0, "PE310G4DBiR-LRD"},
|
|
{0x8086, 0x15A5, 0x1B2E, 0x01B2, 0, "PE310G4DBiR-LRD-RB2"},
|
|
|
|
{0x8086, 0x15A5, SILICOM_SVID, 0x01B3, 0, "PE310G4DBiR-ERD"},
|
|
{0x8086, 0x15A5, 0x1B2E, 0x01B3, 0, "PE310G4DBiR-ERD-RB2"},
|
|
|
|
{0x8086, 0x15A5, SILICOM_SVID, 0x01B4, 0, "PE310G4DBiR-DA"},
|
|
{0x8086, 0x15A5, 0x1B2E, 0x01B4, 0, "PE310G4DBiR-DA-RB2"},
|
|
|
|
|
|
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01B8, 0, "PE340G2DBIR-QS41"},
|
|
{0x8086, 0x15A4, 0x1B2E, 0x01B8, 0, "PE340G2DBIR-QS41-RB2"},
|
|
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01B9, 0, "PE340G2DBIR-QS43"},
|
|
{0x8086, 0x15A4, 0x1B2E, 0x01B9, 0, "PE340G2DBIR-QS43-RB2"},
|
|
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01BA, 0, "PE340G2DBIR-QL4"},
|
|
{0x8086, 0x15A4, 0x1B2E, 0x01BA, 0, "PE340G2DBIR-QL4-RB2"},
|
|
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01BC, 0, "PE3100G2DBIR-ZS4"},
|
|
{0x8086, 0x15A4, 0x1B2E, 0x01BC, 0, "PE3100G2DBIR-ZS4-RB2"},
|
|
|
|
#if 0
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01C0, 0, "PE3100G2DQIR-QX4/QS4/QL4"},
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01C1, 0, "PE3100G2DQIRL-QX4/QS4/QL4"},
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01C2, 0, "PE3100G2DQIRM-QX4/QS4/QL4"},
|
|
{0x8086, 0x15A4, SILICOM_SVID, 0x01C8, 0, "PE325G2DSIR"},
|
|
#endif
|
|
|
|
/* required last entry */
|
|
{0,}
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int v2_bypass_init_module(void)
|
|
{
|
|
int ret_val, idx, idx_dev = 0, idx_dev_mng = 0;
|
|
struct pci_dev *pdev1 = NULL;
|
|
unsigned long mmio_start, mmio_len;
|
|
|
|
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))) {
|
|
|
|
u32 __iomem *uc_addr;
|
|
|
|
if (tx_ctl_pci_tbl[idx].device == 0x15a4) {
|
|
|
|
uc_addr = ioremap(pci_resource_start(pdev1, 0),
|
|
FM10K_UC_ADDR_SIZE);
|
|
if (uc_addr) {
|
|
if (readl((void *)(uc_addr+0)) & 0x4) {
|
|
mng_device_num++;
|
|
}
|
|
if (!(DBI410_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice)))
|
|
device_num++;
|
|
}
|
|
}
|
|
else if (DBI410_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice)){
|
|
if ((PCI_FUNC(pdev1->devfn) == 1) ||
|
|
(PCI_FUNC(pdev1->devfn) == 2) ||
|
|
(PCI_FUNC(pdev1->devfn) == 3) ||
|
|
(PCI_FUNC(pdev1->devfn) == 4))
|
|
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);
|
|
bpctl_dev_mng_arr=kmalloc ((mng_device_num) * sizeof (bpctl_dev_mng_t), GFP_KERNEL);
|
|
|
|
if (!bpctl_dev_arr || (! bpctl_dev_mng_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;
|
|
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))) {
|
|
|
|
u32 __iomem *uc_addr;
|
|
mmio_start = 0;
|
|
mmio_len = 0;
|
|
|
|
if ((tx_ctl_pci_tbl[idx].device == 0x15a5) &&
|
|
(DBI410_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice))) {
|
|
|
|
if ((PCI_FUNC(pdev1->devfn) == 1) ||
|
|
(PCI_FUNC(pdev1->devfn) == 2) ||
|
|
(PCI_FUNC(pdev1->devfn) == 3) ||
|
|
(PCI_FUNC(pdev1->devfn) == 4)) {
|
|
bpctl_dev_arr[idx_dev].pdev=pdev1;
|
|
|
|
bpctl_dev_arr[idx_dev].name = tx_ctl_pci_tbl[idx].bp_name;
|
|
bpctl_dev_arr[idx_dev].device = tx_ctl_pci_tbl[idx].device;
|
|
bpctl_dev_arr[idx_dev].vendor = tx_ctl_pci_tbl[idx].vendor;
|
|
bpctl_dev_arr[idx_dev].subdevice = tx_ctl_pci_tbl[idx].subdevice;
|
|
bpctl_dev_arr[idx_dev].subvendor = tx_ctl_pci_tbl[idx].subvendor;
|
|
//ctl_dev_arr[idx_dev].pdev=pdev1;
|
|
bpctl_dev_arr[idx_dev].func = PCI_FUNC(pdev1->devfn);
|
|
bpctl_dev_arr[idx_dev].slot = PCI_SLOT(pdev1->devfn);
|
|
bpctl_dev_arr[idx_dev].bus = pdev1->bus->number;
|
|
bpctl_dev_arr[idx_dev].bp_master_flag =
|
|
(((bpctl_dev_arr[idx_dev].func == 1)||(bpctl_dev_arr[idx_dev].func == 3)) ? 1:0);
|
|
bpctl_dev_arr[idx_dev].epl_num = bpctl_dev_arr[idx_dev].func;
|
|
bpctl_dev_arr[idx_dev].lane_num = bpctl_dev_arr[idx_dev].func - 1;
|
|
bpctl_dev_arr[idx_dev].port_num = 49999 + bpctl_dev_arr[idx_dev].func;
|
|
bpctl_dev_arr[idx_dev].epl = 0;
|
|
idx_dev++;
|
|
}
|
|
}
|
|
else {
|
|
uc_addr = ioremap(pci_resource_start(pdev1, 0),
|
|
FM10K_UC_ADDR_SIZE);
|
|
|
|
|
|
if (uc_addr) {
|
|
if (readl((void *)(uc_addr+0)) & 0x4) {
|
|
mmio_start = pci_resource_start (pdev1, 4);
|
|
mmio_len = pci_resource_len (pdev1, 4);
|
|
if ((!mmio_len)||(!mmio_start))
|
|
continue;
|
|
bpctl_dev_mng_arr[idx_dev_mng].pdev=pdev1;
|
|
|
|
bpctl_dev_mng_arr[idx_dev_mng].name=tx_ctl_pci_tbl[idx].bp_name;
|
|
bpctl_dev_mng_arr[idx_dev_mng].device=tx_ctl_pci_tbl[idx].device;
|
|
bpctl_dev_mng_arr[idx_dev_mng].vendor=tx_ctl_pci_tbl[idx].vendor;
|
|
bpctl_dev_mng_arr[idx_dev_mng].subdevice=tx_ctl_pci_tbl[idx].subdevice;
|
|
bpctl_dev_mng_arr[idx_dev_mng].subvendor=tx_ctl_pci_tbl[idx].subvendor;
|
|
//ctl_dev_arr[idx_dev].pdev=pdev1;
|
|
bpctl_dev_mng_arr[idx_dev_mng].func= PCI_FUNC(pdev1->devfn);
|
|
bpctl_dev_mng_arr[idx_dev_mng].slot= PCI_SLOT(pdev1->devfn);
|
|
bpctl_dev_mng_arr[idx_dev_mng].bus=pdev1->bus->number;
|
|
bpctl_dev_mng_arr[idx_dev_mng].mem_map=(unsigned long)ioremap(mmio_start,mmio_len);
|
|
spin_lock_init(&bpctl_dev_mng_arr[idx_dev_mng].bypass_wr_lock);
|
|
if (DBI410_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice)) {
|
|
bpctl_dev_mng_arr[idx_dev_mng].port_num = 5;
|
|
}
|
|
else bpctl_dev_mng_arr[idx_dev_mng].port_num = 4;
|
|
mutex_init(&bpctl_dev_mng_arr[idx_dev_mng].i2c_bus_lock);
|
|
idx_dev_mng++;
|
|
}
|
|
}
|
|
if (!(DBI410_IF_SERIES(tx_ctl_pci_tbl[idx].subdevice))) {
|
|
bpctl_dev_arr[idx_dev].pdev=pdev1;
|
|
|
|
bpctl_dev_arr[idx_dev].name = tx_ctl_pci_tbl[idx].bp_name;
|
|
bpctl_dev_arr[idx_dev].device = tx_ctl_pci_tbl[idx].device;
|
|
bpctl_dev_arr[idx_dev].vendor = tx_ctl_pci_tbl[idx].vendor;
|
|
bpctl_dev_arr[idx_dev].subdevice = tx_ctl_pci_tbl[idx].subdevice;
|
|
bpctl_dev_arr[idx_dev].subvendor = tx_ctl_pci_tbl[idx].subvendor;
|
|
bpctl_dev_arr[idx_dev].func = PCI_FUNC(pdev1->devfn);
|
|
bpctl_dev_arr[idx_dev].slot = PCI_SLOT(pdev1->devfn);
|
|
bpctl_dev_arr[idx_dev].bus = pdev1->bus->number;
|
|
if (!mmio_start) {
|
|
bpctl_dev_arr[idx_dev].bp_master_flag = 1;
|
|
bpctl_dev_arr[idx_dev].epl_num = 1;
|
|
bpctl_dev_arr[idx_dev].port_num = 3;
|
|
bpctl_dev_arr[idx_dev].epl = 0;
|
|
}
|
|
else {
|
|
bpctl_dev_arr[idx_dev].epl_num = 2;
|
|
bpctl_dev_arr[idx_dev].port_num = 4;
|
|
bpctl_dev_arr[idx_dev].epl = 6;
|
|
}
|
|
bpctl_dev_arr[idx_dev].lane_num = 0;
|
|
idx_dev++;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
if_scan_init();
|
|
if_scan_mng_init();
|
|
|
|
sema_init (&bpctl_sema, 1);
|
|
|
|
|
|
|
|
{
|
|
|
|
for (idx_dev = 0; ((bpctl_dev_arr[idx_dev].pdev!=NULL)&&(idx_dev<device_num)); idx_dev++)
|
|
{
|
|
{
|
|
bpctl_dev_mng_t *pbpctl_dev_c = NULL;
|
|
struct pci_dev *pdev_mng = NULL;
|
|
struct pci_dev *pdev_slave = NULL;
|
|
|
|
if (!DBI410_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)) {
|
|
rdi_find_master_slave_plx(bpctl_dev_arr[idx_dev].pdev,
|
|
&pdev_mng,
|
|
&pdev_slave);
|
|
bpctl_dev_arr[idx_dev].pdev_mng = pdev_mng;
|
|
/* for 420 chip */
|
|
bpctl_dev_arr[idx_dev].pdev_pf_slave = pdev_mng;
|
|
bpctl_dev_arr[idx_dev].pdev_pf_master = pdev_slave;
|
|
}
|
|
pbpctl_dev_c = get_mng_port_rd_fn(&bpctl_dev_arr[idx_dev]);
|
|
bpctl_dev_arr[idx_dev].pbpctl_dev_c = pbpctl_dev_c;
|
|
|
|
if ((!bpctl_dev_arr[idx_dev].pdev_mng) && (pbpctl_dev_c))
|
|
bpctl_dev_arr[idx_dev].pdev_mng = pbpctl_dev_c->pdev;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_bypass_rd_fn(&bpctl_dev_arr[idx_dev])) {
|
|
printk(KERN_INFO "%s found, ", bpctl_dev_arr[idx_dev].name);
|
|
bpctl_dev_arr[idx_dev].bp_fw_ver=bypass_fw_ver_rd(&bpctl_dev_arr[idx_dev]);
|
|
|
|
//bpctl_dev_arr[idx_dev].bp_fw_ver=0xa8;
|
|
printk("firmware version: 0x%x\n",bpctl_dev_arr[idx_dev].bp_fw_ver);
|
|
}
|
|
bpctl_dev_arr[idx_dev].wdt_status=WDT_STATUS_UNKNOWN;
|
|
bpctl_dev_arr[idx_dev].reset_time=0;
|
|
atomic_set(&bpctl_dev_arr[idx_dev].wdt_busy,0);
|
|
bpctl_dev_arr[idx_dev].bp_status_un=1;
|
|
|
|
bpctl_dev_arr[idx_dev].bp_caps = get_bypass_caps_rd_fn(&bpctl_dev_arr[idx_dev]);
|
|
|
|
get_tpl_rd_fn(&bpctl_dev_arr[idx_dev]);
|
|
init_bypass_wd_auto(&bpctl_dev_arr[idx_dev]);
|
|
if ((is_bypass_rd_fn(&bpctl_dev_arr[idx_dev])) &&
|
|
(DBI240_IF_SERIES(bpctl_dev_arr[idx_dev].subdevice)))
|
|
init_bypass_tpl_auto(&bpctl_dev_arr[idx_dev]);
|
|
}
|
|
}
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
|
|
inter_module_register("is_bypass_rd", THIS_MODULE, &is_bypass_rd);
|
|
inter_module_register("get_bypass_slave_rd", THIS_MODULE, &get_bypass_slave_rd);
|
|
inter_module_register("get_bypass_caps_rd", THIS_MODULE, &get_bypass_caps_rd);
|
|
inter_module_register("get_wd_set_caps_rd", THIS_MODULE, &get_wd_set_caps_rd);
|
|
inter_module_register("set_bypass_rd", THIS_MODULE, &set_bypass_rd);
|
|
inter_module_register("get_bypass_rd", THIS_MODULE, &get_bypass_rd);
|
|
inter_module_register("get_bypass_change_rd", THIS_MODULE, &get_bypass_change_rd);
|
|
inter_module_register("set_dis_bypass_rd", THIS_MODULE, &set_dis_bypass_rd);
|
|
inter_module_register("get_dis_bypass_rd", THIS_MODULE, &get_dis_bypass_rd);
|
|
inter_module_register("set_bypass_pwoff_rd", THIS_MODULE, &set_bypass_pwoff_rd);
|
|
inter_module_register("get_bypass_pwoff_rd", THIS_MODULE, &get_bypass_pwoff_rd);
|
|
inter_module_register("set_bypass_pwup_rd", THIS_MODULE, &set_bypass_pwup_rd);
|
|
inter_module_register("get_bypass_pwup_rd", THIS_MODULE, &get_bypass_pwup_rd);
|
|
inter_module_register("get_bypass_wd_rd", THIS_MODULE, &get_bypass_wd_rd);
|
|
inter_module_register("set_bypass_wd_rd", THIS_MODULE, &set_bypass_wd_rd);
|
|
inter_module_register("get_wd_expire_time_rd", THIS_MODULE, &get_wd_expire_time_rd);
|
|
inter_module_register("reset_bypass_wd_timer_rd", THIS_MODULE, &reset_bypass_wd_timer_rd);
|
|
inter_module_register("set_std_nic_rd", THIS_MODULE, &set_std_nic_rd);
|
|
inter_module_register("get_std_nic_rd", THIS_MODULE, &get_std_nic_rd);
|
|
inter_module_register("set_tx_rd", THIS_MODULE, &set_tx_rd);
|
|
inter_module_register("get_tx_rd", THIS_MODULE, &get_tx_rd);
|
|
inter_module_register("set_tpl_rd", THIS_MODULE, &set_tpl_rd);
|
|
inter_module_register("get_tpl_rd", THIS_MODULE, &get_tpl_rd);
|
|
|
|
inter_module_register("set_bp_hw_reset_rd", THIS_MODULE, &set_bp_hw_reset_rd);
|
|
inter_module_register("get_bp_hw_reset_rd", THIS_MODULE, &get_bp_hw_reset_rd);
|
|
#if 0
|
|
inter_module_register("set_tap_rd", THIS_MODULE, &set_tap_rd);
|
|
inter_module_register("get_tap_rd", THIS_MODULE, &get_tap_rd);
|
|
inter_module_register("get_tap_change_rd", THIS_MODULE, &get_tap_change_rd);
|
|
inter_module_register("set_dis_tap_rd", THIS_MODULE, &set_dis_tap_rd);
|
|
inter_module_register("get_dis_tap_rd", THIS_MODULE, &get_dis_tap_rd);
|
|
inter_module_register("set_tap_pwup_rd", THIS_MODULE, &set_tap_pwup_rd);
|
|
inter_module_register("get_tap_pwup_rd", THIS_MODULE, &get_tap_pwup_rd);
|
|
#endif
|
|
inter_module_register("set_bp_disc_rd", THIS_MODULE, &set_bp_disc_rd);
|
|
inter_module_register("get_bp_disc_rd", THIS_MODULE, &get_bp_disc_rd);
|
|
inter_module_register("get_bp_disc_change_rd", THIS_MODULE, &get_bp_disc_change_rd);
|
|
inter_module_register("set_bp_dis_disc_rd", THIS_MODULE, &set_bp_dis_disc_rd);
|
|
inter_module_register("get_bp_dis_disc_rd", THIS_MODULE, &get_bp_dis_disc_rd);
|
|
inter_module_register("set_bp_disc_pwup_rd", THIS_MODULE, &set_bp_disc_pwup_rd);
|
|
inter_module_register("get_bp_disc_pwup_rd", THIS_MODULE, &get_bp_disc_pwup_rd);
|
|
inter_module_register("set_wd_exp_mode_rd", THIS_MODULE, &set_wd_exp_mode_rd);
|
|
inter_module_register("get_wd_exp_mode_rd", THIS_MODULE, &get_wd_exp_mode_rd);
|
|
inter_module_register("set_wd_autoreset_rd", THIS_MODULE, &set_wd_autoreset_rd);
|
|
inter_module_register("get_wd_autoreset_rd", THIS_MODULE, &get_wd_autoreset_rd);
|
|
inter_module_register("get_bypass_info_rd", THIS_MODULE, &get_bypass_info_rd);
|
|
inter_module_register("bp_if_scan_rd", THIS_MODULE, &bp_if_scan_rd);
|
|
|
|
#endif
|
|
|
|
register_netdevice_notifier(&bp_notifier_block);
|
|
register_reboot_notifier(&bp_reboot_block);
|
|
#ifdef BP_PROC_SUPPORT
|
|
{
|
|
int i=0;
|
|
bp_proc_create();
|
|
for (i = 0; i < device_num; i++) {
|
|
if (bpctl_dev_arr[i].ifindex) {
|
|
bypass_proc_remove_dev_rd(&bpctl_dev_arr[i]);
|
|
bypass_proc_create_dev_rd(&bpctl_dev_arr[i]);
|
|
}
|
|
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static void __exit bypass_cleanup_module(void)
|
|
{
|
|
int i ;
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23))
|
|
int ret;
|
|
#endif
|
|
unregister_netdevice_notifier(&bp_notifier_block);
|
|
unregister_reboot_notifier(&bp_reboot_block);
|
|
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
|
|
inter_module_unregister("is_bypass_rd");
|
|
inter_module_unregister("get_bypass_slave_rd");
|
|
inter_module_unregister("get_bypass_caps_rd");
|
|
inter_module_unregister("get_wd_set_caps_rd");
|
|
inter_module_unregister("set_bypass_rd");
|
|
inter_module_unregister("get_bypass_rd");
|
|
inter_module_unregister("get_bypass_change_rd");
|
|
inter_module_unregister("set_dis_bypass_rd");
|
|
inter_module_unregister("get_dis_bypass_rd");
|
|
inter_module_unregister("set_bypass_pwoff_rd");
|
|
inter_module_unregister("get_bypass_pwoff_rd");
|
|
inter_module_unregister("set_bypass_pwup_rd");
|
|
inter_module_unregister("get_bypass_pwup_rd");
|
|
inter_module_unregister("set_bypass_wd_rd");
|
|
inter_module_unregister("get_bypass_wd_rd");
|
|
inter_module_unregister("get_wd_expire_time_rd");
|
|
inter_module_unregister("reset_bypass_wd_timer_rd");
|
|
inter_module_unregister("set_std_nic_rd");
|
|
inter_module_unregister("get_std_nic_rd");
|
|
inter_module_unregister("set_tx_rd");
|
|
inter_module_unregister("get_tx_rd");
|
|
inter_module_unregister("set_tpl_rd");
|
|
inter_module_unregister("get_tpl_rd");
|
|
#if 0
|
|
inter_module_unregister("set_tap_rd");
|
|
inter_module_unregister("get_tap_rd");
|
|
inter_module_unregister("get_tap_change_rd");
|
|
inter_module_unregister("set_dis_tap_rd");
|
|
inter_module_unregister("get_dis_tap_rd");
|
|
inter_module_unregister("set_tap_pwup_rd");
|
|
inter_module_unregister("get_tap_pwup_rd");
|
|
#endif
|
|
inter_module_unregister("set_bp_disc_rd");
|
|
inter_module_unregister("get_bp_disc_rd");
|
|
inter_module_unregister("get_bp_disc_change_rd");
|
|
inter_module_unregister("set_bp_dis_disc_rd");
|
|
inter_module_unregister("get_bp_dis_disc_rd");
|
|
inter_module_unregister("set_bp_disc_pwup_rd");
|
|
inter_module_unregister("get_bp_disc_pwup_rd");
|
|
inter_module_unregister("set_wd_exp_mode_rd");
|
|
inter_module_unregister("get_wd_exp_mode_rd");
|
|
inter_module_unregister("set_wd_autoreset_rd");
|
|
inter_module_unregister("get_wd_autoreset_rd");
|
|
inter_module_unregister("get_bypass_info_rd");
|
|
inter_module_unregister("bp_if_scan_rd");
|
|
|
|
#endif
|
|
|
|
for (i = 0; i < device_num; i++) {
|
|
//unsigned long flags;
|
|
#ifdef BP_PROC_SUPPORT
|
|
bypass_proc_remove_dev_rd(&bpctl_dev_arr[i]);
|
|
#endif
|
|
remove_bypass_wd_auto(&bpctl_dev_arr[i]);
|
|
bpctl_dev_arr[i].reset_time=0;
|
|
remove_bypass_tpl_auto(&bpctl_dev_arr[i]);
|
|
}
|
|
#ifdef BP_PROC_SUPPORT
|
|
remove_proc_entry(BP_PROC_DIR, init_net.proc_net);
|
|
#endif
|
|
|
|
|
|
/* unmap all devices */
|
|
for (i = 0; i < device_num; i++) {
|
|
#ifdef BP_SELF_TEST
|
|
if (bpctl_dev_arr[i].bp_tx_data)
|
|
kfree (bpctl_dev_arr[i].bp_tx_data);
|
|
#endif
|
|
iounmap ((void *)(bpctl_dev_arr[i].mem_map));
|
|
}
|
|
|
|
/* free all devices space */
|
|
if (bpctl_dev_arr)
|
|
kfree (bpctl_dev_arr);
|
|
|
|
|
|
|
|
/*
|
|
* Unregister the device
|
|
*/
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23))
|
|
ret = unregister_chrdev(major_num, DEVICE_NAME);
|
|
/*
|
|
* If there's an error, report it
|
|
*/
|
|
if (ret < 0)
|
|
printk("Error in module_unregister_chrdev: %d\n", ret);
|
|
#else
|
|
unregister_chrdev(major_num, DEVICE_NAME);
|
|
|
|
#endif
|
|
}
|
|
|
|
|
|
static int __init bprd_init_module(void)
|
|
{
|
|
int ret;
|
|
|
|
printk(KERN_INFO BP_MOD_DESCR" v"BP_MOD_VER"\n");
|
|
|
|
ret=v2_bypass_init_module();
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
static void __exit bprd_exit_module(void)
|
|
{
|
|
/* pci_unregister_driver(&bpvm_driver); */
|
|
bypass_cleanup_module();
|
|
#ifdef BPVM_KVM
|
|
unregister_netdev(netdev);
|
|
free_netdev(netdev);
|
|
#endif /* BPVM_KVM */
|
|
|
|
}
|
|
|
|
module_exit(bprd_exit_module);
|
|
module_init(bprd_init_module);
|
|
|
|
int is_bypass_rd(int ifindex){
|
|
return(is_bypass_rd_fn(get_dev_idx_p(ifindex)));
|
|
}
|
|
|
|
int set_bypass_rd (int ifindex, int bypass_mode){
|
|
|
|
return(set_bypass_rd_fn(get_dev_idx_p(ifindex),bypass_mode));
|
|
}
|
|
|
|
|
|
int get_bypass_rd (int ifindex){
|
|
|
|
return(get_bypass_rd_fn(get_dev_idx_p(ifindex)));
|
|
}
|
|
|
|
int get_wd_expire_rd (int ifindex){
|
|
|
|
return(get_wd_expire_rd_fn(get_dev_idx_p(ifindex)));
|
|
}
|
|
|
|
|
|
int get_bypass_change_rd(int ifindex){
|
|
|
|
return(get_bypass_change_rd_fn(get_dev_idx_p(ifindex)));
|
|
}
|
|
|
|
int set_dis_bypass_rd(int ifindex, int dis_param){
|
|
return(set_dis_bypass_rd_fn(get_dev_idx_p(ifindex),dis_param));
|
|
}
|
|
|
|
int get_dis_bypass_rd(int ifindex){
|
|
|
|
return(get_dis_bypass_rd_fn(get_dev_idx_p(ifindex)));
|
|
}
|
|
|
|
int set_bypass_pwoff_rd (int ifindex, int bypass_mode){
|
|
return(set_bypass_pwoff_rd_fn(get_dev_idx_p(ifindex),bypass_mode));
|
|
|
|
}
|
|
|
|
|
|
int get_bypass_pwoff_rd(int ifindex){
|
|
return(get_bypass_pwoff_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
|
|
int set_bypass_pwup_rd(int ifindex, int bypass_mode){
|
|
return(set_bypass_pwup_rd_fn(get_dev_idx_p(ifindex),bypass_mode));
|
|
|
|
}
|
|
|
|
int get_bypass_pwup_rd(int ifindex){
|
|
return(get_bypass_pwup_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int set_bypass_wd_rd(int if_index, int ms_timeout, int *ms_timeout_set){
|
|
if ((is_bypass_rd_fn(get_dev_idx_p(if_index)))<=0)
|
|
return BP_NOT_CAP;
|
|
*ms_timeout_set= set_bypass_wd_rd_fn(get_dev_idx_p(if_index),ms_timeout);
|
|
return 0;
|
|
}
|
|
|
|
int get_bypass_wd_rd(int ifindex, int *timeout){
|
|
return(get_bypass_wd_rd_fn(get_dev_idx_p(ifindex),timeout));
|
|
|
|
}
|
|
|
|
int get_wd_expire_time_rd(int ifindex, int *time_left){
|
|
return(get_wd_expire_time_rd_fn(get_dev_idx_p(ifindex),time_left));
|
|
}
|
|
|
|
int reset_bypass_wd_timer_rd(int ifindex){
|
|
return(reset_bypass_wd_timer_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int get_wd_set_caps_rd(int ifindex){
|
|
return(get_wd_set_caps_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int set_std_nic_rd(int ifindex, int nic_mode){
|
|
return(set_std_nic_rd_fn(get_dev_idx_p(ifindex),nic_mode));
|
|
|
|
}
|
|
|
|
int get_std_nic_rd(int ifindex){
|
|
return(get_std_nic_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
#if 0
|
|
int set_tap_rd (int ifindex, int tap_mode){
|
|
return(set_tap_rd_fn(get_dev_idx_p(ifindex),tap_mode));
|
|
|
|
}
|
|
|
|
int get_tap_rd (int ifindex){
|
|
return(get_tap_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int set_tap_pwup_rd(int ifindex, int tap_mode){
|
|
return(set_tap_pwup_rd_fn(get_dev_idx_p(ifindex),tap_mode));
|
|
|
|
}
|
|
|
|
int get_tap_pwup_rd(int ifindex){
|
|
return(get_tap_pwup_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int get_tap_change_rd(int ifindex){
|
|
return(get_tap_change_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int set_dis_tap_rd(int ifindex, int dis_param){
|
|
return(set_dis_tap_rd_fn(get_dev_idx_p(ifindex),dis_param));
|
|
|
|
}
|
|
|
|
int get_dis_tap_rd(int ifindex){
|
|
return(get_dis_tap_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
#endif
|
|
int set_bp_disc_rd (int ifindex, int disc_mode){
|
|
return(set_disc_rd_fn(get_dev_idx_p(ifindex),disc_mode));
|
|
|
|
}
|
|
|
|
int get_bp_disc_rd (int ifindex){
|
|
return(get_disc_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int set_bp_disc_pwup_rd(int ifindex, int disc_mode){
|
|
return(set_disc_pwup_rd_fn(get_dev_idx_p(ifindex),disc_mode));
|
|
|
|
}
|
|
|
|
int get_bp_disc_pwup_rd(int ifindex){
|
|
return(get_disc_pwup_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int get_bp_disc_change_rd(int ifindex){
|
|
return(get_disc_change_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int set_bp_dis_disc_rd(int ifindex, int dis_param){
|
|
return(set_dis_disc_rd_fn(get_dev_idx_p(ifindex),dis_param));
|
|
|
|
}
|
|
|
|
int get_bp_dis_disc_rd(int ifindex){
|
|
return(get_dis_disc_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int get_wd_exp_mode_rd(int ifindex){
|
|
return(get_wd_exp_mode_rd_fn(get_dev_idx_p(ifindex)));
|
|
}
|
|
|
|
int set_wd_exp_mode_rd(int ifindex, int param){
|
|
return(set_wd_exp_mode_rd_fn(get_dev_idx_p(ifindex),param));
|
|
|
|
}
|
|
|
|
int set_tx_rd(int ifindex, int tx_state){
|
|
return(set_tx_rd_fn(get_dev_idx_p(ifindex), tx_state));
|
|
|
|
}
|
|
|
|
int set_tpl_rd(int ifindex, int tpl_state){
|
|
return(set_tpl_rd_fn(get_dev_idx_p(ifindex), tpl_state));
|
|
|
|
}
|
|
|
|
int set_bp_hw_reset_rd(int ifindex, int status){
|
|
return(set_bp_hw_reset_rd_fn(get_dev_idx_p(ifindex), status));
|
|
|
|
}
|
|
|
|
|
|
int set_wd_autoreset_rd(int ifindex, int param){
|
|
return(set_wd_autoreset_rd_fn(get_dev_idx_p(ifindex),param));
|
|
|
|
}
|
|
|
|
int get_wd_autoreset_rd(int ifindex){
|
|
return(get_wd_autoreset_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
|
|
int get_bypass_caps_rd(int ifindex){
|
|
return(get_bypass_caps_rd_fn(get_dev_idx_p(ifindex)));
|
|
}
|
|
|
|
int get_bypass_slave_rd(int ifindex){
|
|
bpctl_dev_t *pbpctl_dev_out;
|
|
int ret=get_bypass_slave_rd_fn(get_dev_idx_p(ifindex), &pbpctl_dev_out);
|
|
if (ret==1)
|
|
return(pbpctl_dev_out->ifindex) ;
|
|
return -1;
|
|
|
|
}
|
|
|
|
int get_tx_rd(int ifindex){
|
|
return(get_tx_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int get_tpl_rd(int ifindex){
|
|
return(get_tpl_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
int get_bp_hw_reset_rd(int ifindex){
|
|
return(get_bp_hw_reset_rd_fn(get_dev_idx_p(ifindex)));
|
|
|
|
}
|
|
|
|
|
|
int get_bypass_info_rd(int ifindex, struct bp_info *bp_info) {
|
|
return(get_bypass_info_rd_fn(get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver));
|
|
}
|
|
|
|
int bp_if_scan_rd(void) {
|
|
if_scan_init();
|
|
return 0;
|
|
}
|
|
|
|
|
|
EXPORT_SYMBOL_NOVERS(is_bypass_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bypass_slave_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bypass_caps_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_wd_set_caps_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_bypass_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bypass_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bypass_change_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_dis_bypass_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_dis_bypass_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_bypass_pwoff_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bypass_pwoff_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_bypass_pwup_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bypass_pwup_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_bypass_wd_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bypass_wd_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_wd_expire_time_rd);
|
|
EXPORT_SYMBOL_NOVERS(reset_bypass_wd_timer_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_std_nic_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_std_nic_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_tx_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_tx_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_tpl_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_tpl_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_bp_hw_reset_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bp_hw_reset_rd);
|
|
#if 0
|
|
EXPORT_SYMBOL_NOVERS(set_tap_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_tap_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_tap_change_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_dis_tap_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_dis_tap_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_tap_pwup_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_tap_pwup_rd);
|
|
#endif
|
|
EXPORT_SYMBOL_NOVERS(set_wd_exp_mode_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_wd_exp_mode_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_wd_autoreset_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_wd_autoreset_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_bp_disc_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bp_disc_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bp_disc_change_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_bp_dis_disc_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bp_dis_disc_rd);
|
|
EXPORT_SYMBOL_NOVERS(set_bp_disc_pwup_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bp_disc_pwup_rd);
|
|
EXPORT_SYMBOL_NOVERS(get_bypass_info_rd);
|
|
EXPORT_SYMBOL_NOVERS(bp_if_scan_rd);
|
|
|
|
#ifdef BP_PROC_SUPPORT
|
|
|
|
static struct proc_dir_entry *bp_procfs_dir;
|
|
|
|
static struct proc_dir_entry *
|
|
proc_getdir(char *name, struct proc_dir_entry *proc_dir) {
|
|
struct proc_dir_entry *pde = proc_dir;
|
|
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) )
|
|
|
|
for (pde=pde->subdir; pde; pde = pde->next) {
|
|
if (pde->namelen && (strcmp(name, pde->name) == 0)) {
|
|
/* directory exists */
|
|
break;
|
|
}
|
|
}
|
|
if (pde == (struct proc_dir_entry *) 0)
|
|
#endif
|
|
{
|
|
/* create the directory */
|
|
#if (LINUX_VERSION_CODE > 0x20300)
|
|
pde = proc_mkdir(name, proc_dir);
|
|
#else
|
|
pde = create_proc_entry(name, S_IFDIR, proc_dir);
|
|
#endif
|
|
if (pde == (struct proc_dir_entry *) 0) {
|
|
|
|
return(pde);
|
|
}
|
|
}
|
|
|
|
return(pde);
|
|
}
|
|
|
|
int bp_proc_create(void)
|
|
{
|
|
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) )
|
|
bp_procfs_dir = proc_getdir(BP_PROC_DIR, proc_net);
|
|
#else
|
|
bp_procfs_dir = proc_getdir(BP_PROC_DIR, init_net.proc_net);
|
|
#endif
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) )
|
|
|
|
int
|
|
bypass_proc_create_entry_rd(struct pfs_unit_rd *pfs_unit_curr,
|
|
char* proc_name,
|
|
write_proc_t *write_proc,
|
|
read_proc_t *read_proc,
|
|
struct proc_dir_entry *parent_pfs,
|
|
void *data
|
|
)
|
|
{
|
|
strcpy(pfs_unit_curr->proc_name,proc_name);
|
|
pfs_unit_curr->proc_entry= create_proc_entry(pfs_unit_curr->proc_name,
|
|
S_IFREG|S_IRUSR|S_IWUSR|
|
|
S_IRGRP|S_IWGRP|
|
|
S_IROTH|S_IWOTH, parent_pfs);
|
|
if (pfs_unit_curr->proc_entry == 0) {
|
|
|
|
return -1;
|
|
}
|
|
|
|
pfs_unit_curr->proc_entry->read_proc = read_proc;
|
|
pfs_unit_curr->proc_entry->write_proc = write_proc;
|
|
pfs_unit_curr->proc_entry->data = data;
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
int
|
|
get_bypass_info_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
int len=0;
|
|
|
|
len += sprintf(page, "Name\t\t\t%s\n", pbp_device_block->name);
|
|
len += sprintf(page+len, "Firmware version\t0x%x\n", pbp_device_block->bp_fw_ver);
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
int
|
|
get_bypass_slave_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * dev= (bpctl_dev_t *) data;
|
|
|
|
int len=0;
|
|
|
|
bpctl_dev_t *slave = get_status_port_rd_fn(dev);
|
|
if (!slave)
|
|
slave = dev;
|
|
if (slave) {
|
|
if (slave->ndev)
|
|
len = sprintf(page, "%s\n", slave->ndev->name);
|
|
else
|
|
len=sprintf(page, "fail\n");
|
|
}
|
|
|
|
*eof = 1;
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
get_bypass_caps_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_bypass_caps_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "-1\n");
|
|
else
|
|
len=sprintf(page, "0x%x\n", ret);
|
|
*eof = 1;
|
|
return len;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
get_wd_set_caps_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_wd_set_caps_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "-1\n");
|
|
else
|
|
len=sprintf(page, "0x%x\n", ret);
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
set_bypass_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
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,"on")==0)
|
|
bypass_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
bypass_param=0;
|
|
|
|
|
|
set_bypass_rd_fn (pbp_device_block, bypass_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
int
|
|
set_tap_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int tap_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,"on")==0)
|
|
tap_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
tap_param=0;
|
|
|
|
set_tap_rd_fn(pbp_device_block, tap_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
set_disc_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int tap_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,"on")==0)
|
|
tap_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
tap_param=0;
|
|
|
|
set_disc_rd_fn(pbp_device_block, tap_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
get_bypass_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_bypass_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==1)
|
|
len=sprintf(page, "on\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
int
|
|
get_tap_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_tap_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==1)
|
|
len=sprintf(page, "on\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
int
|
|
get_disc_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_disc_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==1)
|
|
len=sprintf(page, "on\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
int
|
|
get_bypass_change_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_bypass_change_rd_fn (pbp_device_block);
|
|
if (ret==1)
|
|
len=sprintf(page, "on\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
else len=sprintf(page, "fail\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
get_tap_change_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_tap_change_rd_fn (pbp_device_block);
|
|
if (ret==1)
|
|
len=sprintf(page, "on\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
else len=sprintf(page, "fail\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
get_disc_change_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_disc_change_rd_fn (pbp_device_block);
|
|
if (ret==1)
|
|
len=sprintf(page, "on\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
else len=sprintf(page, "fail\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
|
|
#define isdigit(c) (c >= '0' && c <= '9')
|
|
__inline static int atoi( char **s)
|
|
{
|
|
int i = 0;
|
|
while (isdigit(**s))
|
|
i = i*10 + *((*s)++) - '0';
|
|
return i;
|
|
}
|
|
|
|
|
|
int
|
|
set_bypass_wd_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
unsigned int timeout=0;
|
|
char *timeout_ptr=kbuf;
|
|
|
|
if (count>(sizeof(kbuf)-1))
|
|
return -1;
|
|
|
|
if (copy_from_user(&kbuf,buffer,count)) {
|
|
return -1;
|
|
}
|
|
|
|
timeout_ptr=kbuf;
|
|
timeout=atoi(&timeout_ptr);
|
|
|
|
set_bypass_wd_rd_fn(pbp_device_block, timeout) ;
|
|
|
|
return count;
|
|
}
|
|
|
|
int
|
|
get_bypass_wd_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0, timeout=0;
|
|
|
|
ret=get_bypass_wd_rd_fn (pbp_device_block, &timeout);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (timeout==-1)
|
|
len=sprintf(page, "unknown\n");
|
|
else if (timeout==0)
|
|
len=sprintf(page, "disable\n");
|
|
else
|
|
len=sprintf(page, "%d\n", timeout);
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
get_wd_expire_time_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0, timeout=0;
|
|
|
|
ret=get_wd_expire_time_rd_fn (pbp_device_block, &timeout);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (timeout==-1)
|
|
len=sprintf(page, "expire\n");
|
|
else if (timeout==0)
|
|
len=sprintf(page, "disable\n");
|
|
|
|
else
|
|
len=sprintf(page, "%d\n", timeout);
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
get_tpl_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_tpl_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==1)
|
|
len=sprintf(page, "on\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
#ifdef PMC_FIX_FLAG
|
|
int
|
|
get_wait_at_pwup_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_bp_wait_at_pwup_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==1)
|
|
len=sprintf(page, "on\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
get_hw_reset_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_bp_hw_reset_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==1)
|
|
len=sprintf(page, "on\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /*PMC_WAIT_FLAG*/
|
|
|
|
|
|
int
|
|
reset_bypass_wd_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=reset_bypass_wd_timer_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "disable\n");
|
|
else if (ret==1)
|
|
len=sprintf(page, "success\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
set_dis_bypass_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
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,"on")==0)
|
|
bypass_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
bypass_param=0;
|
|
|
|
set_dis_bypass_rd_fn (pbp_device_block, bypass_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
set_dis_tap_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int tap_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,"on")==0)
|
|
tap_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
tap_param=0;
|
|
|
|
set_dis_tap_rd_fn (pbp_device_block, tap_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
set_dis_disc_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int tap_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,"on")==0)
|
|
tap_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
tap_param=0;
|
|
|
|
set_dis_disc_rd_fn (pbp_device_block, tap_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
get_dis_bypass_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_dis_bypass_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
else
|
|
len=sprintf(page, "on\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
int
|
|
get_dis_tap_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_dis_tap_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
else
|
|
len=sprintf(page, "on\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
int
|
|
get_dis_disc_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_dis_disc_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
else
|
|
len=sprintf(page, "on\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
int
|
|
set_bypass_pwup_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
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,"on")==0)
|
|
bypass_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
bypass_param=0;
|
|
|
|
set_bypass_pwup_rd_fn (pbp_device_block, bypass_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
int
|
|
set_bypass_pwoff_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
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,"on")==0)
|
|
bypass_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
bypass_param=0;
|
|
|
|
set_bypass_pwoff_rd_fn (pbp_device_block, bypass_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
set_tap_pwup_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int tap_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,"on")==0)
|
|
tap_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
tap_param=0;
|
|
|
|
set_tap_pwup_rd_fn (pbp_device_block, tap_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
set_disc_pwup_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int tap_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,"on")==0)
|
|
tap_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
tap_param=0;
|
|
|
|
set_disc_pwup_rd_fn (pbp_device_block, tap_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
get_bypass_pwup_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_bypass_pwup_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
else
|
|
len=sprintf(page, "on\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
get_bypass_pwoff_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_bypass_pwoff_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
else
|
|
len=sprintf(page, "on\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
int
|
|
get_tap_pwup_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_tap_pwup_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
else
|
|
len=sprintf(page, "on\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
int
|
|
get_disc_pwup_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_disc_pwup_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
else
|
|
len=sprintf(page, "on\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
set_std_nic_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
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,"on")==0)
|
|
bypass_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
bypass_param=0;
|
|
|
|
set_std_nic_rd_fn (pbp_device_block, bypass_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
int
|
|
get_std_nic_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_std_nic_rd_fn (pbp_device_block);
|
|
if (ret==BP_NOT_CAP)
|
|
len=sprintf(page, "fail\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "off\n");
|
|
else
|
|
len=sprintf(page, "on\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
int
|
|
get_wd_exp_mode_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_wd_exp_mode_rd_fn (pbp_device_block);
|
|
if (ret==1)
|
|
len=sprintf(page, "tap\n");
|
|
else if (ret==0)
|
|
len=sprintf(page, "bypass\n");
|
|
else if (ret==2)
|
|
len=sprintf(page, "disc\n");
|
|
|
|
else len=sprintf(page, "fail\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
int
|
|
set_wd_exp_mode_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
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_rd_fn(pbp_device_block, bypass_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
get_wd_autoreset_pfs (char *page, char **start, off_t off, int count,
|
|
int *eof, void *data)
|
|
{
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int len=0, ret=0;
|
|
|
|
ret=get_wd_autoreset_rd_fn (pbp_device_block);
|
|
if (ret>=0)
|
|
len=sprintf(page, "%d\n",ret);
|
|
else len=sprintf(page, "fail\n");
|
|
|
|
*eof = 1;
|
|
return len;
|
|
}
|
|
|
|
|
|
int
|
|
set_wd_autoreset_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
u32 timeout=0;
|
|
char *timeout_ptr=kbuf;
|
|
|
|
if (count>(sizeof(kbuf)-1))
|
|
return -1;
|
|
|
|
if (copy_from_user(&kbuf,buffer,count)) {
|
|
return -1;
|
|
}
|
|
|
|
timeout_ptr=kbuf;
|
|
timeout=atoi(&timeout_ptr);
|
|
|
|
set_wd_autoreset_rd_fn(pbp_device_block, timeout) ;
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
int
|
|
set_tpl_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int tpl_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,"on")==0)
|
|
tpl_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
tpl_param=0;
|
|
|
|
set_tpl_rd_fn(pbp_device_block, tpl_param);
|
|
|
|
return count;
|
|
}
|
|
#ifdef PMC_FIX_FLAG
|
|
int
|
|
set_wait_at_pwup_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int tpl_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,"on")==0)
|
|
tpl_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
tpl_param=0;
|
|
|
|
set_bp_wait_at_pwup_rd_fn(pbp_device_block, tpl_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
int
|
|
set_hw_reset_pfs(struct file *file, const char *buffer,
|
|
unsigned long count, void *data)
|
|
{
|
|
|
|
char kbuf[256];
|
|
bpctl_dev_t * pbp_device_block= (bpctl_dev_t *) data;
|
|
|
|
int tpl_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,"on")==0)
|
|
tpl_param=1;
|
|
else if (strcmp(kbuf,"off")==0)
|
|
tpl_param=0;
|
|
|
|
set_bp_hw_reset_rd_fn(pbp_device_block, tpl_param);
|
|
|
|
return count;
|
|
}
|
|
|
|
#endif /*PMC_FIX_FLAG*/
|
|
#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0) )
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
#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_rd_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_rd_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 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_rd_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_rd_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 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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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 int show_tpl(struct seq_file *m, void *v)
|
|
{
|
|
bpctl_dev_t *dev = m->private;
|
|
int ret = get_tpl_rd_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;
|
|
}
|
|
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_rd_fn(dev, tpl_param);
|
|
return count;
|
|
}
|
|
|
|
RW_FOPS(tpl)
|
|
|
|
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_rd_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_rd_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_rd_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_rd_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)
|
|
|
|
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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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_rd_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 int show_reset_bypass_wd(struct seq_file *m, void *v)
|
|
{
|
|
bpctl_dev_t *dev = m->private;
|
|
int ret = reset_bypass_wd_timer_rd_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 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_rd_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_rd_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_rd_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 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_rd_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_rd_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 int show_wd_set_caps(struct seq_file *m, void *v)
|
|
{
|
|
bpctl_dev_t *dev = m->private;
|
|
int ret = get_wd_set_caps_rd_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 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_rd_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_rd_fn(dev);
|
|
if (ret >= 0)
|
|
seq_printf(m, "%d\n", ret);
|
|
else
|
|
seq_printf(m, "fail\n");
|
|
return 0;
|
|
}
|
|
RW_FOPS(wd_autoreset)
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) )
|
|
int bypass_proc_create_dev_rd(bpctl_dev_t * pbp_device_block){
|
|
struct bypass_pfs_rd *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_getdir(current_pfs->dir_name,bp_procfs_dir);
|
|
if (procfs_dir == 0) {
|
|
printk(KERN_DEBUG "Could not create procfs directory %s\n",
|
|
current_pfs->dir_name);
|
|
return -1;
|
|
}
|
|
current_pfs->bypass_entry= procfs_dir;
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->bypass_info),
|
|
BYPASS_INFO_ENTRY_SD,
|
|
NULL, /* write */
|
|
get_bypass_info_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
if (pbp_device_block->bp_caps & SW_CTL_CAP) {
|
|
|
|
|
|
/* Create set param proc's */
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->bypass_slave),
|
|
BYPASS_SLAVE_ENTRY_SD,
|
|
NULL, /* write */
|
|
get_bypass_slave_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->bypass_caps),
|
|
BYPASS_CAPS_ENTRY_SD,
|
|
NULL, /* write */
|
|
get_bypass_caps_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->wd_set_caps),
|
|
WD_SET_CAPS_ENTRY_SD,
|
|
NULL, /* write */
|
|
get_wd_set_caps_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->bypass_wd),
|
|
BYPASS_WD_ENTRY_SD,
|
|
set_bypass_wd_pfs, /* write */
|
|
get_bypass_wd_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->wd_expire_time),
|
|
WD_EXPIRE_TIME_ENTRY_SD,
|
|
NULL, /* write */
|
|
get_wd_expire_time_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->reset_bypass_wd),
|
|
RESET_BYPASS_WD_ENTRY_SD,
|
|
NULL, /* write */
|
|
reset_bypass_wd_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->std_nic),
|
|
STD_NIC_ENTRY_SD,
|
|
set_std_nic_pfs, /* write */
|
|
get_std_nic_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
|
|
if (pbp_device_block->bp_caps & BP_CAP) {
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->bypass),
|
|
BYPASS_ENTRY_SD,
|
|
set_bypass_pfs, /* write */
|
|
get_bypass_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->dis_bypass),
|
|
DIS_BYPASS_ENTRY_SD,
|
|
set_dis_bypass_pfs, /* write */
|
|
get_dis_bypass_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->bypass_pwup),
|
|
BYPASS_PWUP_ENTRY_SD,
|
|
set_bypass_pwup_pfs, /* write */
|
|
get_bypass_pwup_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->bypass_pwoff),
|
|
BYPASS_PWOFF_ENTRY_SD,
|
|
set_bypass_pwoff_pfs, /* write */
|
|
get_bypass_pwoff_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->bypass_change),
|
|
BYPASS_CHANGE_ENTRY_SD,
|
|
NULL, /* write */
|
|
get_bypass_change_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
}
|
|
|
|
if (pbp_device_block->bp_caps & TAP_CAP) {
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->tap),
|
|
TAP_ENTRY_SD,
|
|
set_tap_pfs, /* write */
|
|
get_tap_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->dis_tap),
|
|
DIS_TAP_ENTRY_SD,
|
|
set_dis_tap_pfs, /* write */
|
|
get_dis_tap_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->tap_pwup),
|
|
TAP_PWUP_ENTRY_SD,
|
|
set_tap_pwup_pfs, /* write */
|
|
get_tap_pwup_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->tap_change),
|
|
TAP_CHANGE_ENTRY_SD,
|
|
NULL, /* write */
|
|
get_tap_change_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
}
|
|
if (pbp_device_block->bp_caps & DISC_CAP) {
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->tap),
|
|
DISC_ENTRY_SD,
|
|
set_disc_pfs, /* write */
|
|
get_disc_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
#if 1
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->dis_tap),
|
|
DIS_DISC_ENTRY_SD,
|
|
set_dis_disc_pfs, /* write */
|
|
get_dis_disc_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
#endif
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->tap_pwup),
|
|
DISC_PWUP_ENTRY_SD,
|
|
set_disc_pwup_pfs, /* write */
|
|
get_disc_pwup_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->tap_change),
|
|
DISC_CHANGE_ENTRY_SD,
|
|
NULL, /* write */
|
|
get_disc_change_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
}
|
|
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->wd_exp_mode),
|
|
WD_EXP_MODE_ENTRY_SD,
|
|
set_wd_exp_mode_pfs, /* write */
|
|
get_wd_exp_mode_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->wd_autoreset),
|
|
WD_AUTORESET_ENTRY_SD,
|
|
set_wd_autoreset_pfs, /* write */
|
|
get_wd_autoreset_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->tpl),
|
|
TPL_ENTRY_SD,
|
|
set_tpl_pfs, /* write */
|
|
get_tpl_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
#ifdef PMC_FIX_FLAG
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->tpl),
|
|
WAIT_AT_PWUP_ENTRY_SD,
|
|
set_wait_at_pwup_pfs, /* write */
|
|
get_wait_at_pwup_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
if (bypass_proc_create_entry_rd(&(current_pfs->tpl),
|
|
HW_RESET_ENTRY_SD,
|
|
set_hw_reset_pfs, /* write */
|
|
get_hw_reset_pfs, /* read */
|
|
procfs_dir,
|
|
pbp_device_block))
|
|
ret= -1;
|
|
|
|
#endif
|
|
|
|
}
|
|
if (ret<0)
|
|
printk(KERN_DEBUG "Create proc entry failed\n");
|
|
|
|
return ret;
|
|
}
|
|
#else
|
|
|
|
static int procfs_add(char *proc_name, const struct file_operations *fops,
|
|
bpctl_dev_t *dev)
|
|
{
|
|
struct bypass_pfs_rd *pfs = &dev->bypass_pfs_set;
|
|
if (!proc_create_data(proc_name, 0644, pfs->bypass_entry, fops, dev))
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
int bypass_proc_create_dev_rd(bpctl_dev_t *pbp_device_block)
|
|
{
|
|
struct bypass_pfs_rd *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;
|
|
}
|
|
|
|
#endif
|
|
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) )
|
|
int bypass_proc_remove_dev_rd(bpctl_dev_t * pbp_device_block){
|
|
|
|
struct bypass_pfs_rd *current_pfs = &pbp_device_block->bypass_pfs_set;
|
|
struct proc_dir_entry *pde = current_pfs->bypass_entry, *pde_curr=NULL;
|
|
char name[256];
|
|
if (!pde)
|
|
return 0;
|
|
for (pde=pde->subdir; pde; ) {
|
|
strcpy(name,pde->name);
|
|
pde_curr=pde;
|
|
pde=pde->next;
|
|
remove_proc_entry(name,current_pfs->bypass_entry);
|
|
}
|
|
if (!pde)
|
|
remove_proc_entry(current_pfs->dir_name,bp_procfs_dir);
|
|
|
|
current_pfs->bypass_entry=NULL;
|
|
|
|
|
|
return 0;
|
|
}
|
|
#else
|
|
|
|
|
|
int bypass_proc_remove_dev_rd(bpctl_dev_t *pbp_device_block)
|
|
{
|
|
|
|
struct bypass_pfs_rd *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;
|
|
}
|
|
#endif
|
|
|
|
|
|
#endif //BP_PROC_SUPPORT
|
|
|
|
|