/***************************************************************************** * sdla_xilinx.h WANPIPE(tm) S51XX Xilinx Hardware Support * * Authors: Nenad Corbic * * Copyright: (c) 2003 Sangoma Technologies Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ * Jan 07, 2003 Nenad Corbic Initial version. *****************************************************************************/ #ifndef _SDLA_XILINX_H #define _SDLA_XILINX_H /*====================================================== * * XILINX Chip PCI Registers * *=====================================================*/ /* Main configuration and status register */ #define XILINX_CHIP_CFG_REG 0x40 /* Interface registers used to program * board framer i.e. front end * (PCM,Level1...) */ #define XILINX_MCPU_INTERFACE 0x44 #define XILINX_MCPU_INTERFACE_ADDR 0x46 #define TE3_LOCAL_CONTROL_STATUS_REG 0x48 #define XILINX_GLOBAL_INTER_MASK 0x4C /* HDLC interrupt pending registers used * in case of an HDLC tx or rx abort condition */ #define XILINX_HDLC_TX_INTR_PENDING_REG 0x50 #define XILINX_HDLC_RX_INTR_PENDING_REG 0x54 /* Possible RX packet errors */ enum { WP_FIFO_ERROR_BIT, WP_CRC_ERROR_BIT, WP_ABORT_ERROR_BIT, }; /* Maximum number of frames in a fifo * where frame lengths vary from 1 to 4 bytes */ #define WP_MAX_FIFO_FRAMES 7 /* DMA interrupt pending reg, used to * signal dma tx/rx complete event on a * specific channel */ #define XILINX_DMA_TX_INTR_PENDING_REG 0x58 #define XILINX_DMA_RX_INTR_PENDING_REG 0x5C /* Timeslot addr reg (bits: 16-20) is used to access * control memory in order to setup * (physical) T1/E1 timeslot channels * * Logic (HDLC) Channel addr reg (bits: 0-4) is used to * access HDLC Core internal registers. * Used to access and configure each * HDCL channel (tx and rx), * in HDCL core.*/ #define XILINX_TIMESLOT_HDLC_CHAN_REG 0x60 /* T3 Tx/Rx Channel Select * * 0=Tx Channel * 1=Rx Channel */ #define AFT_T3_RXTX_ADDR_SELECT_REG 0x60 #define XILINX_CURRENT_TIMESLOT_MASK 0x00001F00 #define XILINX_CURRENT_TIMESLOT_SHIFT 8 /* HDLC data register used to * access and configure HDLC core * control status registers */ #define XILINX_HDLC_CONTROL_REG 0x64 /* HDLC data register used to * access and configure HDLC core * address registers */ #define XILINX_HDLC_ADDR_REG 0x68 /* Control RAM data buffer, used to * write/read data to/from control * (chip) memory. * * The address of the memory access * must be specified in XILINX_TIMESLOT_HDLC_CHAN_REG. */ #define XILINX_CONTROL_RAM_ACCESS_BUF 0x6C /* Global DMA control register used to * setup DMA engine */ #define XILINX_DMA_CONTROL_REG 0x70 /* DMA tx status register is a bitmap * status of each logical tx (HDLC) channel. * * Bit 0: Fifo full * Bit 1: Fifo is ready to dma tx data from * pci memory to tx fifo. */ #define XILINX_DMA_TX_STATUS_REG 0x74 /* TX Watchdog Timer Register * * Delay constant for watchdog * timer. From 1 to 255. * * Minimum Interval = 1ms * * 0 =Reset/Disable Timer * Ack Interrupt pending flag * * 1-255=Timer enabled 1ms intervals * * */ #define AFT_TE3_TX_WDT_CTRL_REG 0x74 /* DMA rx status register is a bitmap * status of each logical rx (HDLC) channel. * * Bit 0: Fifo is empty or not ready to * dma data to pci memory. * Bit 1: Fifo is ready to dma rx data * into pci memory. */ #define XILINX_DMA_RX_STATUS_REG 0x78 /* RX Watchdog Timer Register * * Delay constant for watchdog * timer. From 1 to 255. * * Minimum Interval = 1ms * * 0 =Reset/Disable Timer * Ack Interrupt pending flag * * 1-255=Timer enabled 1ms intervals * * */ #define AFT_TE3_RX_WDT_CTRL_REG 0x78 /* TE3 Fractional Encapsulation Control * Status Register * */ #define TE3_FRACT_ENCAPSULATION_REG 0x7C /* AFT TE3 Current DMA descriptor address * * Bit 0-3: Current Tx Dma Descr * Bit 4-7: Current Rx Dma Descr */ #define AFT_TE3_CRNT_DMA_DESC_ADDR_REG 0x80 /* DMA descritors, RAM 128x32 * * To be used as offsets to the TX/RX DMA * Descriptor, based on the channel number. * * Addr = Channel_Number*0xF + Tx/Rx_DMA_DESCRIPTOR_LO/HI * * */ #define XILINX_TxDMA_DESCRIPTOR_LO 0x100 #define XILINX_TxDMA_DESCRIPTOR_HI 0x104 #define XILINX_RxDMA_DESCRIPTOR_LO 0x108 #define XILINX_RxDMA_DESCRIPTOR_HI 0x10C /*====================================================== * XILINX_CHIP_CFG_REG Bit Map * * Main configuration and status register *=====================================================*/ /* Select between T1/T3 or E1/E3 front end * Bit=0 : T1/T3 Bit=1 : E1/E3 */ #define INTERFACE_TYPE_T1_E1_BIT 0 #define INTERFACE_TYPE_T3_E3_BIT 0 /* Enable onboard led * 0= On * 1= Off */ #define XILINX_RED_LED 1 /* T3 HDLC Controller Bit * 0= HDLC mode * 1= Transparent mode */ #define AFT_T3_HDLC_TRANS_MODE 1 /* Enable frame flag generation on * front end framers (T1/E1...) */ #define FRONT_END_FRAME_FLAG_ENABLE_BIT 2 /* Select T3/E3 clock source * 0=External/Normal * 1=Internal/Master */ #define AFT_T3_CLOCK_MODE 2 /* Interface mode: * DS3 '0' - M13, "1" - C-Bit * E3 '0' - G.751, "1" - G.832 */ #define INTERFACE_MODE_DS3_C_BIT 3 #define INTERFACE_MODE_E3_G832 3 /* Reset front end framer (T1/E1 ...) * Bit=1: Rest Active */ #define FRONT_END_RESET_BIT 4 /* Reset the whole chip logic except * HDLC Core: Bit=1*/ #define CHIP_RESET_BIT 5 /* Reset HDLC Core: Bit=1 */ #define HDLC_CORE_RESET_BIT 6 /* HDLC core ready flag * Bit=1: HDLC Core ready for operation * Bit=0: HDLC Core in reset state */ #define HDLC_CORE_READY_FLAG_BIT 7 /* Enable or Disable all chip interrupts * Bit=1: Enable Bit=0: Disable */ #define GLOBAL_INTR_ENABLE_BIT 8 /* Enable chip interrupt on any error event. * Bit=1: Enable Bit=0: Disable */ #define ERROR_INTR_ENABLE_BIT 9 /* Reload Xilinx firmware * Used to re-configure xilinx hardware */ #define FRONT_END_INTR_ENABLE_BIT 10 /* Enable HDLC decapsualtion * on the TE3 Rx fractional * data stream. */ #define ENABLE_TE3_FRACTIONAL 12 /* TE3 Remote Fractional Equipment * * This option, indicates the remote * TE3 Fractional Device, since each * device might have custom data endcoding. */ #define TE3_FRACT_REMOTE_VENDOR_SHIFT 16 #define TE3_FRACT_REMOTE_VENDOR_MASK 0xFFF8FFFF #define TE3_FRACT_VENDOR_KENTROX 0 #define TE3_FRACT_VENDOR_ADTRAN 1 #define TE3_FRACT_VENDOR_DIGITAL 2 #define TE3_FRACT_VENDOR_LARSCOM 3 #define TE3_FRACT_VENDOR_VERILINK 4 #ifdef WAN_KERNEL static __inline void te3_enable_fractional(unsigned int *reg, unsigned int vendor) { *reg&=TE3_FRACT_REMOTE_VENDOR_MASK; *reg|=(vendor<>TE3_RX_FRACT_CRC_ERR_CNT_SHIFT); } #endif /* TX Section */ /* Tx Fractional baud rate * * This is a 14 bit counter, used to * specify the period of tx buffers. * * The period is used to thorttle the * tx speed from 1 to 35Mhz. */ #define TE3_TX_FRACT_BAUD_RATE_SHIFT 16 #define TE3_TX_FRACT_BAUD_RATE_MASK 0xFF80FFFF #ifdef WAN_KERNEL static __inline void set_te3_tx_fract_baud_rate(unsigned int *reg, unsigned long bitrate_khz, unsigned int buffer_size, unsigned char e3) { /* Period for T3 and E3 clock in ns */ unsigned long period_ns=e3?29:22; unsigned long data_period_ns=0; unsigned long counter=0; /* Get the number of bits */ buffer_size*=8; data_period_ns=(buffer_size*1000000)/bitrate_khz; counter=data_period_ns/period_ns; counter=(counter>>7)&0x7F; *reg&=TE3_TX_FRACT_BAUD_RATE_MASK; *reg|=(counter<> AFT_TE3_CRNT_RX_DMA_SHIFT); } static __inline unsigned int get_current_tx_dma_ptr(u32 reg) { return ((reg & AFT_TE3_CRNT_TX_DMA_MASK)); } static __inline void set_current_rx_dma_ptr(u32 *reg, u32 val) { *reg &= ~AFT_TE3_CRNT_RX_DMA_MASK; *reg |= (val << AFT_TE3_CRNT_RX_DMA_SHIFT) & AFT_TE3_CRNT_RX_DMA_MASK; } static __inline void set_current_tx_dma_ptr(u32 *reg, u32 val) { *reg &= ~AFT_TE3_CRNT_TX_DMA_MASK; *reg |= val & AFT_TE3_CRNT_TX_DMA_MASK; } #endif /*======================================= * TE3_LOCAL_CONTROL_STATUS_REG * */ enum { WAN_AFT_RED, WAN_AFT_GREEN }; enum { WAN_AFT_OFF, WAN_AFT_ON }; #define TE3_D5_RED 0 #define TE3_D5_GREEN 1 #define TE3_D6_RED 2 #define TE3_D6_GREEN 3 #ifdef WAN_KERNEL static __inline void aft_te3_set_led(unsigned int color, int led_pos, int on, u32 *reg) { if (led_pos == 0){ if (color == WAN_AFT_RED){ if (on == WAN_AFT_OFF){ wan_set_bit(TE3_D5_RED,reg); }else{ wan_clear_bit(TE3_D5_RED,reg); } }else{ if (on == WAN_AFT_OFF){ wan_set_bit(TE3_D5_GREEN,reg); }else{ wan_clear_bit(TE3_D5_GREEN,reg); } } }else{ if (color == WAN_AFT_RED){ if (on == WAN_AFT_OFF){ wan_set_bit(TE3_D6_RED,reg); }else{ wan_clear_bit(TE3_D6_RED,reg); } }else{ if (on == WAN_AFT_OFF){ wan_set_bit(TE3_D6_GREEN,reg); }else{ wan_clear_bit(TE3_D6_GREEN,reg); } } } } #endif /*=============================================== */ typedef struct xilinx_config { unsigned long xilinx_chip_cfg_reg; unsigned long xilinx_dma_control_reg; }xilinx_config_t; /* Default length of the DMA burst * Value indicates the maximum number * of DMA transactions per burst */ #define XILINX_DMA_SIZE 10 /* Used by DMA engine to transfer data from Fifo to PC. * DMA engine start rx when fifo level becomes greater * than the DMA FIFI UP value */ #define XILINX_DMA_FIFO_UP 8 /* Used by DMA engine to transfer data from PC to Fifo. * DMA engine start tx when free space in the fifo * becomes greater than DMA FIFO LO value */ #define XILINX_DMA_FIFO_LO 8 /* Used by DMA engine to transfer data from PC to Fifo. * DMA engine start tx/rx when fifo is greater/lower * than the DMA FIFO MARK value */ #define AFT_T3_DMA_FIFO_MARK 8 /* Default Active DMA channel used by the * DMA Engine */ #define XILINX_DEFLT_ACTIVE_CH 0 #define MAX_XILINX_TX_DMA_SIZE 0xFFFF #define MIN_WP_PRI_MTU 10 #define DEFAULT_WP_PRI_MTU 1500 /* Maximum MTU for AFT card * 8192-4=8188. This is a hardware * limitation. */ #define MAX_WP_PRI_MTU 8188 enum { #if defined(__LINUX__) SDLA_HDLC_READ_REG = SIOC_ANNEXG_PLACE_CALL, #else SDLA_HDLC_READ_REG = 0, /* FIXME !!!*/ #endif SDLA_HDLC_WRITE_REG, SDLA_HDLC_SET_PCI_BIOS }; #define MAX_DATA_SIZE 2000 struct sdla_hdlc_api{ unsigned int cmd; unsigned short len; unsigned char bar; unsigned short offset; unsigned char data[MAX_DATA_SIZE]; }; struct wan_aften_api{ unsigned int cmd; unsigned short len; unsigned char bar; unsigned short offset; unsigned char data[MAX_DATA_SIZE]; }; #pragma pack(1) typedef struct { unsigned char error_flag; unsigned short time_stamp; unsigned char reserved[13]; } api_rx_hdr_t; typedef struct { api_rx_hdr_t api_rx_hdr; unsigned char data[1]; } api_rx_element_t; typedef struct { unsigned char attr; unsigned char misc_Tx_bits; unsigned char reserved[14]; } api_tx_hdr_t; typedef struct { api_tx_hdr_t api_tx_hdr; unsigned char data[1]; } api_tx_element_t; /* the operational statistics structure */ typedef struct { /* Data frame transmission statistics */ unsigned long Data_frames_Tx_count ; /* # of frames transmitted */ unsigned long Data_bytes_Tx_count ; /* # of bytes transmitted */ unsigned long Data_Tx_throughput ; /* transmit throughput */ unsigned long no_ms_for_Data_Tx_thruput_comp ; /* millisecond time used for the Tx throughput computation */ unsigned long Tx_Data_discard_lgth_err_count ; /* Data frame reception statistics */ unsigned long Data_frames_Rx_count ; /* number of frames received */ unsigned long Data_bytes_Rx_count ; /* number of bytes received */ unsigned long Data_Rx_throughput ; /* receive throughput */ unsigned long no_ms_for_Data_Rx_thruput_comp ; /* millisecond time used for the Rx throughput computation */ unsigned long Rx_Data_discard_short_count ; /* received Data frames discarded (too short) */ unsigned long Rx_Data_discard_long_count ; /* received Data frames discarded (too long) */ unsigned long Rx_Data_discard_inactive_count ; /* received Data frames discarded (link inactive) */ /* Incomming frames with a format error statistics */ unsigned short Rx_frm_incomp_CHDLC_hdr_count ; /* frames received of with incomplete Cisco HDLC header */ unsigned short Rx_frms_too_long_count ; /* frames received of excessive length count */ /* CHDLC link active/inactive and loopback statistics */ unsigned short link_active_count ; /* number of times that the link went active */ unsigned short link_inactive_modem_count ; /* number of times that the link went inactive (modem failure) */ unsigned short link_inactive_keepalive_count ; /* number of times that the link went inactive (keepalive failure) */ unsigned short link_looped_count ; /* link looped count */ unsigned long Data_frames_Tx_realign_count; } aft_op_stats_t; typedef struct { unsigned short Rx_overrun_err_count; unsigned short Rx_crc_err_count ; /* receiver CRC error count */ unsigned short Rx_abort_count ; /* abort frames recvd count */ unsigned short Rx_hdlc_corrupiton; /* receiver disabled */ unsigned short Rx_pci_errors; /* missed tx underrun interrupt count */ unsigned short Rx_dma_descr_err; /*secondary-abort frames tx count */ unsigned short DCD_state_change_count ; /* DCD state change */ unsigned short CTS_state_change_count ; /* CTS state change */ unsigned short Tx_pci_errors; /* missed tx underrun interrupt count */ unsigned short Tx_dma_errors; /* missed tx underrun interrupt count */ unsigned int Tx_pci_latency; /* missed tx underrun interrupt count */ unsigned int Tx_dma_len_nonzero; /* Tx dma descriptor len not zero */ } aft_comm_err_stats_t; #pragma pack() #undef wan_udphdr_data #define wan_udphdr_data wan_udphdr_u.aft.data /*========================================== * Board CPLD Interface Section * *=========================================*/ #define PMC_CONTROL_REG 0x00 /* Used to reset the pcm * front end * 0: Reset Enable * 1: Normal Operation */ #define PMC_RESET_BIT 0 /* Used to set the pmc clock * source: * 0 = E1 * 1 = T1 */ #define PMC_CLOCK_SELECT 1 #define LED_CONTROL_REG 0x01 #define JP8_VALUE 0x02 #define JP7_VALUE 0x01 #define SW0_VALUE 0x04 #define SW1_VALUE 0x08 #define SECURITY_CPLD_REG 0x09 #define CUSTOMER_CPLD_ID_REG 0x0A #define SECURITY_CPLD_MASK 0x03 #define SECURITY_CPLD_SHIFT 0x02 #define SECURITY_1LINE_UNCH 0x00 #define SECURITY_1LINE_CH 0x01 #define SECURITY_2LINE_UNCH 0x02 #define SECURITY_2LINE_CH 0x03 /* -------------------------------------- */ #define WRITE_DEF_SECTOR_DSBL 0x01 #define FRONT_END_TYPE_MASK 0x38 #define BIT_DEV_ADDR_CLEAR 0x600 #define BIT_DEV_ADDR_CPLD 0x200 #define MEMORY_TYPE_SRAM 0x00 #define MEMORY_TYPE_FLASH 0x01 #define MASK_MEMORY_TYPE_SRAM 0x10 #define MASK_MEMORY_TYPE_FLASH 0x20 #define BIT_A18_SECTOR_SA4_SA7 0x20 #define USER_SECTOR_START_ADDR 0x40000 #define MAX_TRACE_QUEUE 100 #define MAX_TRACE_BUFFER (MAX_LGTH_UDP_MGNT_PKT - \ sizeof(iphdr_t) - \ sizeof(udphdr_t) - \ sizeof(wan_mgmt_t) - \ sizeof(wan_trace_info_t) - \ sizeof(wan_cmd_t)) enum { ROUTER_UP_TIME = 0x50, ENABLE_TRACING, DISABLE_TRACING, GET_TRACE_INFO, READ_CODE_VERSION, FLUSH_OPERATIONAL_STATS, OPERATIONAL_STATS, READ_OPERATIONAL_STATS, READ_CONFIGURATION, READ_COMMS_ERROR_STATS, FLUSH_COMMS_ERROR_STATS, AFT_LINK_STATUS }; #define UDPMGMT_SIGNATURE "AFTPIPEA" /* the line trace status element presented by the frame relay code */ typedef struct { unsigned char flag ; /* ready flag */ unsigned short length ; /* trace length */ unsigned char rsrv0[2] ; /* reserved */ unsigned char attr ; /* trace attributes */ unsigned short tmstamp ; /* time stamp */ unsigned char rsrv1[4] ; /* reserved */ unsigned long offset ; /* buffer absolute address */ }aft_trc_el_t; typedef struct wp_rx_element { unsigned int dma_addr; unsigned int reg; unsigned int align; unsigned char pkt_error; }wp_rx_element_t; #if defined(WAN_KERNEL) static __inline unsigned short xilinx_valid_mtu(unsigned short mtu) { if (mtu <= 128){ return 128; }else if (mtu <= 256){ return 256; }else if (mtu <= 512){ return 512; }else if (mtu <= 1024){ return 1024; }else if (mtu <= 2048){ return 2048; }else if (mtu <= 4096){ return 4096; }else if (mtu <= 8188){ return 8188; }else{ return 0; } } static __inline unsigned short xilinx_dma_buf_bits(unsigned short dma_bufs) { if (dma_bufs < 2){ return 0; }else if (dma_bufs < 3){ return 1; }else if (dma_bufs < 5){ return 2; }else if (dma_bufs < 9){ return 3; }else if (dma_bufs < 17){ return 4; }else{ return 0; } } #define AFT_TX_TIMEOUT 5 #define AFT_RX_TIMEOUT 2 #define AFT_MAX_WTD_TIMEOUT 2 static __inline void aft_reset_rx_watchdog(sdla_t *card) { card->hw_iface.bus_write_1(card->hw,AFT_TE3_RX_WDT_CTRL_REG,0); } static __inline void aft_enable_rx_watchdog(sdla_t *card, unsigned char timeout) { aft_reset_rx_watchdog(card); card->hw_iface.bus_write_1(card->hw,AFT_TE3_RX_WDT_CTRL_REG,timeout); } static __inline void aft_reset_tx_watchdog(sdla_t *card) { card->hw_iface.bus_write_1(card->hw,AFT_TE3_TX_WDT_CTRL_REG,0); } static __inline void aft_enable_tx_watchdog(sdla_t *card, unsigned char timeout) { aft_reset_tx_watchdog(card); card->hw_iface.bus_write_1(card->hw,AFT_TE3_TX_WDT_CTRL_REG,timeout); } #endif /* WAN_KERNEL */ #if defined(__LINUX__) enum { SIOC_AFT_CUSTOMER_ID = SIOC_WANPIPE_DEVPRIVATE }; #endif #endif