987 lines
27 KiB
C
987 lines
27 KiB
C
/***************************************************************************
|
|
* sdla_serial.c WANPIPE(tm)
|
|
* Serial A140 support module for A140 Serial FE.
|
|
*
|
|
* Author(s): Nenad Corbic <ncorbic@sangoma.com>
|
|
*
|
|
* Copyright: (c) 2007 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.
|
|
*
|
|
* ============================================================================
|
|
* Nov 1, 2007 Nenad Corbic Initial version.
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*******************************************************************************
|
|
** INCLUDE FILES
|
|
*******************************************************************************/
|
|
|
|
|
|
# include "wanpipe_includes.h"
|
|
# include "wanpipe_defines.h"
|
|
# include "wanpipe_debug.h"
|
|
# include "wanpipe_abstr.h"
|
|
# include "wanpipe_common.h"
|
|
# include "wanpipe_events.h"
|
|
# include "wanpipe.h"
|
|
# include "wanpipe_events.h"
|
|
# include "if_wanpipe_common.h" /* for 'wanpipe_common_t' used in 'aft_core.h'*/
|
|
# include "sdla_serial.h"
|
|
# include "aft_core.h" /* Map of Zaptel -> DAHDI definitions */
|
|
|
|
|
|
#undef DEBUG_SERIAL
|
|
#define DEBUG_SERIAL if(0)DEBUG_EVENT
|
|
|
|
/* DEBUG macro definitions */
|
|
#define SERIAL_FUNC() if(0)DEBUG_EVENT("%s(): line: %d\n", __FUNCTION__, __LINE__)
|
|
|
|
int aft_serial_write_cpld(void *card, unsigned short off,u_int16_t data);
|
|
unsigned char aft_serial_read_cpld(void *card, unsigned short cpld_off);
|
|
|
|
/*******************************************************************************
|
|
** DEFINES AND MACROS
|
|
*******************************************************************************/
|
|
#define REPORT_MOD_NO (mod_no+1)
|
|
|
|
static u8 validate_fe_line_no(sdla_fe_t *fe, const char *caller_name)
|
|
{
|
|
if ((int32_t)WAN_FE_LINENO(fe) < 0 || WAN_FE_LINENO(fe) > MAX_SERIAL_LINES){
|
|
DEBUG_EVENT("%s(): %s: SERIAL: Invalid FE line number %d (Min=1 Max=%d)\n",
|
|
caller_name, fe->name, WAN_FE_LINENO(fe)+1, MAX_SERIAL_LINES);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#define FE_LINENO_TO_MODULENO_AND_PORTNO(fe) \
|
|
{ \
|
|
mod_no = fe_line_no_to_physical_mod_no(fe); \
|
|
port = fe_line_no_to_port_no(fe); \
|
|
}
|
|
|
|
#if 0
|
|
/* wait for "milliseconds * 1/1000" of sec */
|
|
static void WP_MDELAY(u32 milliseconds)
|
|
{
|
|
for (; milliseconds > 0; --milliseconds){
|
|
WP_DELAY(1000);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*******************************************************************************/
|
|
/* Register Write/Read debugging funcitons */
|
|
|
|
/* Enabling/Disabling register debugging */
|
|
#define WAN_DEBUG_SERIAL_REG 0
|
|
|
|
#if WAN_DEBUG_SERIAL_REG
|
|
|
|
#define HFC_WRITE 1
|
|
#define HFC_READ 2
|
|
|
|
#endif /* WAN_DEBUG_SERIAL_REG */
|
|
/*******************************************************************************/
|
|
|
|
/*******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
** STRUCTURES AND TYPEDEFS
|
|
*******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
** GLOBAL VARIABLES
|
|
*******************************************************************************/
|
|
#if !defined(__WINDOWS__)
|
|
extern WAN_LIST_HEAD(, wan_tdmv_) wan_tdmv_head;
|
|
#endif
|
|
|
|
/*******************************************************************************
|
|
** FUNCTION PROTOTYPES
|
|
*******************************************************************************/
|
|
static int32_t serial_global_config(void* pfe);
|
|
static int32_t serial_global_unconfig(void* pfe);
|
|
static int32_t wp_serial_config(void *pfe);
|
|
static int32_t wp_serial_unconfig(void *pfe);
|
|
static int32_t wp_serial_post_init(void *pfe);
|
|
static int32_t wp_serial_if_config(void *pfe, u32 mod_map, u8);
|
|
static int32_t wp_serial_if_unconfig(void *pfe, u32 mod_map, u8);
|
|
//static int32_t wp_serial_disable_irq(sdla_fe_t *fe, u32 mod_no, u8 port);
|
|
//static void serial_enable_interrupts(sdla_fe_t *fe, u32 mod_no, u8 port);
|
|
static int32_t wp_serial_intr(sdla_fe_t *);
|
|
static int32_t wp_serial_check_intr(sdla_fe_t *);
|
|
static int32_t wp_serial_polling(sdla_fe_t*);
|
|
static int32_t wp_serial_udp(sdla_fe_t*, void*, u8*);
|
|
static u32 wp_serial_active_map(sdla_fe_t* fe, u8 line_no);
|
|
static u8 wp_serial_fe_media(sdla_fe_t *fe);
|
|
static int32_t wp_serial_set_dtmf(sdla_fe_t*, int32_t, u8);
|
|
static int wp_serial_intr_ctrl(sdla_fe_t *fe, int mod_no, u_int8_t, u_int8_t mode, unsigned int ts_map);
|
|
static int32_t wp_serial_event_ctrl(sdla_fe_t*, wan_event_ctrl_t*);
|
|
|
|
static int wp_serial_get_fe_status(sdla_fe_t *fe, unsigned char *status, int notused);
|
|
static int wp_serial_set_fe_status(sdla_fe_t *fe, unsigned char status);
|
|
|
|
#if 0
|
|
static void wp_serial_enable_timer(sdla_fe_t* fe, u8 mod_no, u8 cmd, u32 delay);
|
|
|
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
|
static void wp_serial_timer(void*);
|
|
#elif defined(__WINDOWS__)
|
|
static void wp_serial_timer(IN PKDPC,void*,void*,void*);
|
|
#else
|
|
static void wp_serial_timer(void*);
|
|
#endif
|
|
#endif /* if 0 */
|
|
|
|
|
|
/* for selecting PCM direction */
|
|
#define XHFC_DIRECTION_TX 0
|
|
#define XHFC_DIRECTION_RX 1
|
|
|
|
#if 0
|
|
static void xhfc_select_xhfc_channel(sdla_fe_t *fe, u32 mod_no,
|
|
u8 channel, u8 direction, u8 vrout_bitmap);
|
|
#endif
|
|
|
|
//static int32_t check_f0cl_increment(sdla_fe_t *fe, u8 old_f0cl, u8 new_f0cl, int32_t *diff);
|
|
|
|
/*******************************************************************************
|
|
** FUNCTION DEFINITIONS
|
|
*******************************************************************************/
|
|
|
|
|
|
/*******************************************************************************/
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
** wp_serial_iface_init) -
|
|
**
|
|
** OK
|
|
*/
|
|
int32_t wp_serial_iface_init(void *pfe_iface)
|
|
{
|
|
sdla_fe_iface_t *fe_iface = (sdla_fe_iface_t*)pfe_iface;
|
|
|
|
SERIAL_FUNC();
|
|
fe_iface->global_config = &serial_global_config; /* not used in remora */
|
|
fe_iface->global_unconfig = &serial_global_unconfig; /* not used in remora */
|
|
|
|
fe_iface->config = &wp_serial_config;
|
|
fe_iface->unconfig = &wp_serial_unconfig;
|
|
|
|
fe_iface->post_init = &wp_serial_post_init;
|
|
|
|
fe_iface->if_config = &wp_serial_if_config;
|
|
fe_iface->if_unconfig = &wp_serial_if_unconfig;
|
|
|
|
fe_iface->active_map = &wp_serial_active_map;
|
|
|
|
fe_iface->set_fe_status = &wp_serial_set_fe_status;
|
|
fe_iface->get_fe_status = &wp_serial_get_fe_status;
|
|
|
|
fe_iface->isr = &wp_serial_intr;
|
|
// fe_iface->disable_irq = &wp_serial_disable_irq;
|
|
fe_iface->check_isr = &wp_serial_check_intr;
|
|
|
|
fe_iface->polling = &wp_serial_polling;
|
|
fe_iface->process_udp = &wp_serial_udp;
|
|
fe_iface->get_fe_media = &wp_serial_fe_media;
|
|
|
|
fe_iface->set_dtmf = &wp_serial_set_dtmf;
|
|
fe_iface->intr_ctrl = &wp_serial_intr_ctrl;
|
|
fe_iface->event_ctrl = &wp_serial_event_ctrl;
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if defined(NOTUSED)
|
|
/* Should be done only ONCE per card. */
|
|
static int32_t wp_serial_spi_bus_reset(sdla_fe_t *fe)
|
|
{
|
|
sdla_t *card = (sdla_t*)fe->card;
|
|
|
|
SERIAL_FUNC();
|
|
|
|
DEBUG_EVENT("%s: Executing SPI bus reset....\n", fe->name);
|
|
|
|
card->hw_iface.bus_write_4( card->hw,
|
|
SPI_INTERFACE_REG,
|
|
MOD_SPI_RESET);
|
|
WP_DELAY(1000);
|
|
card->hw_iface.bus_write_4( card->hw,
|
|
SPI_INTERFACE_REG,
|
|
0x00000000);
|
|
WP_DELAY(1000);
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
/******************************************************************************
|
|
* serial_global_config()
|
|
*
|
|
* Description : Global configuration for Sangoma SERIAL board.
|
|
*
|
|
* Notes : 1. This routine runs only ONCE for a physical 'base' CARD,
|
|
* not for 'additional' cards.
|
|
* 2. reset card's SPI.
|
|
* 3. Scan for installed Remoras and modules.
|
|
*
|
|
* Arguments : pfe - pointer to Front End structure.
|
|
*
|
|
* Returns : 0 - configred successfully, otherwise non-zero value.
|
|
*******************************************************************************/
|
|
static int32_t serial_global_config(void* pfe)
|
|
{
|
|
sdla_fe_t *fe = (sdla_fe_t*)pfe;
|
|
|
|
SERIAL_FUNC();
|
|
|
|
DEBUG_EVENT("%s: %s Global Front End configuration\n",
|
|
fe->name, FE_MEDIA_DECODE(fe));
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* serial_global_unconfig()
|
|
*
|
|
* Description : Global un-configuration for Sangoma SERIAL board.
|
|
* Note: This routne runs only ONCE for a physical card.
|
|
*
|
|
* Arguments :
|
|
*
|
|
* Returns : 0
|
|
*******************************************************************************/
|
|
static int32_t serial_global_unconfig(void* pfe)
|
|
{
|
|
sdla_fe_t *fe = (sdla_fe_t*)pfe;
|
|
sdla_t *card = (sdla_t*)fe->card;
|
|
|
|
SERIAL_FUNC();
|
|
aft_serial_write_cpld(card,0x08,0x00);
|
|
aft_serial_write_cpld(card,0x09,0x00);
|
|
|
|
DEBUG_EVENT("%s: %s Global Front End unconfiguration!\n",
|
|
fe->name, FE_MEDIA_DECODE(fe));
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* wp_serial_config() - initialise the XHFC ISDN Chip.
|
|
*
|
|
* Description : Configure the PHYSICAL module ONE time.
|
|
* On each module 2 lines will be configured
|
|
* in exactly the same way.
|
|
*
|
|
* Arguments : pfe - pointer to Front End structure.
|
|
*
|
|
* Returns : 0 - configred successfully, otherwise non-zero value.
|
|
*******************************************************************************/
|
|
static int32_t wp_serial_config(void *pfe)
|
|
{
|
|
sdla_fe_t *fe = (sdla_fe_t*)pfe;
|
|
sdla_t *card = (sdla_t*)fe->card;
|
|
u32 reg;
|
|
wan_bitmap_t cpld_reg_val;
|
|
wan_bitmap_t cpld_reg=0;
|
|
|
|
SERIAL_FUNC();
|
|
|
|
DEBUG_EVENT("%s: %s: Line %d Front End configuration\n",
|
|
fe->name, FE_MEDIA_DECODE(fe), WAN_FE_LINENO(fe) + 1);
|
|
|
|
if(validate_fe_line_no(fe, __FUNCTION__)){
|
|
return 1;
|
|
}
|
|
|
|
|
|
switch (card->wandev.line_coding){
|
|
case WANOPT_NRZ:
|
|
case WANOPT_NRZI:
|
|
break;
|
|
default:
|
|
DEBUG_ERROR("%s: A140: Error: Unsupported line coding mode 0x%X\n",
|
|
card->devname,
|
|
card->wandev.line_coding);
|
|
return -1;
|
|
}
|
|
|
|
card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),®);
|
|
|
|
switch (card->adptr_type) {
|
|
|
|
case AFT_ADPTR_2SERIAL_V35X21:
|
|
case AFT_ADPTR_4SERIAL_V35X21:
|
|
DEBUG_EVENT("%s: A140: Configuring for %s\n",
|
|
card->devname,card->wandev.electrical_interface==WANOPT_X21?"X21":"V35");
|
|
|
|
switch(WAN_FE_LINENO(fe)) {
|
|
|
|
case 0:
|
|
case 2:
|
|
cpld_reg=0x08;
|
|
break;
|
|
case 1:
|
|
case 3:
|
|
cpld_reg=0x09;
|
|
break;
|
|
default:
|
|
DEBUG_ERROR("%s: Error: Invalid Serial Port Number! (%i) \n",
|
|
card->devname,WAN_FE_LINENO(fe));
|
|
return -EINVAL;
|
|
};
|
|
|
|
cpld_reg_val=aft_serial_read_cpld(card,(unsigned short)cpld_reg);
|
|
|
|
if (card->wandev.electrical_interface == WANOPT_X21) {
|
|
wan_set_bit(AFT_SERIAL_LCFG_X21_MODE_BIT, ®);
|
|
} else {
|
|
if (wan_test_bit(2,&cpld_reg)) {
|
|
/* In this case port is trying to configure for V35
|
|
* where previous port already configured for X21 */
|
|
DEBUG_ERROR("%s: Error: Invalid V35 Configuration, Previous Port configured for X21\n",
|
|
card->devname);
|
|
return -EINVAL;
|
|
}
|
|
wan_clear_bit(AFT_SERIAL_LCFG_X21_MODE_BIT, ®);
|
|
}
|
|
DEBUG_SERIAL("%s(): cpld_reg_val: 0x%X\n", __FUNCTION__, cpld_reg_val);
|
|
|
|
if(card->wandev.clocking) {
|
|
|
|
/*FIXME: Must check for case where first port started in external mode
|
|
At this time, if port 1 start in normal & prot 3 in master, the
|
|
port 1 will silently be reconfigured to Master after port 3 starts */
|
|
|
|
if (card->wandev.clocking == WANOPT_INTERNAL) {
|
|
if (card->wandev.electrical_interface == WANOPT_X21) {
|
|
aft_serial_write_cpld(card,(unsigned short)cpld_reg,0x07);
|
|
}else{
|
|
aft_serial_write_cpld(card,(unsigned short)cpld_reg,0x05);
|
|
}
|
|
} else {
|
|
aft_serial_write_cpld(card,(unsigned short)cpld_reg,0x01);
|
|
}
|
|
} else {
|
|
if (wan_test_bit(2,&cpld_reg_val)) {
|
|
DEBUG_ERROR("%s: Error: Clocking configuration mismatch!\n",
|
|
card->devname);
|
|
DEBUG_EVENT("%s: Ports 1&3 and 2&4 must use same clock source!\n",
|
|
card->devname);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (card->wandev.electrical_interface == WANOPT_X21) {
|
|
aft_serial_write_cpld(card,(unsigned short)cpld_reg,0x03);
|
|
} else {
|
|
aft_serial_write_cpld(card,(unsigned short)cpld_reg,0x01);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case AFT_ADPTR_2SERIAL_RS232:
|
|
case AFT_ADPTR_4SERIAL_RS232:
|
|
|
|
DEBUG_EVENT("%s: A140: Configuring for RS232\n",
|
|
card->devname);
|
|
|
|
if (WAN_FE_LINENO(fe) < 2) {
|
|
cpld_reg=0x08;
|
|
} else {
|
|
cpld_reg=0x09;
|
|
}
|
|
|
|
cpld_reg_val=aft_serial_read_cpld(card,(unsigned short)cpld_reg);
|
|
if(card->wandev.clocking) {
|
|
wan_set_bit((WAN_FE_LINENO(fe)%2), &cpld_reg_val);
|
|
} else {
|
|
wan_clear_bit((WAN_FE_LINENO(fe)%2), &cpld_reg_val);
|
|
}
|
|
aft_serial_write_cpld(card,(unsigned short)cpld_reg,(u16)cpld_reg_val);
|
|
|
|
break;
|
|
|
|
default:
|
|
DEBUG_ERROR("%s: Error: Invalid Serial Card Type 0x%X\n",
|
|
card->devname,card->adptr_type);
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
DEBUG_EVENT("%s: A140: Configurfed for 0x%08X\n",
|
|
card->devname,
|
|
reg);
|
|
|
|
if (card->wandev.clocking) {
|
|
int err;
|
|
|
|
DEBUG_EVENT("%s: A140: Configuring for Internal Clocking: %s, Baud=%i\n",
|
|
card->devname,
|
|
card->wandev.clocking == WANOPT_INTERNAL?"Internal":"Recovery",
|
|
card->wandev.bps);
|
|
|
|
if (card->wandev.bps == 0) {
|
|
DEBUG_ERROR("%s: Error Invalid Baud Rate selected 0Kbps!\n",
|
|
card->devname);
|
|
return -EINVAL;
|
|
}
|
|
|
|
wan_set_bit(AFT_SERIAL_LCFG_CLK_SRC_BIT, ®);
|
|
|
|
if (card->u.aft.firm_ver < 0x07) {
|
|
if (card->wandev.clocking == WANOPT_INTERNAL) {
|
|
err=aft_serial_set_legacy_baud_rate(®,card->wandev.bps);
|
|
} else {
|
|
DEBUG_ERROR("%s: RECOVERY Clocking only supported on Fimware Ver 7 or greater!\n",card->devname);
|
|
return -EINVAL;
|
|
}
|
|
} else {
|
|
if (card->wandev.clocking == WANOPT_INTERNAL) {
|
|
err=aft_serial_set_baud_rate(®,card->wandev.bps,0);
|
|
} else {
|
|
err=aft_serial_set_baud_rate(®,card->wandev.bps*32,1);
|
|
}
|
|
}
|
|
|
|
if (err) {
|
|
return -EINVAL;
|
|
}
|
|
DEBUG_TEST("%s: Setting REG to 0x%08X!\n",card->devname,reg);
|
|
} else {
|
|
DEBUG_EVENT("%s: A140: Configuring for External Clocking: Baud=%i\n",
|
|
card->devname,
|
|
card->wandev.bps);
|
|
wan_clear_bit(AFT_SERIAL_LCFG_CLK_SRC_BIT, ®);
|
|
}
|
|
|
|
switch (card->wandev.line_coding){
|
|
case WANOPT_NRZ:
|
|
DEBUG_EVENT("%s: A140: Configuring for NRZ\n",
|
|
card->devname);
|
|
aft_serial_set_lcoding(®,WANOPT_NRZ);
|
|
break;
|
|
case WANOPT_NRZI:
|
|
DEBUG_EVENT("%s: A140: Configuring for NRZI\n",
|
|
card->devname);
|
|
aft_serial_set_lcoding(®,WANOPT_NRZI);
|
|
break;
|
|
default:
|
|
/* Should never happen because we check above */
|
|
DEBUG_ERROR("%s: A140: Error: Unsupported line coding mode 0x%X\n",
|
|
card->devname,
|
|
card->wandev.line_coding);
|
|
return -1;
|
|
}
|
|
|
|
if (card->wandev.connection == WANOPT_SWITCHED){
|
|
DEBUG_EVENT("%s: A140: Configuring for Switched CTS/RTS\n",card->devname);
|
|
wan_set_bit(AFT_SERIAL_LCFG_SWMODE_BIT, ®);
|
|
wan_set_bit(AFT_SERIAL_LCFG_IDLE_DET_BIT,®);
|
|
} else {
|
|
wan_clear_bit(AFT_SERIAL_LCFG_SWMODE_BIT, ®);
|
|
wan_clear_bit(AFT_SERIAL_LCFG_IDLE_DET_BIT,®);
|
|
}
|
|
|
|
if (card->wandev.clocking == WANOPT_RECOVERY) {
|
|
wan_set_bit(AFT_SERIAL_LCFG_IFACE_TYPE_BIT,®);
|
|
} else {
|
|
wan_clear_bit(AFT_SERIAL_LCFG_IFACE_TYPE_BIT,®);
|
|
}
|
|
|
|
/* CTS/DCD Interrupt Enable */
|
|
if (card->wandev.ignore_front_end_status == WANOPT_YES) {
|
|
/* If ignore front end is set, do not enable CTS/RTS interrupts */
|
|
wan_clear_bit(AFT_SERIAL_LCFG_CTS_INTR_EN_BIT,®);
|
|
wan_clear_bit(AFT_SERIAL_LCFG_DCD_INTR_EN_BIT,®);
|
|
} else {
|
|
wan_set_bit(AFT_SERIAL_LCFG_CTS_INTR_EN_BIT,®);
|
|
wan_set_bit(AFT_SERIAL_LCFG_DCD_INTR_EN_BIT,®);
|
|
}
|
|
|
|
card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),reg);
|
|
|
|
DEBUG_EVENT("%s: A140: Configurfed for 0x%08X CTS/DCD ISR=%s\n",
|
|
card->devname,
|
|
reg,card->wandev.ignore_front_end_status == WANOPT_YES?"Off":"On");
|
|
|
|
/* Raise RTS and DTR */
|
|
wan_set_bit(AFT_SERIAL_LCFG_RTS_BIT,®);
|
|
wan_set_bit(AFT_SERIAL_LCFG_DTR_BIT,®);
|
|
|
|
card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),reg);
|
|
|
|
card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),®);
|
|
|
|
DEBUG_EVENT("%s: A140: Configurfed for 0x%08X\n",
|
|
card->devname,
|
|
reg);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
** wp_serial_unconfig() -
|
|
**
|
|
** OK
|
|
*/
|
|
static int32_t wp_serial_unconfig(void *pfe)
|
|
{
|
|
sdla_fe_t *fe = (sdla_fe_t*)pfe;
|
|
sdla_t *card = (sdla_t*)fe->card;
|
|
u32 reg=0;
|
|
wan_bitmap_t cpld_reg;
|
|
wan_bitmap_t cpld_reg_val;
|
|
|
|
SERIAL_FUNC();
|
|
|
|
if(validate_fe_line_no(fe, __FUNCTION__)){
|
|
return 1;
|
|
}
|
|
|
|
switch (card->adptr_type) {
|
|
case AFT_ADPTR_2SERIAL_RS232:
|
|
case AFT_ADPTR_4SERIAL_RS232:
|
|
|
|
if (WAN_FE_LINENO(fe) < 2) {
|
|
cpld_reg=0x08;
|
|
} else {
|
|
cpld_reg=0x09;
|
|
}
|
|
|
|
cpld_reg_val=aft_serial_read_cpld(card,(unsigned short)cpld_reg);
|
|
wan_clear_bit((WAN_FE_LINENO(fe)%2), &cpld_reg_val);
|
|
aft_serial_write_cpld(card,(unsigned short)cpld_reg,(u16)cpld_reg_val);
|
|
break;
|
|
}
|
|
|
|
card->hw_iface.bus_write_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),reg);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
** wp_serial_post_init() -
|
|
**
|
|
** OK
|
|
*/
|
|
static int32_t wp_serial_post_init(void *pfe)
|
|
{
|
|
sdla_fe_t *fe = (sdla_fe_t*)pfe;
|
|
|
|
SERIAL_FUNC();
|
|
|
|
DEBUG_EVENT("%s: Running post initialization...\n", fe->name);
|
|
/* return sdla_rm_add_timer(fe, HZ); */
|
|
return 0;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
** wp_serial_if_config() -
|
|
**
|
|
** OK
|
|
*/
|
|
static int32_t wp_serial_if_config(void *pfe, u32 mod_map, u8 usedby)
|
|
{
|
|
SERIAL_FUNC();
|
|
return 0;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
** wp_serial_if_unconfig() -
|
|
**
|
|
** OK
|
|
*/
|
|
static int32_t wp_serial_if_unconfig(void *pfe, u32 mod_map, u8 usedby)
|
|
{
|
|
SERIAL_FUNC();
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
#if defined(NOTUSED)
|
|
/*******************************************************************************
|
|
* serial_enable_interrupts()
|
|
*
|
|
* Description: Enable SERIAL interrupts - start interrupt and set interrupt mask.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns:
|
|
*******************************************************************************/
|
|
static void serial_enable_interrupts(sdla_fe_t *fe, u32 mod_no, u8 port)
|
|
{
|
|
|
|
|
|
SERIAL_FUNC();
|
|
|
|
}
|
|
#endif
|
|
|
|
#if defined(NOTUSED)
|
|
/******************************************************************************
|
|
** wp_serial_disable_irq() - disable all interrupts by disabling M_GLOB_IRQ_EN
|
|
**
|
|
** OK
|
|
*/
|
|
static int32_t wp_serial_disable_irq(sdla_fe_t *fe, u32 mod_no, u8 port)
|
|
{
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
static u32 wp_serial_active_map(sdla_fe_t* fe, u8 line_no)
|
|
{
|
|
SERIAL_FUNC();
|
|
|
|
return 0x01;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* wp_serial_fe_status()
|
|
*
|
|
* Description:
|
|
* Arguments:
|
|
* Returns:
|
|
*******************************************************************************/
|
|
static u8 wp_serial_fe_media(sdla_fe_t *fe)
|
|
{
|
|
SERIAL_FUNC();
|
|
return fe->fe_cfg.media;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* wp_serial_set_dtmf()
|
|
*
|
|
* Description:
|
|
* Arguments:
|
|
* Returns:
|
|
*******************************************************************************/
|
|
static int32_t wp_serial_set_dtmf(sdla_fe_t *fe, int32_t mod_no, u8 val)
|
|
{
|
|
SERIAL_FUNC();
|
|
|
|
return -EINVAL;
|
|
}
|
|
|
|
#if 0
|
|
|
|
/*******************************************************************************
|
|
* sdla_serial_timer()
|
|
*
|
|
* Description:
|
|
* Arguments:
|
|
* Returns:
|
|
*******************************************************************************/
|
|
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
|
static void wp_serial_timer(void* pfe)
|
|
#elif defined(__WINDOWS__)
|
|
static void wp_serial_timer(IN PKDPC Dpc, void* pfe, void* arg2, void* arg3)
|
|
#else
|
|
static void wp_serial_timer(void *pfe)
|
|
#endif
|
|
{
|
|
SERIAL_FUNC();
|
|
return;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* wp_serial_enable_timer()
|
|
*
|
|
* Description: Enable software timer interrupt in delay ms.
|
|
* Arguments:
|
|
* Returns:
|
|
*******************************************************************************/
|
|
static void wp_serial_enable_timer(sdla_fe_t* fe, u8 mod_no, u8 cmd, u32 delay)
|
|
{
|
|
SERIAL_FUNC();
|
|
return;
|
|
}
|
|
|
|
static int32_t wp_serial_regdump(sdla_fe_t* fe, u8 *data)
|
|
{
|
|
SERIAL_FUNC();
|
|
return 0;
|
|
}
|
|
|
|
#endif /* if 0*/
|
|
|
|
static int32_t wp_serial_polling(sdla_fe_t* fe)
|
|
{
|
|
SERIAL_FUNC();
|
|
return 0;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* wp_serial_udp()
|
|
*
|
|
* Description:
|
|
* Arguments:
|
|
* Returns:
|
|
*******************************************************************************/
|
|
static int32_t wp_serial_udp(sdla_fe_t *fe, void* p_udp_cmd, u8* data)
|
|
{
|
|
wan_cmd_t *udp_cmd = (wan_cmd_t*)p_udp_cmd;
|
|
wan_femedia_t *fe_media;
|
|
|
|
switch(udp_cmd->wan_cmd_command){
|
|
case WAN_GET_MEDIA_TYPE:
|
|
fe_media = (wan_femedia_t*)data;
|
|
memset(fe_media, 0, sizeof(wan_femedia_t));
|
|
fe_media->media = fe->fe_cfg.media;
|
|
fe_media->sub_media = fe->fe_cfg.sub_media;
|
|
fe_media->chip_id = 0;
|
|
fe_media->max_ports = fe->fe_max_ports;
|
|
udp_cmd->wan_cmd_return_code = WAN_CMD_OK;
|
|
udp_cmd->wan_cmd_data_len = sizeof(wan_femedia_t);
|
|
break;
|
|
default:
|
|
udp_cmd->wan_cmd_return_code = WAN_UDP_INVALID_CMD;
|
|
udp_cmd->wan_cmd_data_len = 0;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*wp_serial_get_fe_status()
|
|
*
|
|
* Description : Get current FE line state - is it Connected or Disconnected
|
|
*
|
|
* Arguments : fe - pointer to Front End structure.
|
|
* status - pointer to location where the FE line state will
|
|
* be stored.
|
|
* notused - ignored
|
|
*
|
|
* Returns : always zero.
|
|
*******************************************************************************/
|
|
static int wp_serial_get_fe_status(sdla_fe_t *fe, unsigned char *status, int notused)
|
|
{
|
|
*status = fe->fe_status;
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* wp_serial_set_fe_status()
|
|
*
|
|
* Description : Set FE line state to Connected or Disconnected.
|
|
* In SERIAL this means Activate or Deactivate the line.
|
|
*
|
|
* Arguments : fe - pointer to Front End structure.
|
|
* new_status - the new FE line state.
|
|
*
|
|
* Returns : 0 - success.
|
|
* 1 - failure.
|
|
*******************************************************************************/
|
|
static int wp_serial_set_fe_status(sdla_fe_t *fe, unsigned char new_status)
|
|
{
|
|
int rc=0;
|
|
SERIAL_FUNC();
|
|
return rc;
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
* wp_serial_event_ctrl()
|
|
*
|
|
* Description: Enable/Disable event types
|
|
* Arguments: mod_no - Module number (1,2,3,... MAX_REMORA_MODULES)
|
|
* Returns:
|
|
******************************************************************************/
|
|
static int32_t
|
|
wp_serial_event_ctrl(sdla_fe_t *fe, wan_event_ctrl_t *ectrl)
|
|
{
|
|
int32_t err = 0;
|
|
|
|
SERIAL_FUNC();
|
|
|
|
WAN_ASSERT(ectrl == NULL);
|
|
|
|
return err;
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* wp_serial_intr_ctrl()
|
|
*
|
|
* Description: Enable/Disable extra interrupt types
|
|
* Arguments: mod_no - Module number (1,2,3,... MAX_REMORA_MODULES)
|
|
* Returns:
|
|
******************************************************************************/
|
|
static int wp_serial_intr_ctrl(sdla_fe_t *fe, int mod_no, u_int8_t type, u_int8_t mode, unsigned int ts_map)
|
|
{
|
|
|
|
SERIAL_FUNC();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#if defined(NOTUSED)
|
|
/******************************************************************************
|
|
* sdla_serial_set_status()
|
|
*
|
|
* Description: handle interrupt on a physical module
|
|
* Arguments: fe, mod_no
|
|
* Returns: 1 - interrupt recognized and handled
|
|
* 0 - interrupt not recognized (not generated by this module)
|
|
******************************************************************************/
|
|
static void sdla_serial_set_status(sdla_fe_t* fe, u8 mod_no, u8 port_no, u8 status)
|
|
{
|
|
sdla_t *card = (sdla_t*)fe->card;
|
|
u8 old_fe_status = fe->fe_status;
|
|
|
|
|
|
SERIAL_FUNC();
|
|
|
|
|
|
#if 0
|
|
if(old_fe_status == status){
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
fe->fe_status = status;
|
|
|
|
if (old_fe_status != fe->fe_status){
|
|
if (fe->fe_status == FE_CONNECTED){
|
|
DEBUG_EVENT("%s: %s Module: %d connected!\n",
|
|
fe->name,
|
|
FE_MEDIA_DECODE(fe), REPORT_MOD_NO + port_no);
|
|
|
|
if (card->wandev.te_report_alarms){
|
|
card->wandev.te_report_alarms(card, 0);
|
|
}
|
|
|
|
}else{
|
|
DEBUG_EVENT("%s: %s Module: %d disconnected!\n",
|
|
fe->name,
|
|
FE_MEDIA_DECODE(fe), REPORT_MOD_NO + port_no);
|
|
if (card->wandev.te_report_alarms){
|
|
card->wandev.te_report_alarms(card, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
static int32_t wp_serial_check_intr(sdla_fe_t *fe)
|
|
{
|
|
/* must return 1! */
|
|
return 1;
|
|
}
|
|
|
|
static int32_t wp_serial_intr(sdla_fe_t *fe)
|
|
{
|
|
sdla_t *card = (sdla_t*)fe->card;
|
|
u32 reg;
|
|
|
|
SERIAL_FUNC();
|
|
card->hw_iface.bus_read_4(card->hw,AFT_PORT_REG(card,AFT_SERIAL_LINE_CFG_REG),®);
|
|
DEBUG_EVENT("%s: DCD/CTS VALUES = 0x%02X\n",card->devname,(reg>>2)&0x03);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***************************************************************************
|
|
Front End T1/E1 interface for Normal cards
|
|
***************************************************************************/
|
|
int aft_serial_write_fe(void* phw, ...)
|
|
{
|
|
va_list args;
|
|
u16 qaccess, off, line_no;
|
|
u8 value;
|
|
// u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0;
|
|
|
|
va_start(args, phw);
|
|
qaccess = (u16)va_arg(args, int);
|
|
line_no = (u16)va_arg(args, int);
|
|
off = (u16)va_arg(args, int);
|
|
value = (u8)va_arg(args, int);
|
|
va_end(args);
|
|
|
|
SERIAL_FUNC();
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*============================================================================
|
|
* Read TE1/56K Front end registers
|
|
*/
|
|
|
|
|
|
u32 aft_serial_read_fe (void* phw, ...)
|
|
{
|
|
va_list args;
|
|
u_int16_t qaccess, line_no, off;
|
|
u_int8_t tmp=0;
|
|
// u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0;
|
|
|
|
va_start(args, phw);
|
|
qaccess = (u_int16_t)va_arg(args, int);
|
|
line_no = (u_int16_t)va_arg(args, int);
|
|
off = (u_int8_t)va_arg(args, int);
|
|
va_end(args);
|
|
|
|
SERIAL_FUNC();
|
|
|
|
return tmp;
|
|
}
|
|
|
|
int aft_serial_write_cpld(void *pcard, unsigned short off,u_int16_t data)
|
|
{
|
|
int err = -EINVAL;
|
|
sdla_t *card = (sdla_t*)pcard;
|
|
|
|
if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){
|
|
DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n",
|
|
card->devname, __FUNCTION__,__LINE__);
|
|
return 0x00;
|
|
}
|
|
|
|
if (card->hw_iface.write_cpld){
|
|
err = card->hw_iface.write_cpld(card->hw, (u16)off, (u8)data);
|
|
}
|
|
|
|
card->hw_iface.fe_clear_bit(card->hw,0);
|
|
return 0;
|
|
}
|
|
|
|
unsigned char aft_serial_read_cpld(void *pcard, unsigned short cpld_off)
|
|
{
|
|
u8 tmp=0;
|
|
int err = -EINVAL;
|
|
sdla_t *card = (sdla_t*)pcard;
|
|
|
|
if (card->hw_iface.fe_test_and_set_bit(card->hw,0)){
|
|
DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n",
|
|
card->devname, __FUNCTION__,__LINE__);
|
|
return 0x00;
|
|
}
|
|
|
|
if (card->hw_iface.read_cpld){
|
|
err = card->hw_iface.read_cpld(card->hw, (u16)cpld_off, &tmp);
|
|
}
|
|
|
|
card->hw_iface.fe_clear_bit(card->hw,0);
|
|
return tmp;
|
|
}
|