wanpipe-3.5.26.tgz

This commit is contained in:
Harald Welte 2021-12-29 18:52:56 +01:00
parent 88541d8e54
commit 50364198d5
72 changed files with 22839 additions and 392 deletions

View File

@ -1,2 +1,2 @@
wanpipe_linux: git ver 94892ae
wanpipe_common: git ver 707f538
wanpipe_linux: git ver 8ad2c16
wanpipe_common: git ver 7bd220e

View File

@ -1 +1 @@
wanpipe-3.5.25
wanpipe-3.5.26

View File

@ -8,13 +8,48 @@ Copyright (c) 1995-2012 Sangoma Technologies Inc.
For more info visit: http://wiki.sangoma.com
------------------------------------------------------------------------------
* Tue Apr 24 2012 Nenad Corbic <ncorbic@sangoma.com> - 3.5.26
==================================================================
- Wanpipe W400 GSM support: Asterisk/Dahdi & FreeSWITCH/FreeTDM
- Wanpipe B610 FXS support
- Fixed Dahdi 2.5 and higher hwec autodetection
For dahdi 2.5 and higher the HWEC option was needed in
dahdi/system.conf to enable onboard hwec.
This fix allows default mg2 software echo to be specified
in dahdi/system.conf, and dahdi will autodetect the sangoma onboard hwec.
- Fixed sangoma hwec boards to use dahdi software ec if hwec is turned off.
Wanpipe driver did not allow sangoma hwec enabled boards to use dahdi
software ec even if hwec was turned off in wanpipe1.conf
This has now been fixed.
If TDMV_HWEC=NO is set in wanpipe1.conf dahdi will now use software ec.
- Fixed BRI dchan reliability
- Fixed BRI for 64bit
The fix for audio issue in 3.5.25 caused the issue on 64bit.
- Dahdi build bug fixes for Trixbox
- Zaptel build bug fixes from 3.5.25
- Build fixes for 3.1.X kernel.
- Fake polarity feature used for Euro Caller ID
- E1 NCRC CAS Framer Configuration for Latin America
Previous NCRC Framer config did not work in all cases.
Affects protocols such as MFC-R2 or CAS
- Analog boards with network sync option set to yes:
Default to fax mode buffering.
Use "when full" dahdi buffer policy.
Improves faxing from PRI to Analog with sync cable.
- Fixed wancfg_dahdi to:
start asterisk using safe_asterisk
to properly detect dahdi version
* Tue Feb 21 2012 Nenad Corbic <ncorbic@sangoma.com> - 3.5.25
==================================================================
- Dahdi 2.6 support
- Linux 3.2.6 support
- Support for B610 Single FXS card
- Support for B500 4 port BRI card
- Support for B610 Single FXS board
- Support for B500 4 port BRI board
- Reduced memory foot print of the driver
by removing some unused statistics structures
- New HWEC firmare v1.7.4 fixes delayed fax issus
@ -51,7 +86,7 @@ For more info visit: http://wiki.sangoma.com
* Wed Aug 24 2011 Nenad Corbic <ncorbic@sangoma.com> - 3.5.22
==================================================================
- Bug introducted in .21 release for analog card.
- Bug introducted in .21 release for analog board.
Changed the way wanpipe enumerates analog channels
breaks backward compatibility. Reverted to original.
@ -162,7 +197,7 @@ For more info visit: http://wiki.sangoma.com
- Added SW HDLC into the core. B
- B601 is now supported on FreeTDM/FreeSWITCH and TMDAPI
- Added wan_fxotune utility to utils directory
Used to tune fxo cards under TDM API or FreeSWITCH mode.
Used to tune fxo boards under TDM API or FreeSWITCH mode.
@ -181,7 +216,7 @@ For more info visit: http://wiki.sangoma.com
dma overruns.
- Bug fix in tdmapi where excessive memory was allocated on pre-allocation buffers.
- Bug fix tdmapi defaults to 20ms chunk size instead of 10ms
- Bug fix broken support for A101/2 legacy EOL cards.
- Bug fix broken support for A101/2 legacy EOL boards.
- New XEN Support
TDM Voice will now work properly on xen virtualized machines
- Fix for 64bit 8gig issues
@ -214,11 +249,11 @@ For more info visit: http://wiki.sangoma.com
===================================================================
- Fixed Dahdi 2.3 Support
- Fixed FreeSwitch Openzap HardHDLC option for AFT cards
- Fixed wanpipemon support for non aft cards.
- Fixed FreeSwitch Openzap HardHDLC option for AFT boards
- Fixed wanpipemon support for non aft boards.
- Merged USB FXO code from 3.6 release
- USB FXO bug fix for 2.6.32 kernels
- Support for B800 Analog card
- Support for B800 Analog board
- Fixed alarm reporting in DAHDI/ZAPTEL
- Added Extra EC DSP Configuration Options
@ -311,7 +346,7 @@ For more info visit: http://wiki.sangoma.com
- Fixed Tx Tristate
- Updated yellow alarm handling for Dallas maxim cards
- Updated yellow alarm handling for Dallas maxim boards
(A101/2/4/8)
- Autodetect USB support so that driver will compile
@ -325,7 +360,7 @@ For more info visit: http://wiki.sangoma.com
- Update to T1 Yellow Alarm handling.
In some cases Yellow alarm did not turn off poperly causing
line to stay down an card startup.
line to stay down an board startup.
- Update configuration utility
wancfg_fs updated for sangoma_prid configuration. Added wancfg_openzap
for OpenZap Configuration
@ -341,10 +376,10 @@ For more info visit: http://wiki.sangoma.com
- Updated for 2.6.30 kernel
- New firmawre feature for A101/2/5/8: Free Run Timer Interrupt
The AFT T1/E1 cards will now provide perfect timing to zatpel/dahdi
The AFT T1/E1 boards will now provide perfect timing to zatpel/dahdi
even when the ports are not connected. The free run interrupt
will be enabled when all zaptel/dahdi ports are down, or on
inital card start. To test this feature just start a wanpipe
inital board start. To test this feature just start a wanpipe
port with zaptel/dahdi and run zttest.
A108 firmare V38
A104/2/1/ firmware V36
@ -382,7 +417,7 @@ For more info visit: http://wiki.sangoma.com
- TDM API
Updated the Global TDM Device
This device can be used to read events an all cards configured in
This device can be used to read events an all boards configured in
TDM API mode.
- Libsangoma verion 3.1.0
@ -453,7 +488,7 @@ For more info visit: http://wiki.sangoma.com
* Fri May 08 2009 Nenad Corbic <ncorbic@sangoma.com> - 3.5.2
===================================================================
- B700 PCIe cards were being displayed as PCI cards in hwprobe
- B700 PCIe boards were being displayed as PCI boards in hwprobe
- Bug fix in wancfg_zaptel
* Thu May 07 2009 Nenad Corbic <ncorbic@sangoma.com> - 3.5.1
@ -477,7 +512,7 @@ For more info visit: http://wiki.sangoma.com
- Unified driver for Linux & Windows
- Updated BRI Stack and Support
- New BRI A500 & B700 firmware that fixes PCI parity errors.
On some systems A500 & B700 cards can generate parity errors.
On some systems A500 & B700 boards can generate parity errors.
- FreeSwitch Tested
- Update for 2.6.26 kernel

18
Setup
View File

@ -2,7 +2,7 @@
#
# Setup WANPIPE WAN Router Installation/Removal Script.
#
# Copyright (c) 1996-2011, Sangoma Technologies Inc.
# Copyright (c) 1996-2012, 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
@ -291,7 +291,7 @@ banner()
echo -e "\t----------------------------------------------------------"
echo -e "\t WANPIPE v$PROD_VER Installation Script"
echo -e "\t Copyright (c) 1995-2011, Sangoma Technologies Inc."
echo -e "\t Copyright (c) 1995-2012, Sangoma Technologies Inc."
echo -e "\t----------------------------------------------------------"
echo ""
@ -914,7 +914,7 @@ get_kernel_ver ()
KERNEL_VERSION=$KVER"."$KPATCH"."$KLVL$KEVER
if [ "$KVER" -eq "3" ] && [ "$KPATCH" -eq "0" ]; then
if [ "$KVER" -eq "3" ]; then
KERN_VER=30;
LINUXDRIVERS_NET="drivers/net/wan"
elif [ "$KVER" -eq "2" ] && [ "$KPATCH" -eq "6" ]; then
@ -3331,8 +3331,8 @@ ENDOFTEXT
eval "grep \"define *CONFIG_MODVERSIONS\" $SOURCEDIR/include/linux/autoconf.h > /dev/null"
if [ $? -eq 0 ]; then
if [ $KERN_VER -ne 26 ] || [ $KERN_VER -ne 30 ]; then
MODVER=" -DMODVERSIONS -include $SOURCEDIR/include/linux/modversions.h "
if [ $KERN_VER -ne 26 ] && [ $KERN_VER -ne 30 ]; then
MODVER=" -DMODVERSIONS -include $SOURCEDIR/include/linux/modversions.h "
fi
MOD_ENABLED=y
else
@ -3994,12 +3994,13 @@ WANPIPE_OBJS=
if [ "$TDM_PROT" = "YES" ]; then
\cp $DRIVER_UPDATE_DIR/src/net/sdla_tdmv.c .
\cp $DRIVER_UPDATE_DIR/src/net/sdla_remora_tdmv.c .
\cp $DRIVER_UPDATE_DIR/src/net/sdla_gsm_tdmv.c .
\cp $DRIVER_UPDATE_DIR/src/net/sdla_bri_tdmv.c .
\cp $DRIVER_UPDATE_DIR/src/net/sdla_tdmv_dummy.c .
if [ -e $DRIVER_UPDATE_DIR/src/net/sdla_usb_remora_tdmv.c ]; then
\cp $DRIVER_UPDATE_DIR/src/net/sdla_usb_remora_tdmv.c .
fi
WANPIPE_OBJS=$WANPIPE_OBJS"sdla_tdmv sdla_remora_tdmv sdla_bri_tdmv sdla_tdmv_dummy "
WANPIPE_OBJS=$WANPIPE_OBJS"sdla_tdmv sdla_gsm_tdmv sdla_remora_tdmv sdla_bri_tdmv sdla_tdmv_dummy "
WANPIPE_EXTRA_CFLAGS=$WANPIPE_EXTRA_CFLAGS"-I$ZAPTEL_SOURCE_DIR "
if [ -f $ZAPTEL_SOURCE_DIR/dahdi/kernel.h ]; then
# this is required for some dependencies of kernel.h (dahdi_config.h, ecdis.h etc)
@ -4049,7 +4050,8 @@ WANPIPE_OBJS=
WANPIPE_OBJS=$WANPIPE_OBJS"sdla_56k sdla_te1 sdla_8te1 sdla_te3 sdla_ft1 wanpipe_utils wanpipe_abstr wanpipe_linux_iface wanpipe_mtp1 "
# GSM always built
WANPIPE_OBJS=$WANPIPE_OBJS"sdla_gsm aft_gsm "
if [ $? -eq 0 ]; then
echo -e "Done.\n"
@ -7330,7 +7332,7 @@ KERNEL_UNAME=`uname -r`
PKG_NAME=wanpipe
DISTR_NAME="WANPIPE"
PROD=wanrouter
PROD_VER=3.5.25
PROD_VER=3.5.26
PROD_HOME=`pwd`
META_CONF=$PROD_HOME/$PROD.rc
WAN_INTR_DIR=$PROD_HOME/interfaces

View File

@ -191,7 +191,7 @@ enum {
#define X25_MAX_DATA 1024 /* max length of X.25 data buffer */
#define X25_MAX_DATA 4096 /* max length of X.25 data buffer */
#pragma pack(1)
typedef struct {

View File

@ -1,5 +1,5 @@
Package: wanpipe
Version: 3.5.25-0
Version: 3.5.26-0
Section: networking
Priority: optional
Architecture: all

View File

@ -41,6 +41,7 @@
#include "aft_a104.h"
#include "aft_analog.h"
#include "aft_bri.h"
#include "aft_gsm.h"
#if defined(__WINDOWS__)

View File

@ -230,17 +230,18 @@ typedef struct aft_config
unsigned int aft_dma_control_reg;
}aft_config_t;
static __inline u32 AFT_PORT_REG(sdla_t *card, u32 reg)
{
if (card->adptr_type == AFT_ADPTR_A600 ||
card->adptr_type == AFT_ADPTR_B610 ||
card->adptr_type == AFT_ADPTR_B601) {
//A600 CASE
if (AFT_NEEDS_DEFAULT_REG_OFFSET(card->adptr_type)) {
char comm_port = card->wandev.comm_port;
if (card->adptr_type == AFT_ADPTR_W400) {
/* Force GSM comm port to 0, as we fake ports in the driver */
comm_port = 0;
}
if (reg < 0x100) {
return (reg+0x1000);
} else {
return (reg+0x2000)+(0x8000*card->wandev.comm_port);
return (reg+0x2000)+(0x8000*comm_port);
}
} else {
if (reg < 0x100) {
@ -640,6 +641,10 @@ void aft_list_tx_descriptors(private_area_t *chan);
#define CHAN_GLOBAL_IRQ_CFG(chan) (chan->channelized_cfg && !chan->hdlc_eng && !chan->sw_hdlc_mode)
#define AFT_HAS_FAKE_PORTS(card) (IS_BRI_CARD(card) || IS_GSM_CARD(card))
#define AFT_HAS_FAKE_DCHAN(card) (IS_BRI_CARD(card) || IS_GSM_CARD(card))
#define AFT_MAX_PORTS(card) IS_BRI_CARD(card) ? MAX_BRI_LINES : IS_GSM_CARD(card) ? MAX_GSM_MODULES : 8
#endif /* WAN_KERNEL */

View File

@ -0,0 +1,40 @@
/*****************************************************************************
* aft_gsm.c
*
* WANPIPE(tm) AFT W400 Hardware Support
*
* Authors: Moises Silva <moy@sangoma.com>
*
* Copyright: (c) 2011 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.
* ============================================================================
* Oct 06, 2011 Moises Silva Initial Version
*****************************************************************************/
#ifndef __AFT_GSM_H_
#define __AFT_GSM_H_
#ifdef WAN_KERNEL
int aft_gsm_global_chip_config(sdla_t *card);
int aft_gsm_global_chip_unconfig(sdla_t *card);
int aft_gsm_chip_config(sdla_t *card, wandev_conf_t *);
int aft_gsm_chip_unconfig(sdla_t *card);
int aft_gsm_chan_dev_config(sdla_t *card, void *chan);
int aft_gsm_chan_dev_unconfig(sdla_t *card, void *chan);
int aft_gsm_led_ctrl(sdla_t *card, int color, int led_pos, int on);
int aft_gsm_test_sync(sdla_t *card, int tx_only);
unsigned char aft_gsm_read_cpld(sdla_t *card, unsigned short cpld_off);
int aft_gsm_write_cpld(sdla_t *card, unsigned short off,u_int16_t data);
void aft_gsm_fifo_adjust(sdla_t *card,u32 level);
int w400_check_ec_security(sdla_t *card);
#endif
#endif

View File

@ -15,6 +15,7 @@
# include "sdla_remora.h"
# include "sdla_bri.h"
# include "sdla_serial.h"
# include "sdla_gsm.h"
/*
*************************************************************************
@ -33,6 +34,7 @@
#define WAN_MEDIA_FXOFXS 0x08
#define WAN_MEDIA_BRI 0x09
#define WAN_MEDIA_SERIAL 0x0A
#define WAN_MEDIA_GSM 0x0B
/*The line code */
#define WAN_LCODE_NONE 0x00
@ -156,6 +158,7 @@
#define IS_E3_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_E3)
#define IS_FXOFXS_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_FXOFXS)
#define IS_BRI_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_BRI)
#define IS_GSM_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_GSM)
#define IS_SERIAL_MEDIA(fe_cfg) (FE_MEDIA(fe_cfg) == WAN_MEDIA_SERIAL)
#define IS_TXTRISTATE(fe_cfg) (FE_TXTRISTATE(fe_cfg) == WANOPT_YES)
@ -293,9 +296,11 @@ typedef struct
/* Front-End status */
#define FE_STATUS_DECODE(fe_status) \
(fe_status == FE_UNITIALIZED) ? "unitialized" : \
(fe_status == FE_UNITIALIZED) ? "uninitialized" : \
(fe_status == FE_DISCONNECTED) ? "disconnected": \
(fe_status == FE_CONNECTED) ? "connected" : \
(fe_status == FE_CONNECTING) ? "connecting" : \
(fe_status == FE_DISCONNECTING) ? "disconnecting" : \
"unknown"
#define WAN_FE_STATUS_DECODE(fe) FE_STATUS_DECODE((fe)->fe_status)
@ -315,6 +320,7 @@ typedef struct
#define IS_56K_FEMEDIA(fe) IS_56K_MEDIA(&((fe)->fe_cfg))
#define IS_J1_FEMEDIA(fe) IS_J1_MEDIA(&((fe)->fe_cfg))
#define IS_FXOFXS_FEMEDIA(fe) IS_FXOFXS_MEDIA(&((fe)->fe_cfg))
#define IS_GSM_FEMEDIA(fe) IS_GSM_MEDIA(&((fe)->fe_cfg))
#define IS_FE_TXTRISTATE(fe) IS_TXTRISTATE(&((fe)->fe_cfg))
#define IS_FR_FEUNFRAMED(fe) IS_FR_UNFRAMED(&((fe)->fe_cfg))
#define IS_BRI_FEMEDIA(fe) IS_BRI_MEDIA(&((fe)->fe_cfg))
@ -341,6 +347,7 @@ typedef struct
#define WAN_FE_MAX_CHANNELS(fe) \
(IS_TE1_FEMEDIA(fe)) ? GET_TE_CHANNEL_RANGE(fe) : \
(IS_FXOFXS_FEMEDIA(fe)) ? MAX_FXOFXS_CHANNELS : \
(IS_GSM_FEMEDIA(fe)) ? MAX_GSM_CHANNELS : \
(IS_BRI_FEMEDIA(fe)) ? MAX_BRI_CHANNELS : 0
#if 0
@ -500,6 +507,7 @@ typedef struct {
sdla_te3_param_t te3;
sdla_remora_param_t remora;
sdla_bri_param_t bri;
sdla_gsm_param_t gsm;
} fe_param;
#define fe_alarm fe_stats.alarms
sdla_fe_stats_t fe_stats;

View File

@ -0,0 +1,192 @@
/******************************************************************************
* sdla_gsm.h
*
* Author: Moises Silva <moy@sangoma.com>
*
* Copyright: (c) 2011 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.
* ============================================================================
* Oct 06, 2011 Moises Silva Initial Version
******************************************************************************
*/
#ifndef __SDLA_GSM_H
#define __SDLA_GSM_H
#if (defined __WINDOWS__)
# define inline __inline
#endif
/* W400 has 4 GSM modules. Each module has one voice channel and one fake D-channel */
#define MAX_GSM_MODULES 4
/* All modules masked (4 modules, 1111) */
#define AFT_GSM_ALL_MODULES_MASK 0x000F
/* Assumed the last channel is the HDLC channel */
#define MAX_GSM_CHANNELS 2
#define MAX_GSM_TIMESLOTS 32
/* where in the span channel array indexes we have voice and data */
#define GSM_VOICE_CHANNEL 0
#define GSM_UART_CHANNEL 1
/* 31th chan (zero-based) will have the dchan */
#define GSM_DCHAN_LOGIC_CHAN 31
#define IS_GSM_CARD(card) IS_GSM_FEMEDIA(&(card)->fe)
/* Global register */
#define AFT_GSM_GLOBAL_REG 0x1400
/* Starting configuration register (incremented by AFT_GSM_REG_OFFSET for each module) */
#define AFT_GSM_CONFIG_REG 0x1200
/* UART tx/rx data and status registers (incremented by AFT_GSM_REG_OFFSET for each module) */
#define AFT_GSM_UART_TX_REG 0x1300
#define AFT_GSM_UART_RX_REG 0x1310
#define AFT_GSM_UART_STAT_REG 0x1320
/* Per module register offset */
#define AFT_GSM_REG_OFFSET 0x0004
/* Our FIFO size for the UART */
#define AFT_GSM_UART_TX_FIFO_SIZE 15
#define AFT_GSM_UART_RX_FIFO_SIZE 66
/* UART status */
#define AFT_GSM_UART_TX_FIFO_DATA_COUNT_MASK 0x0F
#define AFT_GSM_UART_RX_FIFO_DATA_COUNT_MASK 0x7F
#define AFT_GSM_UART_RX_FIFO_DATA_COUNT_OFFSET 8
#define AFT_GSM_UART_TX_FIFO_OVERFLOW_BIT 16
#define AFT_GSM_UART_RX_FIFO_OVERFLOW_BIT 17
/* PLL status bits in the global register */
#define AFT_GSM_PLL_RESET_BIT 0
#define AFT_GSM_PLL_PHASE_SHIFT_OVERFLOW_BIT 1
#define AFT_GSM_PLL_INPUT_CLOCK_LOST_BIT 2
#define AFT_GSM_PLL_OUTPUT_CLOCK_STOPPED_BIT 3
#define AFT_GSM_PLL_LOCKED_BIT 4
/* SIM muxing error in the global register */
#define AFT_GSM_SIM_MUXING_ERROR_BIT 5
/* PCM audio loop, all audio going towards the Digital Voiceband Interface (DVI) will be looped back,
* this is only useful for debugging purposes */
#define AFT_GSM_GLOBAL_PCM_LOOPBACK_BIT 30
/* Shutdown 3.8v for all modules (active 0) in the global register */
#define AFT_GSM_GLOBAL_SHUTDOWN_BIT 31
/*!< Retrieve the register address for a module */
#define AFT_GSM_MOD_REG(mod_no, reg) (reg + ((mod_no-1) * AFT_GSM_REG_OFFSET))
/*!< GSM module configuration (bit numbers are zero-based) */
#define AFT_GSM_MOD_POWER_BIT 0x0
#define AFT_GSM_MOD_RESET_BIT 0x1
#define AFT_GSM_MOD_POWER_MONITOR_BIT 0x2
#define AFT_GSM_MOD_TX_MONITOR_BIT 0x3
#define AFT_GSM_MOD_SIM_INSERTED_BIT 0x4
/*!< The high order last 3 bits of first byte of the module configuration register select the SIM */
#define AFT_GSM_MOD_SIM_BIT_OFFSET 5
#define AFT_GSM_MOD_SIM_MASK (0x7 << AFT_GSM_MOD_SIM_BIT_OFFSET)
/*!< The first 3 bits of the second byte select the UART baud rate */
#define AFT_GSM_MOD_UART_BAUD_RATE_BIT_OFFSET 0x8
#define AFT_GSM_MOD_UART_BAUD_RATE_MASK (0x7 << AFT_GSM_MOD_UART_BAUD_RATE_BIT_OFFSET)
/*!< The fourth bit of the second byte report if there is service or not */
#define AFT_GSM_MOD_SERVICE_BIT 0xB
/*!< The fifth bit of the second byte report if there is a module (cell phone) present or not */
#define AFT_GSM_MOD_PRESENT_BIT 0xC
/*! Absolute timeout to power on/off a module
* Telit data sheet suggests 2 seconds, in real life for W400
* I've seen power off take more than that, 3-4 seconds, so
* I decided to boost this to 10 seconds to be ultra-safe
* The only down-side of this will be if we ever need to
* use the "slow hwprobe" mechanism that attempts to power on/off
* the modules the first time hwprobe is run, because a timeout
* of 10 seconds will slow down a lot the first hwprobe in cases where
* the module is not present (see sdladrv.c slow hw probe define)
* since currently we do not use the "slow hwprobe" mode and rely
* instead on the GSM hw FPGA register to tell us if the module
* is present or not, we should be fine ...
* */
#define AFT_GSM_MODULE_POWER_TOGGLE_TIMEOUT_MS 10000
/*!< How often to check if the module is already on/off during startup/shutdown */
#define AFT_GSM_MODULE_POWER_TOGGLE_CHECK_INTERVAL_MS 10
/*! Absolute timeout to enable PLL */
#define AFT_GSM_PLL_ENABLE_TIMEOUT_MS 2000
/*!< How often to check if the PLL is already enabled on startup */
#define AFT_GSM_PLL_ENABLE_CHECK_INTERVAL_MS 10
/*! How much to wait between power registry writes
* Telit data sheet says input command for switch off/on must be equal or bigger to 1 second,
* we give it 100ms more in case the host scheduling is somewhat faster */
#define AFT_GSM_MODULE_POWER_TOGGLE_DELAY_MS 1100
/* Transform from module index to bit index in bit map */
#define AFT_GSM_MOD_BIT(mod_no) (mod_no - 1)
static inline int aft_gsm_get_sim_no(int reg)
{
reg &= AFT_GSM_MOD_SIM_MASK;
return (reg >> AFT_GSM_MOD_SIM_BIT_OFFSET);
}
static inline void aft_gsm_set_sim_no(int *reg, int sim_no)
{
sim_no <<= AFT_GSM_MOD_SIM_BIT_OFFSET;
*reg |= (sim_no & AFT_GSM_MOD_SIM_MASK);
}
static inline int aft_gsm_get_uart_baud_rate(int reg)
{
reg &= AFT_GSM_MOD_UART_BAUD_RATE_MASK;
return (reg >> AFT_GSM_MOD_UART_BAUD_RATE_BIT_OFFSET);
}
int wp_gsm_iface_init(void*, void*);
int wp_gsm_uart_rx_fifo(void *card, unsigned char *rx_buff, int reqlen);
int wp_gsm_uart_check_tx_fifo(void *card);
int wp_gsm_uart_tx_fifo(void *card, unsigned char *tx_buff, int len);
int wp_gsm_pll_reset(void *card);
int wp_gsm_update_sim_status(void *card);
typedef struct wan_gsm_udp {
union {
char uart_debug;
} u;
} wan_gsm_udp_t;
/* used by gsm front end code to store GSM-specific data */
#define GSM_MAX_UART_FRAME_LEN 300
typedef struct sdla_gsm_param {
unsigned char uart_txbuf[GSM_MAX_UART_FRAME_LEN];
int uart_txbuf_len;
int uart_tx_cnt;
} sdla_gsm_param_t;
/* Front-End UDP command */
#define WAN_GSM_REGDUMP (WAN_FE_UDP_CMD_START + 0)
#define WAN_GSM_UART_DEBUG (WAN_FE_UDP_CMD_START + 1)
#define WAN_GSM_AUDIO_DEBUG (WAN_FE_UDP_CMD_START + 2)
#define WAN_GSM_PLL_RESET (WAN_FE_UDP_CMD_START + 3)
#define WAN_GSM_POWER_TOGGLE (WAN_FE_UDP_CMD_START + 4)
#define WAN_GSM_UPDATE_SIM_STATUS (WAN_FE_UDP_CMD_START + 5)
#define WAN_GSM_PCM_LOOPBACK (WAN_FE_UDP_CMD_START + 6)
#define AFT_GSM_UART_DEBUG_ENABLED_BIT 1
#define AFT_GSM_AUDIO_DEBUG_TOGGLE_BIT 2
#endif /* __SDLA_GSM_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,113 @@
/******************************************************************************
* sdla_gsm_inline.h
*
* Author: Moises Silva <moy@sangoma.com>
*
* Copyright: (c) 2011 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.
* ============================================================================
* Dec 09, 2011 Moises Silva Initial Version
******************************************************************************
*/
#ifndef __SDLA_GSM_INLINE_H
#define __SDLA_GSM_INLINE_H
/* XXX This mess was brought to you by <moy@sangoma.com> ... XXX
* I could not find a way to abstract the module power on/off code in a way could be used
* by sdladrv.c for hardware probe, aft_gsm.c for port start/stop, and sdla_gsm.c
* for wanpipemon handling of fixed start/stop of the modules without messing with the build
* in such a painful way that I'd rather die first, so I added this function here,
* in a way can be included by each file that uses it ... */
static __inline int wp_gsm_toggle_power(void *phw, int mod_map, int turn_on)
{
u32 reg[MAX_GSM_MODULES+1]; /* mod_no is not zero-based */
int timeout_loops = 0;
int mod_no = 1;
sdlahw_t *hw = phw;
const char *devname = hw->devname;
/*
* Power toggle sequence as described by the Telit documentation
* We have a power monitor pin that tells us whether the module is on/off
* We have a power pin that is equivalent to the power on/off button on your cell phone
* In order to turn on/off we hold high the power pin for at least one second and then
* set it low. Then we monitor the power monitor pin until goes high/low depending on
* whether we're turning on or off the module
*
* Note that in the Telit documentation you will see the high/low order inversed, there
* is an inversor in our hardware doing that, ask our hw engineers why? :-)
*/
for (mod_no = 1; mod_no <= MAX_GSM_MODULES; mod_no++) {
if (!wan_test_bit(AFT_GSM_MOD_BIT(mod_no), &mod_map)) {
continue;
}
reg[mod_no] = 0;
__sdla_bus_read_4(hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_CONFIG_REG), &reg[mod_no]);
/* if we were asked to turn the module on and is on, we're done */
if (turn_on && wan_test_bit(AFT_GSM_MOD_POWER_MONITOR_BIT, &reg[mod_no])) {
DEBUG_EVENT("%s: GSM module %d is already on, skipping power toggle ...\n", devname, mod_no);
wan_clear_bit(AFT_GSM_MOD_BIT(mod_no), &mod_map);
continue;
}
/* if we were asked to turn the module off and is off, we're done */
if (!turn_on && !wan_test_bit(AFT_GSM_MOD_POWER_MONITOR_BIT, &reg[mod_no])) {
DEBUG_EVENT("%s: GSM module %d is already off, skipping power toggle ...\n", devname, mod_no);
wan_clear_bit(AFT_GSM_MOD_BIT(mod_no), &mod_map);
continue;
}
DEBUG_EVENT("%s: Turning GSM module %d %s ...\n", devname, mod_no, turn_on ? "on" : "off");
wan_set_bit(AFT_GSM_MOD_POWER_BIT, &reg[mod_no]);
__sdla_bus_write_4(hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_CONFIG_REG), reg[mod_no]);
}
/* no modules to toggle */
if (!mod_map) {
return 0;
}
WP_DELAY(AFT_GSM_MODULE_POWER_TOGGLE_DELAY_MS * 1000);
/* restore the power bit in all modules */
for (mod_no = 1; mod_no <= MAX_GSM_MODULES; mod_no++) {
if (!wan_test_bit(AFT_GSM_MOD_BIT(mod_no), &mod_map)) {
continue;
}
wan_clear_bit(AFT_GSM_MOD_POWER_BIT, &reg[mod_no]);
__sdla_bus_write_4(hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_CONFIG_REG), reg[mod_no]);
}
/* monitor the modules to see if they power on/off */
for (timeout_loops = (AFT_GSM_MODULE_POWER_TOGGLE_TIMEOUT_MS / AFT_GSM_MODULE_POWER_TOGGLE_CHECK_INTERVAL_MS);
(timeout_loops && mod_map);
timeout_loops--) {
WP_DELAY(AFT_GSM_MODULE_POWER_TOGGLE_CHECK_INTERVAL_MS * 1000);
for (mod_no = 1; mod_no <= MAX_GSM_MODULES; mod_no++) {
if (!wan_test_bit(AFT_GSM_MOD_BIT(mod_no), &mod_map)) {
continue;
}
reg[mod_no] = 0;
__sdla_bus_read_4(hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_CONFIG_REG), &reg[mod_no]);
/* if we were asked to turn the module on and is on, we're done */
if (turn_on && wan_test_bit(AFT_GSM_MOD_POWER_MONITOR_BIT, &reg[mod_no])) {
DEBUG_EVENT("%s: GSM module %d is now on ...\n", devname, mod_no);
wan_clear_bit(AFT_GSM_MOD_BIT(mod_no), &mod_map);
}
/* if we were asked to turn the module off and is off, we're done */
if (!turn_on && !wan_test_bit(AFT_GSM_MOD_POWER_MONITOR_BIT, &reg[mod_no])) {
DEBUG_EVENT("%s: GSM module %d is now off ...\n", devname, mod_no);
wan_clear_bit(AFT_GSM_MOD_BIT(mod_no), &mod_map);
}
}
}
/* return a map of the modules that failed to turn on/off (if any) */
return mod_map;
}
#endif /* __SDLA_GSM_INLINE_H */

View File

@ -0,0 +1,51 @@
/******************************************************************************
* sdla_gsm_tdmv.h
*
* Author: Moises Silva <moy@sangoma.com>
*
* Copyright: (c) 2011 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.
* ============================================================================
* Oct 11, 2011 Moises Silva Initial Version
******************************************************************************
*/
#include "wanpipe_defines.h"
#include "sdla_tdmv.h"
#include "zapcompat.h" /* Map of Zaptel -> DAHDI definitions */
typedef struct wp_tdmv_gsm_ {
/*! Wanpipe card structre */
sdla_t *card;
/*! Shortcut to card->devname */
char *devname;
/*! Wanpipe GSM span number */
int num;
/*! Sanity check flags */
int flags;
/* DAHDI span number (as assigned in Wanpipe configuration) */
int spanno;
/*! DAHDI span and channels */
#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE)
struct zt_span span;
#ifdef DAHDI_ISSUES
struct zt_chan *chans_ptrs[MAX_GSM_CHANNELS];
#endif
struct zt_chan chans[MAX_GSM_CHANNELS];
#endif
/*! Number of users of this span (for sanity checks) */
int usecount;
/*! Debug audio buffer index */
int audio_debug_i;
unsigned char ec_chunk[ZT_CHUNKSIZE];
#ifdef DAHDI_26
struct dahdi_device *ddev;
struct device dev;
#endif
} wp_tdmv_gsm_t;

View File

@ -175,7 +175,9 @@ typedef struct sdla_remora_cfg_ {
int fxs_ringampl;
u_int8_t rm_mode; /*Analog Operation mode: default or tapping */
u_int8_t fake_polarity;
u_int8_t fake_polarity; /*FAKE Polarity event generation : YES or NO*/
int fake_polarity_thres; /*Threshold value(only for Analoge cards,units defined in L16 sample value)
to decide generation of FAKE Polarity event*/
u_int8_t rm_lcm; /*Analog Loop Current Measure (LCM) : Yes Or NO */
} sdla_remora_cfg_t;
@ -359,15 +361,14 @@ typedef struct {
unsigned char imask; /* interrupt mask */
int readcid;
unsigned int cidtimer;
/*Additional for Zaptel mode*/
#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE)
int echotune; /* echo tune */
struct wan_rm_echo_coefs echoregs; /* echo tune */
int readcid;
unsigned int cidtimer;
#endif
} wp_remora_fxo_t;
typedef struct {

View File

@ -107,6 +107,7 @@ WP_EXTERN int wp_tdmv_bri_init(wan_tdmv_iface_t *iface);
#if defined(CONFIG_PRODUCT_WANPIPE_USB)
WP_EXTERN int wp_usb_tdmv_remora_init(wan_tdmv_iface_t *iface);
#endif
WP_EXTERN int wp_tdmv_gsm_init(wan_tdmv_iface_t *iface);
#ifdef CONFIG_PRODUCT_WANPIPE_TDM_VOICE_ECHOMASTER
WP_EXTERN int wp_tdmv_echo_check(wan_tdmv_t *wan_tdmv, void *current_ztchan, int channo);

View File

@ -235,6 +235,11 @@ struct sdlahw_dev;
#define IS_HWCARD_PCIE(hwcard) ((hwcard)->hw_type == SDLA_PCI_EXP_CARD)
#define IS_HWCARD_USB(hwcard) ((hwcard)->hw_type == SDLA_USB_CARD)
#define AFT_NEEDS_DEFAULT_REG_OFFSET(adptr_type) \
((adptr_type == AFT_ADPTR_A600) || \
(adptr_type == AFT_ADPTR_B610) || \
(adptr_type == AFT_ADPTR_B601) || \
(adptr_type == AFT_ADPTR_W400))
#if defined(__FreeBSD__)
# if defined(__i386__)
@ -767,6 +772,7 @@ typedef struct sdla_hw_type_cnt
unsigned char aft_x_adapters;
unsigned char usb_adapters;
unsigned char aft_w400_adapters;
}sdla_hw_type_cnt_t;
typedef struct sdladrv_callback_ {
@ -1257,10 +1263,8 @@ static __inline u32 SDLA_REG_OFF(sdlahw_card_t *hwcard, u32 reg)
DEBUG_EVENT("sdladrv: Critical error: hw or hw->cpu is NULL\n");
return reg;
}
if (hwcard->adptr_type == AFT_ADPTR_A600 ||
hwcard->adptr_type == AFT_ADPTR_B610 ||
hwcard->adptr_type == AFT_ADPTR_B601) {
if (AFT_NEEDS_DEFAULT_REG_OFFSET(hwcard->adptr_type)) {
if (reg < 0x100) {
return (reg+0x1000);
} else {

View File

@ -90,6 +90,8 @@
#define AFT_B601_SUBSYS_VENDOR 0xA601 /* AFT-B600 Series board */
#define AFT_B610_SUBSYS_VENDOR 0xA610 /* AFT-B610 single FXS Series board */
#define AFT_W400_SUBSYS_VENDOR 0xF400 /* AFT-W400 (GSM card) */
#define AFT_B800_SUBSYS_VENDOR 0xB800 /* AFT-B800 2/4 FXO or 2/4 FXS board */
#define AFT_2SERIAL_V35X21_SUBSYS_VENDOR 0xA031 /* AFT-A142 2 Port V.35/X.21 board */

View File

@ -149,8 +149,8 @@ enum {
AFT_ADPTR_B800, /* AFT-B800 board */
AFT_ADPTR_FLEXBRI, /* AFT-A700 FlexBRI board */
AFT_ADPTR_B500, /* AFT B500 BRI board */
AFT_ADPTR_W400, /* AFT-W400 (GSM) */
AFT_ADPTR_B610, /* AFT-B610 Single FXS board */
AFT_ADPTR_LAST /* NOTE: Keep it as a last line */
};
#define MAX_ADPTRS AFT_ADPTR_LAST
@ -310,7 +310,8 @@ enum {
(adapter_type == AFT_ADPTR_B601) ? "AFT-B601" : \
(adapter_type == AFT_ADPTR_B610) ? "AFT-B610" : \
(adapter_type == AFT_ADPTR_B800) ? "AFT-B800" : \
(adapter_type == AFT_ADPTR_FLEXBRI) ? "AFT-B700" : \
(adapter_type == AFT_ADPTR_FLEXBRI) ? "AFT-B700" : \
(adapter_type == AFT_ADPTR_W400) ? "AFT-W400" : \
"UNKNOWN"
#define AFT_GET_SECURITY(security) \

View File

@ -962,6 +962,7 @@ int wp_pos_init(sdla_t* card, wandev_conf_t* conf); /* POS Driver */
int wp_xilinx_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Support */
int wp_aft_te1_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Support */
int wp_aft_a600_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx A600 Hardware Support */
int wp_aft_w400_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx W400 (GSM) Hardware Support */
int wp_aft_56k_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Support */
int wp_aft_analog_init(sdla_t* card, wandev_conf_t* conf); /* Xilinx Hardware Support */
int wp_aft_bri_init(sdla_t* card, wandev_conf_t* conf); /* BRI Hardware Support */

View File

@ -630,6 +630,7 @@ typedef enum SANG_STATUS
# undef EAGAIN
# undef EFBIG
# define ETIMEDOUT SANG_STATUS_GENERAL_ERROR
# define EFAULT SANG_STATUS_GENERAL_ERROR
# define EBUSY SANG_STATUS_DEVICE_BUSY
# define ENODEV SANG_STATUS_INVALID_DEVICE

View File

@ -157,6 +157,7 @@ enum {
card_type == WANOPT_AFT108) ? "A101/1D/A102/2D/4/4D/8" : \
(card_type == WANOPT_AFT300) ? "A300" : \
(card_type == WANOPT_AFT_ANALOG) ? "A200/A400/B600/B700/B800" : \
(card_type == WANOPT_AFT_GSM) ? "W400" : \
(card_type == WANOPT_AFT_ISDN) ? "A500/B700/B500" : \
(card_type == WANOPT_AFT_56K) ? "A056" : \
(card_type == WANOPT_AFT_SERIAL) ? "A14x" : \
@ -819,6 +820,7 @@ typedef struct wandev_conf
#define WANCONFIG_AFT_SERIAL 138 /* AFT Serial V32/RS232 Driver */
#define WANCONFIG_LIP_HDLC 139 /* LIP HDLC protocol */
#define WANCONFIG_USB_ANALOG 140 /* Wanpipe USB Driver */
#define WANCONFIG_AFT_GSM 141 /* Wanpipe GSM Driver */
/*FIXME: This should be taken out, I just
//used it so I don't break the apps that are
@ -1087,6 +1089,7 @@ typedef struct {
(cardtype == WANOPT_AFT104) ? "WANOPT_AFT104": \
(cardtype == WANOPT_AFT108) ? "WANOPT_AFT108": \
(cardtype == WANOPT_AFT_ANALOG) ? "WANOPT_AFT_ANALOG": \
(cardtype == WANOPT_AFT_GSM) ? "WANOPT_AFT_GSM": \
(cardtype == WANOPT_AFT_56K) ? "WANOPT_AFT_56K": \
(cardtype == WANOPT_AFT300) ? "WANOPT_AFT300": \
(cardtype == WANOPT_AFT600) ? "WANOPT_AFT600": \

View File

@ -104,7 +104,8 @@ enum {
#define WANOPT_USB_ANALOG 15
#define WANOPT_AFT600 16
#define WANOPT_AFT601 17
#define WANOPT_AFT610 18
#define WANOPT_AFT_GSM 18
#define WANOPT_AFT610 19
/*
* Configuration options defines.

View File

@ -27,6 +27,11 @@
#ifdef CONFIG_PRODUCT_WANPIPE_CODEC_SLINEAR_LAW
/*! The A-law alternate mark inversion mask */
#define G711_ALAW_AMI_MASK 0x55
/*! Bias for u-law encoding from linear. */
#define G711_ULAW_BIAS 0x84
extern int wanpipe_codec_law_init(void);
extern int wanpipe_codec_convert_s_2_alaw(u16 *data,
@ -57,7 +62,11 @@ extern int wanpipe_codec_convert_ulaw_2_s(u8 *data,
extern int wanpipe_codec_get_mtu_law_2_s(u32 mtu);
extern int wanpipe_codec_get_mtu_s_2_law(u32 mtu);
#endif
extern int wanpipe_codec_get_alaw_to_linear(u8 alaw);
extern int wanpipe_codec_get_ulaw_to_linear(u8 ulaw);
#endif /*CONFIG_PRODUCT_WANPIPE_CODEC_SLINEAR_LAW*/
#endif
#endif /*__WANPIPE_CODEC_H_*/

View File

@ -28,12 +28,14 @@
enum wan_codec_source_format{
WP_MULAW,
WP_ALAW
WP_ALAW,
WP_LIN16
};
#define WP_CODEC_FORMAT_DECODE(codec) \
codec == WP_MULAW ? "WP_MULAW" : \
codec == WP_ALAW ? "WP_ALAW" : \
codec == WP_ALAW ? "WP_ALAW" : \
codec == WP_LIN16 ? "WP_LIN16" : \
"Invalid Codec"
#if 0
@ -92,6 +94,8 @@ extern int wanpipe_codec_free(void);
extern wanpipe_codec_ops_t *WANPIPE_CODEC_OPS[WP_TDM_HW_CODING_MAX][WP_TDM_CODEC_MAX];
extern int wanpipe_codec_convert_to_linear(u8 pcm_value,u8 codecType);
#endif
#endif

View File

@ -107,13 +107,13 @@ static __inline int __wp_dahdi_free_device(struct zt_span *span)
}
#define wp_dahdi_register_device(wp) __wp_dahdi_register_device(&wp->span)
static __inline int __wp_dahdi_register_device(struct dahdi_span *span)
static __inline int __wp_dahdi_register_device(struct zt_span *span)
{
return zt_register(span, 0);
}
#define wp_dahdi_unregister_device(wp) __wp_dahdi_unregister_device(&wp->span)
static __inline void __wp_dahdi_unregister_device(struct dahdi_span *span)
static __inline void __wp_dahdi_unregister_device(struct zt_span *span)
{
zt_unregister(span);
}

View File

@ -892,9 +892,14 @@ typedef struct wan_rtp_pkt {
#pragma pack()
#if (!defined __WINDOWS__)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
#define LINUX_HAS_NET_DEVICE_OPS
#endif
#endif
#if defined(HAVE_NET_DEVICE_OPS) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
//#if defined(HAVE_NET_DEVICE_OPS) || LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
#if defined(HAVE_NET_DEVICE_OPS) || defined(LINUX_HAS_NET_DEVICE_OPS)
#define WAN_DECLARE_NETDEV_OPS(_ops_name) static struct net_device_ops _ops_name = {0};
#define WAN_NETDEV_OPS_BIND(dev,_ops_name) dev->netdev_ops = &_ops_name

View File

@ -204,7 +204,6 @@ typedef struct wanpipe_tdm_api_dev {
u32 buffer_multiplier;
u32 timeslots;
u8 loop_reenable_hwec;
}wanpipe_tdm_api_dev_t;

View File

@ -10,14 +10,14 @@
#define WANPIPE_COMPANY "Sangoma Technologies Inc"
/********** LINUX **********/
#define WANPIPE_VERSION "3.5.25"
#define WANPIPE_VERSION "3.5.26"
#define WANPIPE_SUB_VERSION "0"
#define WANPIPE_LITE_VERSION "1.1.1"
#if defined(__LINUX__)
#define WANPIPE_VERSION_MAJOR 3
#define WANPIPE_VERSION_MINOR 5
#define WANPIPE_VERSION_MINOR1 25
#define WANPIPE_VERSION_MINOR1 26
#define WANPIPE_VERSION_MINOR2 0
#endif
@ -48,8 +48,8 @@
# define WANPIPE_VERSION_MINOR1 42 /* frozen feature number */
# define WANPIPE_VERSION_MINOR2 5 /* patch number for WANPIPE_VERSION_MINOR1 */
# else
# define WANPIPE_VERSION_MINOR1 44 /* frozen feature number */
# define WANPIPE_VERSION_MINOR2 5 /* patch number for WANPIPE_VERSION_MINOR1 */
# define WANPIPE_VERSION_MINOR1 45 /* frozen feature number */
# define WANPIPE_VERSION_MINOR2 1 /* patch number for WANPIPE_VERSION_MINOR1 */
# endif
# undef VER_PRODUCTVERSION
@ -61,14 +61,14 @@
# define VER_PRODUCTVERSION 6,0,42,5
# define VER_PRODUCTVERSION_STR "6.0.42.5"
# else
# define VER_PRODUCTVERSION 6,0,44,5
# define VER_PRODUCTVERSION_STR "6.0.44.5"
# define VER_PRODUCTVERSION 6,0,45,1
# define VER_PRODUCTVERSION_STR "6.0.45.1"
# endif
# define __BUILDDATE__ Jan 11, 2012
# define __BUILDDATE__ Apr 19, 2012
# define VER_COMPANYNAME_STR "Sangoma Technologies Corporation"
# define VER_LEGALCOPYRIGHT_YEARS "1984-2011"
# define VER_LEGALCOPYRIGHT_YEARS "1984-2012"
# define VER_LEGALCOPYRIGHT_STR "Copyright (c) Sangoma Technologies Corp."
# define VER_PRODUCTNAME_STR "Sangoma WANPIPE (TM)"
@ -80,8 +80,8 @@
# define WANPIPE_VERSION_Windows "6.0.42"
# define WANPIPE_SUB_VERSION_Windows "5"
# else
# define WANPIPE_VERSION_Windows "6.0.44"
# define WANPIPE_SUB_VERSION_Windows "5"
# define WANPIPE_VERSION_Windows "6.0.45"
# define WANPIPE_SUB_VERSION_Windows "1"
# endif
# define WANPIPE_VERSION_BETA_Windows 0

View File

@ -191,7 +191,7 @@ enum {
#define X25_MAX_DATA 1024 /* max length of X.25 data buffer */
#define X25_MAX_DATA 4096 /* max length of X.25 data buffer */
#pragma pack(1)
typedef struct {

View File

@ -13,6 +13,7 @@
* Sep 06, 2008 Moises Silva Initial Version
* Nov 20, 2008 Alex Feldman Added ZT_XLAW
* Sep 22, 2009 Moises Silva Added dahdi_alarm_channel stuff
* Nov 11, 2011 Moises Silva Added HDLC functions
******************************************************************************
*/
@ -20,6 +21,8 @@
#ifndef __ZAPCOMPAT_H
# define __ZAPCOMPAT_H
#define WP_DAHDI_MAX_STR_SZ 100
// for DAHDI we need to map values and functions from ZT_XX to DAHDI_XX
#if defined (DAHDI_ISSUES)
@ -29,21 +32,20 @@
# include <dahdi/user.h> // this will bring dahdi user stuff
#endif
#define WP_DAHDI_MAX_STR_SZ 100
#if defined(DAHDI_26)
#define DAHDI_25
#define DAHDI_24
#define DAHDI_23
#define DAHDI_22
#elif defined(DAHDI_25)
#elif defined(DAHDI_MAINT_ALARM_SIM)
#define DAHDI_24
#define DAHDI_23
#define DAHDI_22
#elif defined(DAHDI_24)
#elif defined(DAHDI_AUDIO_NOTIFY)
#define DAHDI_23
#define DAHDI_22
#elif defined(DAHDI_23)
#elif defined(DAHDI_ECHOCANCEL_FAX_MODE)
#define DAHDI_22
#endif
@ -109,6 +111,8 @@
#define ZT_LAW_ALAW DAHDI_LAW_ALAW
#define ZT_LAW_MULAW DAHDI_LAW_MULAW
#define ZT_XLAW DAHDI_XLAW
#define ZT_MULAW DAHDI_MULAW
#define ZT_LIN2X DAHDI_LIN2X
#define ZT_MAINT_REMOTELOOP DAHDI_MAINT_REMOTELOOP
#define ZT_MAINT_NONE DAHDI_MAINT_NONE
@ -138,7 +142,7 @@
#define ZT_SIG_SF DAHDI_SIG_SF
#define ZT_SIG_MTP2 DAHDI_SIG_MTP2
#define ZT_LIN2X DAHDI_LIN2X
#define ZT_POLICY_WHEN_FULL DAHDI_POLICY_WHEN_FULL
// data types
#define __zt_mulaw __dahdi_mulaw
@ -160,6 +164,9 @@
#define zt_hooksig dahdi_hooksig
#define zt_ec_span dahdi_ec_span
#define zt_qevent_lock dahdi_qevent_lock
#define zt_hdlc_putbuf dahdi_hdlc_putbuf
#define zt_hdlc_finish dahdi_hdlc_finish
#define zt_hdlc_abort dahdi_hdlc_abort
#if defined (DAHDI_26)
#define WP_DAHDI_SET_STR_INFO(dev,name,...) sprintf((char*)(dev)->ddev->name, ## __VA_ARGS__);

View File

@ -21,7 +21,7 @@ wanpipe-y := sdlamain.o
ifneq (,$(ZAPDIR))
PRODUCT_DEFINES += -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE
wanpipe-y += sdla_tdmv.o sdla_remora_tdmv.o sdla_bri_tdmv.o sdla_tdmv_dummy.o sdla_usb_remora_tdmv.o
wanpipe-y += sdla_tdmv.o sdla_remora_tdmv.o sdla_bri_tdmv.o sdla_gsm_tdmv.o sdla_tdmv_dummy.o sdla_usb_remora_tdmv.o
ifneq (,$(wildcard $(ZAPHDLC)))
PRODUCT_DEFINES+= -DCONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL
@ -32,10 +32,10 @@ wanpipe-y += sdla_ft1.o sdla_te1.o sdla_te3.o sdla_56k.o sdla_8te1.o
wanpipe-y += wanpipe_tdm_api.o
wanpipe-y += aft_core.o aft_core_api_events.o aft_core_prot.o aft_core_utils.o
wanpipe-y += sdla_xilinx.o aft_a104.o
wanpipe-y += aft_analog.o sdla_aft_te3.o wanpipe_utils.o sdla_remora_analog.o
wanpipe-y += aft_gsm.o aft_analog.o sdla_aft_te3.o wanpipe_utils.o sdla_remora_analog.o
wanpipe-y += wanpipe_abstr.o wanpipe_linux_iface.o
wanpipe-y += wanpipe_tdm_api.o sdla_remora.o
wanpipe-y += sdla_bri.o aft_bri.o sdla_serial.o wanpipe_mtp1.o
wanpipe-y += sdla_gsm.o sdla_bri.o aft_bri.o sdla_serial.o wanpipe_mtp1.o
wanpipe-y += wanpipe_codec.o wanpipe_codec_law.o
wanpipe-y += wanpipe_usb.o sdla_usb_remora.o

View File

@ -207,7 +207,6 @@
#define AFT_GLOBAL_POLL_IRQ_TX_POLL 10 /* 10ms */
#define DEBUG_SS7 DEBUG_TEST
WAN_DECLARE_NETDEV_OPS(wan_netdev_ops)
/*=================================================================
@ -533,6 +532,19 @@ int aft_global_hw_device_init(void)
aft_hwdev[WANOPT_AFT_56K].aft_fifo_adjust = a104_fifo_adjust;
aft_hwdev[WANOPT_AFT_56K].aft_check_ec_security = a104_check_ec_security;
#endif
aft_hwdev[WANOPT_AFT_GSM].init = 1;
aft_hwdev[WANOPT_AFT_GSM].aft_global_chip_config = aft_gsm_global_chip_config;
aft_hwdev[WANOPT_AFT_GSM].aft_global_chip_unconfig = aft_gsm_global_chip_unconfig;
aft_hwdev[WANOPT_AFT_GSM].aft_chip_config = aft_gsm_chip_config;
aft_hwdev[WANOPT_AFT_GSM].aft_chip_unconfig = aft_gsm_chip_unconfig;
aft_hwdev[WANOPT_AFT_GSM].aft_chan_config = aft_gsm_chan_dev_config;
aft_hwdev[WANOPT_AFT_GSM].aft_chan_unconfig = aft_gsm_chan_dev_unconfig;
aft_hwdev[WANOPT_AFT_GSM].aft_led_ctrl = aft_gsm_led_ctrl;
aft_hwdev[WANOPT_AFT_GSM].aft_test_sync = aft_gsm_test_sync;
aft_hwdev[WANOPT_AFT_GSM].aft_read_cpld = aft_gsm_read_cpld;
aft_hwdev[WANOPT_AFT_GSM].aft_write_cpld = aft_gsm_write_cpld;
aft_hwdev[WANOPT_AFT_GSM].aft_fifo_adjust = aft_gsm_fifo_adjust;
aft_hwdev[WANOPT_AFT_GSM].aft_check_ec_security = w400_check_ec_security;
return 0;
}
@ -1260,7 +1272,7 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf)
card->hw_iface.getcfg(card->hw, SDLA_BASEADDR, &card->u.aft.bar);
card->hw_iface.getcfg(card->hw, SDLA_MEMBASE, &card->u.aft.bar_virt);
port_set_state(card,WAN_DISCONNECTED);
port_set_state(card, IS_GSM_CARD(card) ? WAN_CONNECTED : WAN_DISCONNECTED);
WAN_TASKQ_INIT((&card->u.aft.port_task),0,aft_port_task,card);
@ -1422,6 +1434,10 @@ static int wan_aft_init (sdla_t *card, wandev_conf_t* conf)
restart of the FPGA */
wan_set_bit(AFT_TDM_RING_BUF,&card->u.aft.chip_cfg_status);
#endif
} else if (IS_GSM_CARD(card)) {
/* For GSM we want the global ISR as we fake multiple ports per card, this means there won't be
* any interrupts for the other ports and must be handled in the first port */
wan_set_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status);
} else if (card->wandev.config_id == WANCONFIG_AFT_ANALOG) {
wan_set_bit(AFT_TDM_SW_RING_BUF,&card->u.aft.chip_cfg_status);
}
@ -1861,7 +1877,8 @@ static int new_if_private (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t*
aft_chan_if_init(card,dev,chan);
if (card->wandev.config_id == WANCONFIG_AFT_ANALOG) {
if (card->wandev.config_id == WANCONFIG_AFT_ANALOG
|| card->wandev.config_id == WANCONFIG_AFT_GSM) {
chan->dma_chain_opmode = WAN_AFT_DMA_CHAIN_SINGLE;
conf->hdlc_streaming=0;
}
@ -3097,14 +3114,22 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf)
switch(card->wandev.config_id){
case WANCONFIG_AFT_ANALOG:
DEBUG_EVENT("%s: Initializing Analog Voice functions\n", card->devname);
err = wp_tdmv_remora_init(&card->tdmv_iface);
break;
#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI)
case WANCONFIG_AFT_ISDN_BRI:
DEBUG_EVENT("%s: Initializing BRI Voice functions\n", card->devname);
err = wp_tdmv_bri_init(&card->tdmv_iface);
break;
#endif
case WANCONFIG_AFT_GSM:
DEBUG_EVENT("%s: Initializing GSM Voice functions\n", card->devname);
err = wp_tdmv_gsm_init(&card->tdmv_iface);
break;
default:
DEBUG_EVENT("%s: Initializing TE1 Voice functions\n", card->devname);
err = wp_tdmv_te1_init(&card->tdmv_iface);
break;
}
@ -3196,17 +3221,22 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf)
if (IS_BRI_CARD(card)) {
wan_set_bit(BRI_DCHAN_LOGIC_CHAN,&card->u.aft.tdmv_dchan);
} else if (IS_GSM_CARD(card)) {
wan_set_bit(GSM_DCHAN_LOGIC_CHAN,&card->u.aft.tdmv_dchan);
}
if (card->wandev.fe_iface.active_map) {
conf->active_ch = card->wandev.fe_iface.active_map(&card->fe, 0);
if(IS_BRI_CARD(card)) {
wan_set_bit(BRI_DCHAN_LOGIC_CHAN,&conf->active_ch);
wan_set_bit(BRI_DCHAN_LOGIC_CHAN,&card->tdmv_conf.dchan);
wan_set_bit(BRI_DCHAN_LOGIC_CHAN, &conf->active_ch);
wan_set_bit(BRI_DCHAN_LOGIC_CHAN, &card->tdmv_conf.dchan);
} else if (IS_GSM_CARD(card)) {
wan_set_bit(GSM_DCHAN_LOGIC_CHAN, &conf->active_ch);
wan_set_bit(GSM_DCHAN_LOGIC_CHAN, &card->tdmv_conf.dchan);
}
active_ch=conf->active_ch;
active_ch = conf->active_ch;
}
err=aft_find_master_if_and_dchan(card,&master_if,active_ch);
@ -3261,15 +3291,15 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf)
u32 voice_chan=active_ch& ~(card->tdmv_conf.dchan);
if (!voice_chan) {
card->u.aft.global_poll_irq=1;
card->u.aft.global_poll_irq=1;
}
/* Global poll irq enables wdt interrupt at 1ms rate
and polls all interface for HDLC rx/tx data. Much
more efficient than running all timeslots on its own
interrupts */
DEBUG_EVENT("%s: Global Poll IRQ= %s\n",
card->devname,card->u.aft.global_poll_irq?"Enabled":"Disabled");
DEBUG_EVENT("%s: Global Poll IRQ= %s\n",
card->devname, card->u.aft.global_poll_irq ? "Enabled" : "Disabled");
for (i=0;i<card->u.aft.num_of_time_slots;i++){
@ -3310,7 +3340,7 @@ static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf)
#endif
}else{
if(IS_BRI_CARD(card)) {
if (IS_BRI_CARD(card)) {
if (conf->active_ch & ~(0x07)) {
DEBUG_ERROR("%s: Error: BRI Active Channels range 1 to 3: Range 0x%08X invalid\n",
@ -3380,7 +3410,8 @@ new_if_cfg_skip:
card->hw_iface.hw_unlock(card->hw,&flags);
} else if (card->wandev.config_id == WANCONFIG_AFT_ISDN_BRI) {
} else if (card->wandev.config_id == WANCONFIG_AFT_ISDN_BRI ||
card->wandev.config_id == WANCONFIG_AFT_GSM) {
wan_smp_flag_t smp_flags;
card->hw_iface.hw_lock(card->hw,&smp_flags);
@ -3674,14 +3705,14 @@ static int del_if (wan_device_t* wandev, netdevice_t* dev)
wan_spin_lock_irq(&card->wandev.lock,&flags);
if (chan->channelized_cfg) {
if (IS_BRI_CARD(card)) {
if (AFT_HAS_FAKE_PORTS(card)) {
int card_use_cnt;
card->wandev.state=WAN_DISCONNECTED;
card->hw_iface.getcfg(card->hw, SDLA_HWTYPE_USEDCNT, &card_use_cnt);
if (card_use_cnt == 1) {
DEBUG_TEST("%s: BRI Disabling TDMV INTR\n",
DEBUG_TEST("%s: Disabling TDMV INTR\n",
card->devname);
aft_tdm_intr_ctrl(card,0);
aft_fifo_intr_ctrl(card, 0);
@ -5050,8 +5081,8 @@ static void aft_dev_enable(sdla_t *card, private_area_t *chan)
static void aft_dev_open_private(sdla_t *card, private_area_t *chan)
{
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
/* BRI dchan does not use DMA thus
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0){
/* fake dchan does not use DMA thus
skip the dma config code below */
return;
}
@ -5146,8 +5177,8 @@ static void aft_dev_close_private(sdla_t *card, private_area_t *chan)
return;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
/* BRI dchan does not use DMA thus
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0){
/* fake dchan does not use DMA thus
skip the dma config code below */
return;
}
@ -5175,13 +5206,12 @@ static void aft_dev_close_private(sdla_t *card, private_area_t *chan)
static void aft_dev_close(sdla_t *card, private_area_t *gchan)
{
private_area_t *chan=gchan;
if (chan->channelized_cfg || chan->wp_api_op_mode){
if (IS_BRI_CARD(card)) {
if (AFT_HAS_FAKE_PORTS(card)) {
int card_use_cnt;
card->hw_iface.getcfg(card->hw, SDLA_HWTYPE_USEDCNT, &card_use_cnt);
if (card_use_cnt == 1) {
DEBUG_TEST("%s: BRI Disabling TDMV INTR\n",
DEBUG_TEST("%s: Disabling TDMV INTR\n",
card->devname);
aft_tdm_intr_ctrl(card,0);
aft_fifo_intr_ctrl(card, 0);
@ -6465,7 +6495,7 @@ static int __wp_aft_fifo_per_port_isr(sdla_t *card, u32 rx_status, u32 tx_status
continue;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0){
continue;
}
@ -6526,7 +6556,7 @@ static int __wp_aft_fifo_per_port_isr(sdla_t *card, u32 rx_status, u32 tx_status
continue;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0){
continue;
}
}
@ -6622,10 +6652,11 @@ static int wp_aft_fifo_per_port_isr(sdla_t *card)
__sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_TX_FIFO_INTR_PENDING_REG),&tx_status);
__sdla_bus_read_4(card->hw, AFT_PORT_REG(card,AFT_RX_FIFO_INTR_PENDING_REG),&rx_status);
if (IS_BRI_CARD(card)) {
if (AFT_HAS_FAKE_PORTS(card)) {
void **card_list=__sdla_get_ptr_isr_array(card->hw);
sdla_t *tmp_card;
for (i=0;i<MAX_BRI_LINES;i++) {
int max_lines = AFT_MAX_PORTS(card);
for (i=0;i<max_lines;i++) {
tmp_card=(sdla_t*)card_list[i];
if (tmp_card &&
!wan_test_bit(CARD_DOWN,&tmp_card->wandev.critical)) {
@ -6645,11 +6676,7 @@ sdla_t * aft_find_first_card_in_list(sdla_t *card, int type)
u32 max_number_of_ports, i;
sdla_t *tmp_card;
if (IS_BRI_CARD(card)) {
max_number_of_ports = MAX_BRI_LINES; /* 24 */
} else {
max_number_of_ports = 8; /* 24 */
}
max_number_of_ports = AFT_MAX_PORTS(card);
card_list=__sdla_get_ptr_isr_array(card->hw);
@ -6736,12 +6763,7 @@ static int aft_is_first_card_in_list(sdla_t *card, int type, int fe_isr)
u32 max_number_of_ports, i;
sdla_t *tmp_card;
if (IS_BRI_CARD(card)) {
max_number_of_ports = MAX_BRI_LINES; /* 24 */
} else {
max_number_of_ports = 8; /* 24 */
}
max_number_of_ports = AFT_MAX_PORTS(card);
card_list=__sdla_get_ptr_isr_array(card->hw);
@ -6804,12 +6826,7 @@ static void front_end_interrupt(sdla_t *card, unsigned long reg, int lock)
u32 max_number_of_ports, i;
sdla_t *tmp_card;
if (IS_BRI_CARD(card)) {
max_number_of_ports = MAX_BRI_LINES; /* 24 */
} else {
max_number_of_ports = 8; /* 24 */
}
max_number_of_ports = AFT_MAX_PORTS(card);
card_list=__sdla_get_ptr_isr_array(card->hw);
@ -6871,6 +6888,7 @@ static int gdma_cnt=0;
static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card)
{
char comm_port = 0;
u32 reg_sec=0,reg=0;
u32 a108_reg=0, a56k_reg=0, serial_reg=0;
u32 fifo_port_intr=0;
@ -6880,7 +6898,8 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card)
u32 status_port_intr=0;
u32 free_port_intr=0;
u32 fe_intr=0;
u32 max_ports=IS_BRI_CARD(card)?MAX_BRI_LINES:8;
u32 max_ports = AFT_MAX_PORTS(card);
u8 check_fe_isr=0;
u8 handle_dma=1;
@ -6901,7 +6920,6 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card)
#ifdef DEBUG_CNT
gcnt++;
#endif
wan_set_bit(0,&card->in_isr);
/* -----------------2/6/2003 9:02AM------------------
@ -6923,7 +6941,6 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card)
DEBUG_ISR("%s: Got Front End Interrupt 0x%08X fe_no_intr=%i\n",
card->devname,reg,card->fe_no_intr);
WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED);
@ -6944,6 +6961,7 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card)
card->devname);
} else {
card->front_end_irq_timeout=SYSTEM_TICKS;
DEBUG_TEST("%s: Setting Front End interrupt timeout\n", card->devname);
}
}
__aft_fe_intr_ctrl(card,0);
@ -6953,7 +6971,6 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card)
DEBUG_FE("%s: Launching Front End Interrupt\n", card->devname);
} else {
DEBUG_FE("%s: Card not first in the list\n",card->devname);
}
@ -6974,6 +6991,7 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card)
#endif
} else {
DEBUG_FE("%s: Got Front end interrupt but MASK is not set!\n",card->devname);
check_fe_isr=1;
}
} else if (!card->fe_no_intr) { /* if (wan_test_bit(AFT_CHIPCFG_FE_INTR_STAT_BIT,&reg)) */
check_fe_isr=1;
@ -7009,6 +7027,7 @@ static WAN_IRQ_RETVAL wp_aft_global_isr (sdla_t* card)
IS_BRI_CARD(card) ||
IS_A600_CARD(card) ||
IS_B601_CARD(card) ||
IS_GSM_CARD(card) ||
IS_A700_CARD(card)) {
__sdla_bus_read_4(card->hw,AFT_PORT_REG(card, AFT_CHIP_STAT_REG), &a108_reg);
@ -7110,9 +7129,15 @@ if (1){
goto aft_global_isr_exit;
}
if (IS_GSM_CARD(card)) {
/* All ports within the card share the same port */
comm_port = 0;
} else {
comm_port = card->wandev.comm_port;
}
if (wan_test_bit(AFT_LCFG_FIFO_INTR_BIT,&card->u.aft.lcfg_reg) &&
wan_test_bit(card->wandev.comm_port,&fifo_port_intr)){
wan_test_bit(comm_port, &fifo_port_intr)){
int irq_handled=wp_aft_fifo_per_port_isr(card);
AFT_PERF_STAT_INC(card,isr,fifo);
@ -7125,7 +7150,7 @@ if (1){
#if 1
if (wan_test_bit(AFT_LCFG_DMA_INTR_BIT,&card->u.aft.lcfg_reg) &&
wan_test_bit(card->wandev.comm_port,&dma_port_intr)) {
wan_test_bit(comm_port,&dma_port_intr)) {
handle_dma=1;
@ -7136,7 +7161,7 @@ if (1){
/* Skip the dma per port and run it in loop below */
if (wan_test_bit(AFT_TDM_GLOBAL_ISR,&card->u.aft.chip_cfg_status) && tdmv_port_intr) {
if (IS_A700_CARD(card)) {
if (wan_test_bit(card->wandev.comm_port,&tdmv_port_intr)) {
if (wan_test_bit(comm_port,&tdmv_port_intr)) {
handle_dma=0;
}
} else if (tdmv_port_intr) {
@ -7211,7 +7236,7 @@ if (1){
AFT_PERF_STAT_INC(tmp_card,isr,tdm_run);
if (IS_A700_CARD(tmp_card)) {
if (!wan_test_bit(tmp_card->wandev.comm_port,&tdmv_port_intr)) {
if (!wan_test_bit(comm_port,&tdmv_port_intr)) {
continue;
}
}
@ -7263,7 +7288,8 @@ if (1){
#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE)
if ((tmp_card->wan_tdmv.sc || tmp_card->tdm_api_span) &&
!tmp_card->wandev.rtp_len &&
tmp_card->wandev.config_id != WANCONFIG_AFT_ANALOG) {
tmp_card->wandev.config_id != WANCONFIG_AFT_ANALOG &&
tmp_card->wandev.config_id != WANCONFIG_AFT_GSM) {
aft_voice_span_rx_tx(tmp_card,
ring_buf_enabled);
@ -7272,7 +7298,8 @@ if (1){
#endif
if (tmp_card->tdm_api_span &&
!tmp_card->wandev.rtp_len &&
tmp_card->wandev.config_id != WANCONFIG_AFT_ANALOG) {
tmp_card->wandev.config_id != WANCONFIG_AFT_ANALOG &&
tmp_card->wandev.config_id != WANCONFIG_AFT_GSM) {
aft_voice_span_rx_tx(tmp_card,
ring_buf_enabled);
@ -7347,7 +7374,7 @@ if (1){
if (wan_test_bit(AFT_LCFG_TDMV_INTR_BIT,&card->u.aft.lcfg_reg) &&
wan_test_bit(card->wandev.comm_port,&tdmv_port_intr)){
wan_test_bit(comm_port, &tdmv_port_intr)){
WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED);
@ -7358,7 +7385,8 @@ if (1){
if (card->wan_tdmv.sc &&
wan_test_bit(WP_ZAPTEL_DCHAN_OPTIMIZATION,&card->u.aft.tdmv_zaptel_cfg) &&
!card->wandev.rtp_len &&
card->wandev.config_id != WANCONFIG_AFT_ANALOG) {
card->wandev.config_id != WANCONFIG_AFT_ANALOG &&
card->wandev.config_id != WANCONFIG_AFT_GSM) {
u32 dmareg;
aft_voice_span_rx_tx(card, 0);
@ -7386,7 +7414,7 @@ if (1){
wp_aft_free_timer_status_isr(card, free_port_intr);
}
if (wan_test_bit(card->wandev.comm_port,&wdt_port_intr)){
if (wan_test_bit(comm_port,&wdt_port_intr)){
WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED);
wp_aft_wdt_per_port_isr(card,1);
card->u.aft.wdt_tx_cnt=SYSTEM_TICKS;
@ -7403,7 +7431,7 @@ if (1){
}
#ifdef AFT_WDT_ENABLE
else if (card->wandev.state == WAN_CONNECTED &&
else if ((IS_GSM_CARD(card) || card->wandev.state == WAN_CONNECTED) &&
SYSTEM_TICKS-card->u.aft.wdt_tx_cnt > (HZ>>2)){
wp_aft_wdt_per_port_isr(card,0);
card->u.aft.wdt_tx_cnt=SYSTEM_TICKS;
@ -7674,7 +7702,7 @@ static void __wp_aft_per_per_port_isr(sdla_t *card, u32 dma_rx_reg, u32 dma_tx_r
continue;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0){
continue;
}
@ -7712,7 +7740,7 @@ static void __wp_aft_per_per_port_isr(sdla_t *card, u32 dma_rx_reg, u32 dma_tx_r
continue;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0){
continue;
}
}
@ -7738,6 +7766,7 @@ static void __wp_aft_per_per_port_isr(sdla_t *card, u32 dma_rx_reg, u32 dma_tx_r
static void wp_aft_dma_per_port_isr(sdla_t *card, int tdm)
{
int i;
int max_ports = AFT_MAX_PORTS(card);
u32 dma_tx_reg=0,dma_rx_reg=0;
AFT_PERF_STAT_INC(card,isr,dma);
@ -7795,10 +7824,10 @@ static void wp_aft_dma_per_port_isr(sdla_t *card, int tdm)
DEBUG_TEST("Line: %d: dma_rx_reg: 0x%X\n", __LINE__, dma_rx_reg);
if (IS_BRI_CARD(card)) {
if (AFT_HAS_FAKE_PORTS(card)) {
void **card_list=__sdla_get_ptr_isr_array(card->hw);
sdla_t *tmp_card;
for (i=0;i<MAX_BRI_LINES;i++) {
for (i=0;i<max_ports;i++) {
tmp_card=(sdla_t*)card_list[i];
if (tmp_card &&
!wan_test_bit(CARD_DOWN,&tmp_card->wandev.critical) &&
@ -7846,7 +7875,7 @@ static void wp_aft_tdmv_per_port_isr(sdla_t *card)
continue;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0){
continue;
}
@ -7957,8 +7986,7 @@ static void __wp_aft_wdt_per_port_isr (sdla_t *card, int wdt_intr, int *wdt_disa
#endif
if (wdt_intr &&
card->wandev.config_id == WANCONFIG_AFT_ANALOG &&
card->u.aft.tdmv_mtu > 8) {
((card->wandev.config_id == WANCONFIG_AFT_ANALOG || IS_GSM_CARD(card)) && card->u.aft.tdmv_mtu > 8)) {
#if 0
private_area_t *top_chan,*chan;
@ -7973,7 +8001,11 @@ static void __wp_aft_wdt_per_port_isr (sdla_t *card, int wdt_intr, int *wdt_disa
card->wandev.fe_iface.watchdog(card);
}
*timeout=1;
if (IS_GSM_CARD(card)) {
*timeout=10;
} else {
*timeout=1;
}
do_not_disable=1;
}
@ -8021,7 +8053,7 @@ static void __wp_aft_wdt_per_port_isr (sdla_t *card, int wdt_intr, int *wdt_disa
continue;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0){
continue;
}
@ -8075,11 +8107,12 @@ static void wp_aft_wdt_per_port_isr(sdla_t *card, int wdt_intr)
aft_wdt_set(card,card->wdt_timeout);
}
if (IS_BRI_CARD(card)) {
if (AFT_HAS_FAKE_PORTS(card)) {
int x;
int max_ports = AFT_MAX_PORTS(card);
void **card_list=__sdla_get_ptr_isr_array(card->hw);
sdla_t *first_card;
for (x=0;x<MAX_BRI_LINES;x++) {
for (x=0;x<max_ports;x++) {
first_card=(sdla_t *)card_list[x];
if (first_card && !wan_test_bit(CARD_DOWN,&first_card->wandev.critical)) {
__wp_aft_wdt_per_port_isr(first_card,wdt_intr,&wdt_disable,&timeout);
@ -8331,9 +8364,9 @@ static void handle_front_end_state(void *card_id,int lock)
wan_spin_lock_irq(&card->wandev.lock,&flags);
}
if (!IS_BRI_CARD(card)) {
if (!AFT_HAS_FAKE_PORTS(card)) {
/* Interrupts for non BRI cards stop
/* Interrupts for non BRI/GSM cards stop
so tell timer device that this card is down */
wp_timer_device_unreg(card);
@ -8444,6 +8477,7 @@ static void enable_data_error_intr(sdla_t *card)
u32 reg;
int i,err;
int card_use_cnt;
int reset_dma_pending = 0;
card->hw_iface.getcfg(card->hw, SDLA_HWTYPE_USEDCNT, &card_use_cnt);
@ -8482,7 +8516,16 @@ static void enable_data_error_intr(sdla_t *card)
aft_wdt_reset(card);
if (!IS_BRI_CARD(card) || (IS_BRI_CARD(card) && card_use_cnt == 1)) {
reset_dma_pending = 0;
if (!IS_BRI_CARD(card) && !IS_GSM_CARD(card)) {
reset_dma_pending = 1;
}
if (((IS_BRI_CARD(card) || IS_GSM_CARD(card)) && card_use_cnt == 1)) {
reset_dma_pending = 1;
}
if (reset_dma_pending) {
/* Clean Tx/Rx DMA interrupts */
card->hw_iface.bus_read_4(card->hw,
AFT_PORT_REG(card,AFT_TX_DMA_INTR_PENDING_REG),
@ -8530,7 +8573,7 @@ static void enable_data_error_intr(sdla_t *card)
continue;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0) {
continue;
}
@ -8587,7 +8630,7 @@ static void enable_data_error_intr(sdla_t *card)
continue;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0) {
continue;
}
@ -8624,7 +8667,7 @@ static void enable_data_error_intr(sdla_t *card)
continue;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0) {
continue;
}
@ -8678,7 +8721,7 @@ static void enable_data_error_intr(sdla_t *card)
continue;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0) {
continue;
}
@ -8792,7 +8835,7 @@ static void disable_data_error_intr(sdla_t *card, unsigned char event)
card->hw_iface.getcfg(card->hw, SDLA_HWTYPE_USEDCNT, &type_use_cnt);
if(IS_BRI_CARD(card) && type_use_cnt > 1 && event < CRITICAL_DOWN){
if(AFT_HAS_FAKE_PORTS(card) && type_use_cnt > 1 && event < CRITICAL_DOWN){
/* BRI card loaded with multiple ports should igore all
DOWN events EXCEPT CRITICAL */
return;
@ -8820,6 +8863,8 @@ static void disable_data_error_intr(sdla_t *card, unsigned char event)
/* Disable Front End Interface */
wan_set_bit(AFT_LCFG_FE_IFACE_RESET_BIT,&reg);
}
} else if (IS_GSM_CARD(card)) {
/* twiddle */
} else {
if (event >= DEVICE_DOWN) {
/* Disable Front End Interface */
@ -9582,7 +9627,6 @@ static void
aft_tx_dma_chain_init(private_area_t *chan, wan_dma_descr_t *dma_chain)
{
#define card chan->card
card->hw_iface.busdma_sync( card->hw,
dma_chain,
1, 1,
@ -10153,7 +10197,7 @@ static int aft_dma_voice_rx(sdla_t *card, private_area_t *chan)
card->u.aft.tdm_rx_dma[chan->logic_ch_num%2]=dma_chain;
} else {
card->u.aft.tdm_rx_dma[chan->logic_ch_num]=dma_chain;
}
}
DEBUG_DMA("%s: %s:%s: Chain %d Used %ld\n",
__FUNCTION__,card->devname,chan->if_name,
@ -10665,7 +10709,7 @@ static void aft_init_tx_rx_dma_descr(private_area_t *chan)
dma_tx_cnt=1;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0){
return;
}
@ -10748,7 +10792,7 @@ static void aft_free_rx_descriptors(private_area_t *chan)
dma_cnt=1;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0){
return;
}
@ -10846,7 +10890,7 @@ static void aft_free_tx_descriptors(private_area_t *chan)
dma_cnt=1;
}
if (IS_BRI_CARD(card) && chan->dchan_time_slot >= 0){
if (AFT_HAS_FAKE_DCHAN(card) && chan->dchan_time_slot >= 0){
return;
}
@ -11696,18 +11740,43 @@ static void aft_set_channel(sdla_t *card, int ch)
}
#endif
static int wp_tdmv_span_buf_sync(sdla_t *card)
{
int x;
#if defined(__LINUX__)
for (x=0; x<32;x++){
if (card->u.aft.tdm_rx_dma[x]) {
wan_dma_descr_t *dma_descr = card->u.aft.tdm_rx_dma[x];
card->hw_iface.busdma_sync(card->hw, dma_descr, 1, 1, PCI_DMA_FROMDEVICE);
}
if (card->u.aft.tdm_tx_dma[x]) {
wan_dma_descr_t *dma_descr = card->u.aft.tdm_tx_dma[x];
card->hw_iface.busdma_sync(card->hw, dma_descr, 1, 1, PCI_DMA_TODEVICE);
}
}
#endif
return 0;
}
static int aft_voice_span_rx_tx(sdla_t *card, int rotate)
{
int err;
err=0;
if (!rotate) {
wp_tdmv_span_buf_sync(card);
}
#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE)
if (card->wan_tdmv.sc){
if (rotate) {
WAN_TDMV_CALL(buf_rotate, (card,AFT_TDMV_CIRC_BUF,AFT_TDMV_BUF_MASK,AFT_TDMV_CIRC_BUF_LEN), err);
}
}
if (!card->wandev.ec_enable || card->wandev.ec_enable_map == 0){
WAN_TDMV_CALL(ec_span, (card), err);
@ -11737,6 +11806,10 @@ static int aft_voice_span_rx_tx(sdla_t *card, int rotate)
}
if (!rotate) {
wp_tdmv_span_buf_sync(card);
}
card->wandev.stats.rx_packets++;
card->wandev.stats.tx_packets++;
@ -12043,7 +12116,7 @@ static int aft_dma_rx_tdmv(sdla_t *card, private_area_t *chan)
err = card->wandev.fe_iface.watchdog(card);
}
} else {
if (card->u.aft.tdmv_mtu == 8) {
if (card->u.aft.tdmv_mtu == 8) {
if (card->wandev.fe_iface.watchdog) {
err = card->wandev.fe_iface.watchdog(card);
}
@ -12119,11 +12192,12 @@ static void aft_critical_shutdown (sdla_t *card)
wan_set_bit(CARD_DOWN,&card->wandev.critical);
port_set_state(card,WAN_DISCONNECTED);
if (IS_BRI_CARD(card)) {
if (AFT_HAS_FAKE_PORTS(card)) {
void **card_list=__sdla_get_ptr_isr_array(card->hw);
sdla_t *tmp_card;
int i;
for (i=0;i<MAX_BRI_LINES;i++) {
int max_ports = AFT_MAX_PORTS(card);
for (i=0;i<max_ports;i++) {
tmp_card=(sdla_t*)card_list[i];
if (tmp_card &&
!wan_test_bit(CARD_DOWN,&tmp_card->wandev.critical)) {
@ -12403,6 +12477,58 @@ static netskb_t *aft_core_sw_raw_hdlc_tx(sdla_t *card, private_area_t *chan)
return tskb;
}
int wp_aft_w400_init (sdla_t* card, wandev_conf_t *conf)
{
AFT_FUNC_DEBUG();
/* Verify configuration ID */
if (card->wandev.config_id != WANCONFIG_AFT_GSM) {
DEBUG_EVENT( "%s: invalid configuration ID %u!\n",
card->devname, card->wandev.config_id);
return -EINVAL;
}
ASSERT_AFT_HWDEV(card->wandev.card_type);
if (card->adptr_type != AFT_ADPTR_W400) {
DEBUG_ERROR( "%s: Error: Attempting to configure for GSM on non GSM hardware!\n", card->devname);
return -EINVAL;
}
card->hw_iface.getcfg(card->hw, SDLA_COREREV, &card->u.aft.firm_ver);
card->hw_iface.getcfg(card->hw, SDLA_COREID, &card->u.aft.firm_id);
DEBUG_EVENT( "%s: GSM firmware version %X\n", card->devname, card->u.aft.firm_ver);
if (conf == NULL){
DEBUG_EVENT("%s: Bad configuration structure!\n", card->devname);
return -EINVAL;
}
/* Make special hardware initialization for W400 board */
memset(&card->fe, 0, sizeof(sdla_fe_t));
memcpy(&card->fe.fe_cfg, &conf->fe_cfg, sizeof(sdla_fe_cfg_t));
wp_gsm_iface_init(&card->fe, &card->wandev.fe_iface);
card->fe.name = card->devname;
card->fe.card = card;
card->fe.write_fe_reg = card->hw_iface.fe_write;
card->fe.read_fe_reg = card->hw_iface.fe_read;
card->fe.__read_fe_reg = card->hw_iface.__fe_read;
card->fe.reset_fe = card->hw_iface.reset_fe;
card->wandev.fe_enable_timer = enable_timer;
card->wandev.ec_enable_timer = enable_ec_timer;
card->wandev.te_link_state = callback_front_end_state;
card->wandev.comm_port = card->fe.fe_cfg.line_no;
/* Set 'num_of_time_slots' to 32. This is needed for the d-chan,
which is always at the otherwise unused timeslot 31. */
card->u.aft.num_of_time_slots = MAX_GSM_TIMESLOTS;
return wan_aft_init(card,conf);
}
/****** End ****************************************************************/

View File

@ -44,6 +44,7 @@ static int aft_write_rbs_bits(void *chan_ptr, u32 ch, u8 rbs_bits);
static int aft_write_hdlc_frame(void *chan_ptr, netskb_t *skb, wp_api_hdr_t *hdr);
static int aft_write_hdlc_check(void *chan_ptr, int lock, int buffers);
static int aft_write_hdlc_timeout(void *chan_ptr, int lock);
static int aft_fake_dchan_transmit(sdla_t *card, void *chan_ptr, void *src_data_buffer, unsigned int buffer_len);
/*--------------------------------------------------------
* PRIVATE EVENT FUNCTIONS
@ -423,6 +424,23 @@ static void wan_aft_api_ringdetect (void* card_id, wan_event_t *event)
return;
}
static int aft_fake_dchan_transmit(sdla_t *card, void *chan_ptr, void *src_data_buffer, unsigned int buffer_len)
{
int err = 0;
/* XXX isdn_bri_dchan_tx should be renamed to dchan_tx as it works for other protocols as well (ie GSM) XXX*/
if (card->wandev.fe_iface.isdn_bri_dchan_tx){
err = card->wandev.fe_iface.isdn_bri_dchan_tx(
&card->fe,
src_data_buffer,
buffer_len);
}else{
DEBUG_WARNING("%s():%s: Warning: uninitialized isdn_bri_dchan_tx() pointer.\n",
__FUNCTION__, card->devname);
}
return err;
}
static int aft_write_hdlc_check(void *chan_ptr, int lock, int buffers)
{
private_area_t *chan = (private_area_t *)chan_ptr;
@ -436,9 +454,9 @@ static int aft_write_hdlc_check(void *chan_ptr, int lock, int buffers)
return 1;
}
if (IS_BRI_CARD(card) && (chan->dchan_time_slot >= 0)){
if (AFT_HAS_FAKE_DCHAN(card) && (chan->dchan_time_slot >= 0)){
rc=aft_bri_dchan_transmit(card, chan,
rc=aft_fake_dchan_transmit(card, chan,
NULL,
0);
@ -481,7 +499,7 @@ static int aft_write_hdlc_timeout(void *chan_ptr, int lock)
sdla_t *card=chan->card;
wan_smp_flag_t smp_flags=0;
if (IS_BRI_CARD(card)) {
if (AFT_HAS_FAKE_DCHAN(card)) {
return 0;
}
@ -537,27 +555,20 @@ static int aft_write_hdlc_frame(void *chan_ptr, netskb_t *skb, wp_api_hdr_t *hd
}
#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI)
if(IS_BRI_CARD(card) && (chan->dchan_time_slot >= 0)){
/* BRI D-chan data NOT transmitted using DMA. */
#if 0
err=aft_bri_dchan_transmit(card, chan, NULL, 0);
if(err){
/* still busy transmitting */
return -EBUSY;
}
#endif
if(AFT_HAS_FAKE_DCHAN(card) && (chan->dchan_time_slot >= 0)){
/* D-chan data NOT transmitted using DMA. */
/* NOTE: BRI dchan tx has to be done inside IRQ lock.
It allows to synchronize access to SPI on the card. */
card->hw_iface.hw_lock(card->hw,&smp_flags);
err=aft_bri_dchan_transmit(card, chan,
wan_skb_data(skb),
wan_skb_len(skb));
err=aft_fake_dchan_transmit(card, chan, wan_skb_data(skb), wan_skb_len(skb));
card->hw_iface.hw_unlock(card->hw,&smp_flags);
hdr->tx_h.max_tx_queue_length = 1;
hdr->tx_h.current_number_of_frames_in_tx_queue = 1;
/* BRI D-channel will return 0 after accepting a frame for transmission or -EBUSY.
/* D-channel will return 0 after accepting a frame for transmission or -EBUSY.
* That means 0 is a success return code - successful tx but now queue is full. */
if (err == 0) {
@ -1084,7 +1095,7 @@ static int aft_driver_ctrl(void *chan_ptr, int cmd, wanpipe_api_cmd_t *api_cmd)
chan->chan_stats.current_number_of_frames_in_rx_queue = (u8)wan_skb_queue_len(&chan->wp_rx_complete_list);
wptdm_os_unlock_irq(&card->wandev.lock, &smp_flags);
if (IS_BRI_CARD(card) && (chan->dchan_time_slot >= 0)) {
if (AFT_HAS_FAKE_DCHAN(card) && (chan->dchan_time_slot >= 0)) {
if (aft_bri_dchan_transmit(card, chan, NULL, 0)) {
/* Tx busy. It means there is a single frame in tx queue. */

View File

@ -605,6 +605,13 @@ int aft_tdm_api_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf)
} else {
chan_no = (u8)(chan->first_time_slot % 2)+1;
}
} else if (IS_GSM_CARD(card)) {
if (chan->dchan_time_slot >= 0) {
chan_no = MAX_GSM_CHANNELS; /* d-chan is the last one */
} else {
/* funky math to calculate the chan number based on port number, -1 to remove the dchan from the tdm slot count */
chan_no=(u8) (chan->first_time_slot + 1) - ((MAX_GSM_CHANNELS-1) * card->wandev.comm_port);
}
} else {
chan_no=(u8)chan->first_time_slot+1;
}
@ -678,7 +685,11 @@ int aft_tdm_api_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf)
} else {
chan->wp_tdm_api_dev->cfg.hw_tdm_coding=WP_ALAW;
}
} else if (IS_GSM_CARD(card)) {
DEBUG_EVENT("WANPIPE: IS_GSM_CARD\n");
/* multiple ports share the same active_ch map, use the port number to decide the proper tdm slot */
wan_set_bit((chan->wp_tdm_api_dev->tdm_chan + (card->wandev.comm_port * MAX_GSM_CHANNELS)),&chan->wp_tdm_api_dev->active_ch);
chan->wp_tdm_api_dev->cfg.hw_tdm_coding=WP_LIN16;
} else {
if (card->fe.fe_cfg.tdmv_law == WAN_TDMV_MULAW){
chan->wp_tdm_api_dev->cfg.hw_tdm_coding=WP_MULAW;
@ -734,6 +745,15 @@ int aft_tdm_api_init(sdla_t *card, private_area_t *chan, wanif_conf_t *conf)
chan->wp_tdm_api_dev->tdm_chan = (u8)chan->if_cnt;
}
switch(chan->wp_tdm_api_dev->cfg.hw_tdm_coding) {
case WP_LIN16:
chan->wp_tdm_api_dev->cfg.hw_mtu_mru = 16;
break;
default:
chan->wp_tdm_api_dev->cfg.hw_mtu_mru = 8;
break;
};
if (chan->usedby_cfg == MTP1_API) {
chan->wp_tdm_api_dev->operation_mode = WP_TDM_OPMODE_MTP1;
}

View File

@ -1114,6 +1114,15 @@ static int wp_bert_allocate_tx_bert_skb(private_area_t* chan)
}
static int safe_copy_to_udp(void *udp, void *src, size_t len)
{
if (len > WAN_MAX_DATA_SIZE) {
DEBUG_ERROR("Can't copy UDP data of len %zd (max = %d)\n", len, WAN_MAX_DATA_SIZE);
return -1;
}
memcpy(udp, src, len);
return 0;
}
/*=============================================================================
* process_udp_mgmt_pkt
@ -1132,11 +1141,15 @@ static int wp_bert_allocate_tx_bert_skb(private_area_t* chan)
int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, private_area_t* chan, int local_dev )
{
/* MAINTENANCE WARNING:
* Do not use memcpy to copy udp data to the user buffer, use safe_copy_to_udp() instead, and check the return value,
* the udp user data is limited, we can't just blindly copy our internal data structures in there, size must be checked! */
unsigned short buffer_length;
wan_udp_pkt_t *wan_udp_pkt;
wan_trace_t *trace_info=NULL;
wan_if_cfg_t *if_cfg;
wan_smp_flag_t smp_flags;
int rc = 0;
smp_flags=0;
@ -1167,18 +1180,18 @@ int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, private_area_t* chan, i
if_cfg = (wan_if_cfg_t*)&wan_udp_pkt->wan_udp_data[0];
memset(if_cfg,0,sizeof(wan_if_cfg_t));
if_cfg->usedby = chan->usedby_cfg;
if_cfg->media=card->wandev.fe_iface.get_fe_media(&card->fe);
if_cfg->usedby = chan->usedby_cfg;
if_cfg->media=card->wandev.fe_iface.get_fe_media(&card->fe);
if_cfg->active_ch=chan->time_slot_map;
if_cfg->cfg_active_ch=chan->cfg_active_ch;
/* EC API always expects first channel to start from 1
however in driver, we use first channel 0. Since E1
however in driver, we use first channel 0. Since E1
is already shifted and 0 channel is not used, we dont
have to shif for E1 */
if(IS_E1_CARD(card)) {
if_cfg->ec_active_ch=chan->time_slot_map;
if_cfg->ec_active_ch=chan->time_slot_map;
} else {
if (IS_BRI_CARD(card)) {
/* BRI always has 2 timeslots (1 & 2) thus 0x06 */
@ -1189,21 +1202,21 @@ int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, private_area_t* chan, i
}
}
if_cfg->chunk_sz=chan->mru/chan->num_of_time_slots;
if_cfg->interface_number=chan->logic_ch_num;
if_cfg->chunk_sz=chan->mru/chan->num_of_time_slots;
if_cfg->interface_number=chan->logic_ch_num;
if (chan->hdlc_eng) {
if_cfg->hw_coding=WAN_TDMV_HDLC;
if (chan->hdlc_eng) {
if_cfg->hw_coding=WAN_TDMV_HDLC;
} else {
if_cfg->hw_coding=(u8)card->fe.fe_cfg.tdmv_law;
if (IS_T1_CARD(card)){
if_cfg->hw_coding=WAN_TDMV_MULAW;
} else if (IS_E1_CARD(card)) {
if_cfg->hw_coding=WAN_TDMV_ALAW;
}
}
if_cfg->hw_coding=(u8)card->fe.fe_cfg.tdmv_law;
if (IS_T1_CARD(card)){
if_cfg->hw_coding=WAN_TDMV_MULAW;
} else if (IS_E1_CARD(card)) {
if_cfg->hw_coding=WAN_TDMV_ALAW;
}
}
memcpy(&if_cfg->fe_cfg, &card->fe.fe_cfg, sizeof(sdla_fe_cfg_t));
memcpy(&if_cfg->fe_cfg, &card->fe.fe_cfg, sizeof(sdla_fe_cfg_t));
/* line_mode: MODE_OPTION_HDLC/MODE_OPTION_BITSTRM/ISDN_BRI_DCHAN */
if (IS_BRI_CARD(card) && (chan->dchan_time_slot >= 0)){
@ -1246,9 +1259,9 @@ int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, private_area_t* chan, i
}
wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK;
wan_udp_pkt->wan_udp_data_len=sizeof(wan_if_cfg_t);
break;
wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK;
wan_udp_pkt->wan_udp_data_len=sizeof(wan_if_cfg_t);
break;
case WANPIPEMON_READ_CODE_VERSION:
#if defined(__WINDOWS__)
@ -1313,7 +1326,11 @@ int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, private_area_t* chan, i
break;
case WANPIPEMON_READ_PERFORMANCE_STATS:
memcpy(wan_udp_pkt->wan_udp_data,&card->aft_perf_stats,sizeof(card->aft_perf_stats));
//memcpy(wan_udp_pkt->wan_udp_data,&card->aft_perf_stats,sizeof(card->aft_perf_stats));
rc = safe_copy_to_udp(wan_udp_pkt->wan_udp_data, &card->aft_perf_stats, sizeof(card->aft_perf_stats));
if (rc) {
return -ENOMEM;
}
wan_udp_pkt->wan_udp_data_len=sizeof(card->aft_perf_stats);
wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK;
break;
@ -1325,7 +1342,11 @@ int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, private_area_t* chan, i
break;
case WANPIPEMON_READ_OPERATIONAL_STATS:
memcpy(wan_udp_pkt->wan_udp_data,&chan->chan_stats,sizeof(wp_tdm_chan_stats_t));
//memcpy(wan_udp_pkt->wan_udp_data,&chan->chan_stats,sizeof(wp_tdm_chan_stats_t));
rc = safe_copy_to_udp(wan_udp_pkt->wan_udp_data, &chan->chan_stats, sizeof(wp_tdm_chan_stats_t));
if (rc) {
return -ENOMEM;
}
wan_udp_pkt->wan_udp_data_len=sizeof(wp_tdm_chan_stats_t);
wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK;
break;
@ -1341,8 +1362,12 @@ int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev, private_area_t* chan, i
break;
case WANPIPEMON_READ_COMMS_ERROR_STATS:
wan_udp_pkt->wan_udp_return_code = 0;
memcpy(wan_udp_pkt->wan_udp_data,&chan->errstats,sizeof(aft_comm_err_stats_t));
//memcpy(wan_udp_pkt->wan_udp_data,&chan->errstats,sizeof(aft_comm_err_stats_t));
rc = safe_copy_to_udp(wan_udp_pkt->wan_udp_data,&chan->errstats,sizeof(aft_comm_err_stats_t));
if (rc) {
return -ENOMEM;
}
wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK;
wan_udp_pkt->wan_udp_data_len=sizeof(aft_comm_err_stats_t);
memset(&card->wandev.stats,0,sizeof(card->wandev.stats));
break;

View File

@ -0,0 +1,513 @@
/*****************************************************************************
* aft_gsm.c
*
* WANPIPE(tm) AFT W400 Hardware Support
*
* Authors: Moises Silva <moy@sangoma.com>
*
* Copyright: (c) 2011 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.
* ============================================================================
* Oct 06, 2011 Moises Silva Initial Version
*****************************************************************************/
#if defined(__WINDOWS__)
# include <wanpipe_includes.h>
# include <wanpipe_defines.h>
# include <wanpipe.h>
# include <wanpipe_abstr.h>
# include <if_wanpipe_common.h> /* Socket Driver common area */
# include <sdlapci.h>
# include <aft_core.h>
#else
# include <linux/wanpipe_includes.h>
# include <linux/wanpipe_defines.h>
# include <linux/wanpipe.h>
# include <linux/wanproc.h>
# include <linux/wanpipe_abstr.h>
# include <linux/if_wanpipe_common.h>
# include <linux/if_wanpipe.h>
# include <linux/sdlapci.h>
# include <linux/aft_core.h>
# include <linux/wanpipe_iface.h>
# include <linux/wanpipe_tdm_api.h>
# include <linux/sdla_gsm.h>
#endif
int aft_gsm_test_sync(sdla_t *card, int tx_only)
{
return 0;
}
int aft_gsm_led_ctrl(sdla_t *card, int color, int led_pos, int on)
{
return 0;
}
#include "sdla_gsm_inline.h"
int aft_gsm_global_chip_config(sdla_t *card)
{
u32 reg = 0;
int used_cnt = 0;
u8 core_rev = 0;
int pll_reset_counter = 1;
DEBUG_EVENT("%s: Performing GSM global chip configuration\n", card->devname);
card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &used_cnt);
card->fe_no_intr = 1;
if (used_cnt == 1) {
DEBUG_EVENT("%s: Performing GSM FPGA reset ...\n", card->devname);
reg = 0;
/*
* You would think to set/clear bits you need to first read the contents of
* the registry to not modify other stuff. In fact, looking at analog (aft_analog.c)
* it seems that is the way is done there. But in GSM, testing shows that if we
* read the original register contents and only set the SFR EX/IN bits, the first time
* the PC boots and the port is started, the TDMV interrupt will not fire. Therefore
* is needed to clear the contents of all other bits reg=0 and just set the EX/IN bits
*
* card->hw_iface.bus_read_4(card->hw, AFT_PORT_REG(card, AFT_CHIP_CFG_REG), &reg);
*
*/
wan_set_bit(AFT_CHIPCFG_SFR_EX_BIT, &reg);
wan_set_bit(AFT_CHIPCFG_SFR_IN_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_PORT_REG(card, AFT_CHIP_CFG_REG), reg);
WP_DELAY(10);
wan_clear_bit(AFT_CHIPCFG_SFR_EX_BIT, &reg);
wan_clear_bit(AFT_CHIPCFG_SFR_IN_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_PORT_REG(card, AFT_CHIP_CFG_REG), reg);
WP_DELAY(10);
card->hw_iface.getcfg(card->hw, SDLA_COREREV, &core_rev);
DEBUG_EVENT("%s: GSM FPGA reset done! (core rev = %X)\n", card->devname, core_rev);
DEBUG_EVENT("%s: Resetting GSM front end\n", card->devname);
/* FE reset */
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_PORT_REG(card, AFT_LINE_CFG_REG), &reg);
wan_set_bit(AFT_LCFG_FE_IFACE_RESET_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_PORT_REG(card, AFT_LINE_CFG_REG), reg);
WP_DELAY(10);
wan_clear_bit(AFT_LCFG_FE_IFACE_RESET_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_PORT_REG(card, AFT_LINE_CFG_REG),reg);
WP_DELAY(10);
DEBUG_EVENT("%s: GSM front end reset done!\n", card->devname);
do {
/* Due to some sort of hardware bug, it seems we have to do the PLL reset procedure twice
* the first time after the PC boots up, otherwise often the UART will not work.
* Sometimes due to the PLL output clock stopped bit being set, but other times
* even when the status register says the PLL is locked (enabled) and there is no
* clock lost, the UART just won't work. I had to resort to do it twice every time :-(
*/
wp_gsm_pll_reset(card);
} while (pll_reset_counter--);
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_GLOBAL_REG, &reg);
if (!wan_test_bit(AFT_GSM_PLL_LOCKED_BIT, &reg)) {
DEBUG_ERROR("%s: Error: Failed to enable PLL!\n", card->devname);
} else if (wan_test_bit(AFT_GSM_PLL_OUTPUT_CLOCK_STOPPED_BIT, &reg)) {
DEBUG_ERROR("%s: Error: PLL enabled but no output clock!\n", card->devname);
} else if (wan_test_bit(AFT_GSM_PLL_INPUT_CLOCK_LOST_BIT, &reg)) {
DEBUG_ERROR("%s: Error: PLL enabled but no input clock!\n", card->devname);
} else {
DEBUG_EVENT("%s: GSM PLL enabled!\n", card->devname);
}
/* Make sure the loopback bit is cleared
* wanpipemon cmd can enable it and if the user stops the ports, the bit stays enabled even
* after restart, it makes more sense to start without the debug PCM loopback */
wan_clear_bit(AFT_GSM_GLOBAL_PCM_LOOPBACK_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_GSM_GLOBAL_REG, reg);
#if 0
DEBUG_EVENT("%s: Dumping Global Configuration (reg=%X)\n", card->devname, reg);
DEBUG_EVENT("%s: PLL Reset: %d\n", card->devname, wan_test_bit(AFT_GSM_PLL_RESET_BIT, &reg));
DEBUG_EVENT("%s: PLL Phase Shift Overflow: %d\n", card->devname, wan_test_bit(AFT_GSM_PLL_PHASE_SHIFT_OVERFLOW_BIT, &reg));
DEBUG_EVENT("%s: PLL Input Clock Lost: %d\n", card->devname, wan_test_bit(AFT_GSM_PLL_INPUT_CLOCK_LOST_BIT, &reg));
DEBUG_EVENT("%s: PLL Output Clock Stopped: %d\n", card->devname, wan_test_bit(AFT_GSM_PLL_OUTPUT_CLOCK_STOPPED_BIT, &reg));
DEBUG_EVENT("%s: PLL Locked Bit: %d\n", card->devname, wan_test_bit(AFT_GSM_PLL_LOCKED_BIT, &reg));
DEBUG_EVENT("%s: SIM Muxing Error: %d\n", card->devname, wan_test_bit(AFT_GSM_SIM_MUXING_ERROR_BIT, &reg));
DEBUG_EVENT("%s: Global Shutdown Bit: %d\n", card->devname, wan_test_bit(AFT_GSM_GLOBAL_SHUTDOWN_BIT, &reg));
#endif
}
DEBUG_EVENT("%s: GSM global chip configuration done!\n", card->devname);
return 0;
}
int aft_gsm_global_chip_unconfig(sdla_t *card)
{
u32 reg = 0;
int used_cnt = 0;
card->hw_iface.getcfg(card->hw, SDLA_HWCPU_USEDCNT, &used_cnt);
DEBUG_EVENT("%s: GSM global chip unconfig (use count = %d)\n", card->devname, used_cnt);
if (used_cnt == 1) {
DEBUG_EVENT("%s: Unconfiguring unique GSM line (port = %d)\n", card->devname, card->wandev.comm_port + 1);
/* GSM PLL */
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_GLOBAL_REG, &reg);
wan_set_bit(AFT_GSM_PLL_RESET_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_GSM_GLOBAL_REG, reg);
/* Front end */
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_PORT_REG(card, AFT_LINE_CFG_REG), &reg);
wan_set_bit(AFT_LCFG_FE_IFACE_RESET_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_PORT_REG(card, AFT_LINE_CFG_REG), reg);
/* FPGA */
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_PORT_REG(card, AFT_CHIP_CFG_REG), &reg);
wan_set_bit(AFT_CHIPCFG_SFR_EX_BIT, &reg);
wan_set_bit(AFT_CHIPCFG_SFR_IN_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_PORT_REG(card,AFT_CHIP_CFG_REG), reg);
}
return 0;
}
static void aft_gsm_read(sdla_t *card, u32 offset, u32 *reg)
{
int mod_no = card->wandev.comm_port + 1;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_MOD_REG(mod_no, offset), reg);
//DEBUG_EVENT("%s: regaccess: read from address 0x%X -> 0x%08X\n", card->devname, AFT_GSM_MOD_REG(mod_no, offset), *reg);
}
static void aft_gsm_write(sdla_t *card, u32 offset, u32 reg)
{
int mod_no = card->wandev.comm_port + 1;
card->hw_iface.bus_write_4(card->hw, AFT_GSM_MOD_REG(mod_no, offset), reg);
//DEBUG_EVENT("%s: regaccess: wrote to address 0x%X -> 0x%08X\n", card->devname, AFT_GSM_MOD_REG(mod_no, offset), reg);
}
/* This is called for each port/line via user ioctl
* wanrouter_ioctl -> wan_device_setup -> setup -> wp_aft_w400_init -> aft_gsm_chip_config() */
int aft_gsm_chip_config(sdla_t *card, wandev_conf_t *conf)
{
u32 reg = 0;
int mod_no = card->wandev.comm_port + 1;
DEBUG_EVENT("%s: Configuring GSM module %d\n", card->devname, mod_no);
reg = 0;
aft_gsm_read(card, AFT_GSM_CONFIG_REG, &reg);
if (wan_test_bit(AFT_GSM_MOD_POWER_MONITOR_BIT, &reg)) {
DEBUG_EVENT("%s: GSM module %d is already turned on ...\n", card->devname, mod_no);
goto select_sim;
}
wp_gsm_toggle_power(card->hw, (1 << (mod_no - 1)), WAN_TRUE);
reg = 0;
aft_gsm_read(card, AFT_GSM_CONFIG_REG, &reg);
if (!wan_test_bit(AFT_GSM_MOD_POWER_MONITOR_BIT, &reg)) {
DEBUG_ERROR("%s: Failed to turn on GSM module %d\n", card->devname, mod_no);
return -ETIMEDOUT;
}
select_sim:
aft_gsm_set_sim_no(&reg, mod_no);
aft_gsm_write(card, AFT_GSM_CONFIG_REG, reg);
WP_DELAY(10);
if (card->wandev.fe_iface.post_init) {
card->wandev.fe_iface.post_init(&card->fe);
}
return 0;
}
int aft_gsm_chip_unconfig(sdla_t *card)
{
u32 reg = 0;
int mod_no = card->wandev.comm_port + 1;
DEBUG_EVENT("%s: Unconfiguring GSM module %d\n", card->devname, mod_no);
reg = 0;
aft_gsm_read(card, AFT_GSM_CONFIG_REG, &reg);
if (!wan_test_bit(AFT_GSM_MOD_POWER_MONITOR_BIT, &reg)) {
DEBUG_EVENT("%s: GSM module %d is already turned off ...\n", card->devname, mod_no);
goto done;
}
wp_gsm_toggle_power(card->hw, (1 << (mod_no - 1)), WAN_FALSE);
reg = 0;
aft_gsm_read(card, AFT_GSM_CONFIG_REG, &reg);
if (wan_test_bit(AFT_GSM_MOD_POWER_MONITOR_BIT, &reg)) {
DEBUG_ERROR("%s: Failed to turn off GSM module %d\n", card->devname, mod_no);
}
done:
/* clear the selected SIM */
aft_gsm_set_sim_no(&reg, 0);
aft_gsm_write(card, AFT_GSM_CONFIG_REG, reg);
return 0;
}
static int aft_free_fifo_baddr_and_size (sdla_t *card, private_area_t *chan)
{
u32 reg=0;
int i;
for (i=0;i<chan->fifo_size;i++){
wan_set_bit(i,&reg);
}
DEBUG_TEST("%s: Unmapping 0x%X from 0x%lX\n",
card->devname,reg<<chan->fifo_base_addr, card->u.aft.fifo_addr_map);
card->u.aft.fifo_addr_map &= ~(reg<<chan->fifo_base_addr);
DEBUG_TEST("%s: New Map is 0x%lX\n",
card->devname, card->u.aft.fifo_addr_map);
chan->fifo_size=0;
chan->fifo_base_addr=0;
return 0;
}
static char aft_request_logical_channel_num (sdla_t *card, private_area_t *chan)
{
signed char logic_ch=-1;
long i;
int timeslots=0;
DEBUG_CFG("%s: GSM Timeslots=%d, Logic ChMap 0x%lX \n", card->devname, card->u.aft.num_of_time_slots, card->u.aft.logic_ch_map);
/* Check that the time slot is not being used. If it is
* stop the interface setup. Notice, though we proceed
* to check for all timeslots before we start binding
* the channels in. This way, we don't have to go back
* and clean the time_slot_map */
for (i=0;i<card->u.aft.num_of_time_slots;i++){
if (wan_test_bit(i,&chan->time_slot_map)){
if (chan->first_time_slot == -1){
DEBUG_EVENT("%s: First TSlot :%ld\n",
card->devname,i);
chan->first_time_slot=i;
}
chan->last_time_slot=i;
DEBUG_CFG("%s: Configuring %s for timeslot %ld\n",
card->devname, chan->if_name,i+1);
if (wan_test_bit(i,&card->u.aft.time_slot_map)){
DEBUG_ERROR("%s: Channel/Time Slot resource conflict!\n",
card->devname);
DEBUG_ERROR("%s: %s: Channel/Time Slot %ld, aready in use!\n",
card->devname,chan->if_name, (i+1));
return -EEXIST;
}
timeslots++;
}
}
if (timeslots > 1){
DEBUG_ERROR("%s: GSM Interface can only support a single timeslot\n", card->devname);
chan->first_time_slot = -1;
return -1;
}
logic_ch = (signed char)chan->first_time_slot;
if (logic_ch == 31) {
/* The UART fake D-channel */
chan->fifo_base_addr = 0x1;
} else {
/* Must be a voice channel */
chan->fifo_base_addr = 0x0;
}
chan->fifo_size = 1;
chan->fifo_size_code = 0;
/* Add this timeslot to the map */
card->u.aft.fifo_addr_map |= (1 << chan->fifo_base_addr);
if (wan_test_and_set_bit(logic_ch,&card->u.aft.logic_ch_map)){
return -1;
}
if (logic_ch == -1){
return logic_ch;
}
for (i=0;i<card->u.aft.num_of_time_slots;i++){
if (!wan_test_bit(i,&card->u.aft.logic_ch_map)){
break;
}
}
if (card->u.aft.dev_to_ch_map[(unsigned char)logic_ch]){
DEBUG_ERROR("%s: Error, request logical ch=%d map busy\n", card->devname,logic_ch);
return -1;
}
card->u.aft.dev_to_ch_map[(unsigned char)logic_ch]=(void*)chan;
if (logic_ch >= card->u.aft.top_logic_ch){
card->u.aft.top_logic_ch=logic_ch;
aft_dma_max_logic_ch(card);
}
DEBUG_EVENT("%s: Binding logic ch %d, fifo_base_addr=%X, fifo_size=%X, fifo addr map=%X, Ptr=%p\n",
card->devname, logic_ch, chan->fifo_base_addr, chan->fifo_size, card->u.aft.fifo_addr_map, chan);
return logic_ch;
}
int aft_gsm_chan_dev_config(sdla_t *card, void *chan_ptr)
{
u32 reg = 0;
private_area_t *chan = (private_area_t *)chan_ptr;
u32 dma_ram_reg = 0;
DEBUG_EVENT("%s: Configuring GSM channel device\n", card->devname);
chan->logic_ch_num = aft_request_logical_channel_num(card, chan);
if (chan->logic_ch_num == -1){
return -EBUSY;
}
DEBUG_EVENT("%s: GSM received logic_ch_num = %d\n", card->devname, chan->logic_ch_num);
dma_ram_reg = AFT_PORT_REG(card, AFT_DMA_CHAIN_RAM_BASE_REG);
dma_ram_reg += (chan->logic_ch_num * 4);
DEBUG_EVENT("%s: GSM logic_ch_num %d is at address 0x%08X\n", card->devname, chan->logic_ch_num, dma_ram_reg);
reg = 0;
card->hw_iface.bus_write_4(card->hw, dma_ram_reg, reg);
card->hw_iface.bus_read_4(card->hw, dma_ram_reg, &reg);
aft_dmachain_set_fifo_size(&reg, chan->fifo_size_code);
aft_dmachain_set_fifo_base(&reg, chan->fifo_base_addr);
/* Initially always disable rx synchronization */
wan_clear_bit(AFT_DMACHAIN_RX_SYNC_BIT, &reg);
if (CHAN_GLOBAL_IRQ_CFG(chan)){
aft_dmachain_enable_tdmv_and_mtu_size(&reg, chan->mru);
}
card->hw_iface.bus_write_4(card->hw, dma_ram_reg, reg);
reg = 0;
if (CHAN_GLOBAL_IRQ_CFG(chan)){
card->hw_iface.bus_read_4(card->hw, AFT_PORT_REG(card,AFT_LINE_CFG_REG), &reg);
aft_lcfg_tdmv_cnt_inc(&reg);
card->hw_iface.bus_write_4(card->hw, AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg);
card->u.aft.lcfg_reg = reg;
wan_set_bit(chan->logic_ch_num, &card->u.aft.tdm_logic_ch_map);
}
if (card->wandev.fe_iface.if_config){
card->wandev.fe_iface.if_config(
&card->fe,
chan->time_slot_map,
chan->common.usedby);
}
return 0;
}
int aft_gsm_chan_dev_unconfig(sdla_t *card, void *chan_ptr)
{
private_area_t *chan = (private_area_t *)chan_ptr;
u32 dma_ram_reg, reg;
volatile int i;
DEBUG_EVENT("%s: Unconfiguring GSM channel device\n", card->devname);
if (card->wandev.fe_iface.if_unconfig){
card->wandev.fe_iface.if_unconfig(
&card->fe,
chan->time_slot_map,
chan->common.usedby);
}
/* Select logic channel for configuration */
if (chan->logic_ch_num != -1){
dma_ram_reg = AFT_PORT_REG(card, AFT_DMA_CHAIN_RAM_BASE_REG);
dma_ram_reg += (chan->logic_ch_num * 4);
card->hw_iface.bus_read_4(card->hw, dma_ram_reg, &reg);
aft_dmachain_set_fifo_base(&reg, 0x1F);
aft_dmachain_set_fifo_size(&reg, 0);
card->hw_iface.bus_write_4(card->hw, dma_ram_reg, reg);
aft_free_logical_channel_num(card, chan->logic_ch_num);
aft_free_fifo_baddr_and_size(card, chan);
for (i = 0; i < card->u.aft.num_of_time_slots; i++){
if (wan_test_bit(i, &chan->time_slot_map)){
wan_clear_bit(i, &card->u.aft.time_slot_map);
}
}
if (CHAN_GLOBAL_IRQ_CFG(chan)){
card->hw_iface.bus_read_4(card->hw, AFT_PORT_REG(card,AFT_LINE_CFG_REG), &reg);
aft_lcfg_tdmv_cnt_dec(&reg);
card->hw_iface.bus_write_4(card->hw, AFT_PORT_REG(card,AFT_LINE_CFG_REG), reg);
wan_clear_bit(chan->logic_ch_num,&card->u.aft.tdm_logic_ch_map);
}
/* Do not clear the logic_ch_num here the core will do it at the end of del_if_private() function */
}
return 0;
}
int w400_check_ec_security(sdla_t *card)
{
return 0;
}
unsigned char aft_gsm_read_cpld(sdla_t *card, unsigned short cpld_off)
{
return 0;
}
int aft_gsm_write_cpld(sdla_t *card, unsigned short off, u_int16_t data_in)
{
return 0;
}
void aft_gsm_fifo_adjust(sdla_t *card, u32 level)
{
return;
}

View File

@ -175,6 +175,30 @@
* STRUCTURES AND TYPEDEFS
******************************************************************************/
typedef struct {
unsigned int reg;
unsigned int value;
} wan_reg_indx_t;
wan_reg_indx_t ncrc4_regs[] = {
{0x40,0x00},{0x41,0xFF},{0x42,0xFF},{0x43,0xFF},{0x44,0xFF},{0x45,0xFF},
{0x46,0xFF},{0x47,0xFF},{0x48,0xFF},{0x49,0xFF},{0x4a,0xFF},{0x4b,0xFF},
{0x4c,0xFF},{0x4d,0xFF},{0x4e,0xFF},{0x4f,0xFF},{0x56,0x03},{0x57,0xE8},
{0x5e,0x01},{0x5f,0x38},{0x60,0x5F},{0x64,0x1B},{0x65,0x5F},{0x66,0x00},
{0x67,0x00},{0x77,0x1B},{0x78,0x00},{0x79,0x00},{0x81,0x44},{0x82,0xF8},
{0x91,0x03},{0x92,0x22},{0x93,0x01},{0x96,0x02},{0xa0,0xFF},{0xa2,0x11},
{0xa3,0x02},{0xb6,0x6C},{0x114,0xDF},{0x118,0xFF},{0x119,0xFF},{0x11a,0xFF},
{0x11b,0xFF},{0x140,0x0B},{0x141,0x99},{0x142,0x99},{0x143,0x99},{0x144,0x99},
{0x145,0x99},{0x146,0x99},{0x147,0x99},{0x148,0x99},{0x149,0x99},{0x14a,0x99},
{0x14b,0x99},{0x14c,0x99},{0x14d,0x99},{0x14e,0x99},{0x14f,0x99},{0x164,0x9B},
{0x165,0xC0},{0x166,0xFF},{0x167,0xFF},{0x169,0xFF},{0x16a,0xFF},{0x16b,0xFF},
{0x16c,0xFF},{0x16d,0xFF},{0x181,0x04},{0x182,0xA0},{0x191,0x00},{0x1bb,0x9B},
{0x1004,0x00},{0x1005,0x55},{0x1007,0x30},{0x100c,0x00},{0xFFFF,0xFFFF}
};
/******************************************************************************
* GLOBAL VERIABLES
@ -607,6 +631,19 @@ static int sdla_ds_e1_set_sig_mode(sdla_fe_t *fe, int verbose)
//WRITE_REG(REG_RSIGC, value | BIT_RSIGC_CASMS);
value = READ_REG(REG_TCR1);
WRITE_REG(REG_TCR1, value | BIT_TCR1_E1_T16S);
if (WAN_FE_FRAME(fe) == WAN_FR_NCRC4){
int i=0;
while (1) {
if (ncrc4_regs[i].reg == 0xffff) {
break;
}
WRITE_REG(ncrc4_regs[i].reg,ncrc4_regs[i].value);
i++;
}
DEBUG_EVENT("%s: E1 CAS NCRC4 updated config %d\n",
fe->name, i);
}
}else{
/* CCS signalling mode */
@ -1366,6 +1403,7 @@ static int sdla_ds_te1_chip_config(void* pfe)
/* INIT RBS bits to 1 */
sdla_ds_te1_rbs_init(fe);

View File

@ -189,6 +189,10 @@ static int wp_bri_zap_ioctl(struct zt_chan *chan, unsigned int cmd, caddr_t data
static int wp_bri_zap_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data);
#endif
#ifdef DAHDI_25
static const char *wp_tdmv_bri_hwec_name(const struct zt_chan *chan);
#endif
#if defined(DAHDI_24) || defined(DAHDI_25)
@ -206,6 +210,9 @@ static const struct dahdi_span_ops wp_tdm_span_ops = {
.dacs = ,
#endif
.echocan_create = wp_tdmv_bri_hwec_create,
#ifdef DAHDI_25
.echocan_name = wp_tdmv_bri_hwec_name,
#endif
};
#endif
@ -247,8 +254,9 @@ wp_bri_zap_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data)
wan_event_ctrl_t *event_ctrl = NULL;
int err = -ENOTTY, x;
WAN_ASSERT(chan == NULL || chan->pvt == NULL);
wp = wr = chan->pvt;
WAN_ASSERT(chan == NULL);
wp = wr = WP_PRIV_FROM_CHAN(chan, wp_tdmv_bri_t);
WAN_ASSERT(chan == NULL || wp == NULL);
WAN_ASSERT(wr->card == NULL);
card = wr->card;
@ -306,12 +314,9 @@ wp_bri_zap_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data)
DEBUG_TDMV_BRI("chan: 0x%p\n", chan);
if(chan){
DEBUG_TDMV_BRI("chan->pvt: 0x%p\n", chan->pvt);
}
WAN_ASSERT(chan == NULL || chan->pvt == NULL);
wp = chan->pvt;
WAN_ASSERT(chan == NULL);
wp = WP_PRIV_FROM_CHAN(chan, wp_tdmv_bri_t);
WAN_ASSERT( wp == NULL);
if (wp->dchan_dev && wp->dchan_dev->hard_start_xmit){
wp_tdmv_tx_dchan(chan, (int)data);
@ -347,8 +352,8 @@ static int wp_bri_zap_open(struct zt_chan *chan)
BRI_FUNC();
WAN_ASSERT2(chan == NULL, -ENODEV);
WAN_ASSERT2(chan->pvt == NULL, -ENODEV);
wr = chan->pvt;
wr = WP_PRIV_FROM_CHAN(chan, wp_tdmv_bri_t);
WAN_ASSERT2(wr == NULL, -ENODEV);
WAN_ASSERT2(wr->card == NULL, -ENODEV);
card = wr->card;
wr->usecount++;
@ -371,8 +376,8 @@ static int wp_bri_zap_close(struct zt_chan *chan)
BRI_FUNC();
WAN_ASSERT2(chan == NULL, -ENODEV);
WAN_ASSERT2(chan->pvt == NULL, -ENODEV);
wr = chan->pvt;
wr = WP_PRIV_FROM_CHAN(chan, wp_tdmv_bri_t);
WAN_ASSERT2(wr == NULL, -ENODEV);
WAN_ASSERT2(wr->card == NULL, -ENODEV);
card = wr->card;
wanpipe_close(card);
@ -394,6 +399,26 @@ static int wp_bri_zap_watchdog(struct zt_span *span, int event)
return 0;
}
#ifdef DAHDI_25
/* This funciton is used for dahdi 2.5 or higher */
static const char *wp_tdmv_bri_hwec_name(const struct zt_chan *chan)
{
wp_tdmv_bri_t *wr = NULL;
sdla_t *card = NULL;
WAN_ASSERT2(chan == NULL, NULL);
wr = WP_PRIV_FROM_CHAN(chan,wp_tdmv_bri_t);
WAN_ASSERT2(wr == NULL, NULL);
WAN_ASSERT2(wr->card == NULL, NULL);
card = wr->card;
if (card->wandev.ec_enable && wr->hwec == WANOPT_YES){
return "WANPIPE_HWEC";
}
return NULL;
}
#endif
#ifdef DAHDI_22
/******************************************************************************
@ -413,8 +438,8 @@ static int wp_tdmv_bri_hwec_create(struct dahdi_chan *chan,
BRI_FUNC();
WAN_ASSERT2(chan == NULL, -ENODEV);
WAN_ASSERT2(chan->pvt == NULL, -ENODEV);
wr = chan->pvt;
wr = WP_PRIV_FROM_CHAN(chan, wp_tdmv_bri_t);
WAN_ASSERT2(wr == NULL, -ENODEV);
WAN_ASSERT2(wr->card == NULL, -ENODEV);
card = wr->card;
@ -435,8 +460,8 @@ static int wp_tdmv_bri_hwec_create(struct dahdi_chan *chan,
wan_set_bit((chan->chanpos - 1), &card->wandev.rtp_tap_call_map);
wp_fax_tone_timeout_set(wr, chan->chanpos-1);
if (card->wandev.ec_enable){
DEBUG_EVENT("[TDMV_BRI]: %s: %s(): channel %d\n",
if (card->wandev.ec_enable && wr->hwec == WANOPT_YES){
DEBUG_TDMV("[TDMV_BRI]: %s: %s(): channel %d\n",
wr->devname, __FUNCTION__, chan->chanpos);
if(chan->chanpos == 1 || chan->chanpos == 2){
@ -446,9 +471,6 @@ static int wp_tdmv_bri_hwec_create(struct dahdi_chan *chan,
wr->devname, __FUNCTION__, chan->chanpos);
err = 0;
}
}else{
DEBUG_EVENT("[TDMV_BRI]: %s: %s(): card->wandev.ec_enable == NULL!!!!!!\n",
wr->devname, __FUNCTION__);
}
return err;
}
@ -467,8 +489,8 @@ static void wp_tdmv_bri_hwec_free(struct dahdi_chan *chan, struct dahdi_echocan_
memset(ec, 0, sizeof(*ec));
if(chan == NULL) return;
if(chan->pvt == NULL) return;
wr = chan->pvt;
wr = WP_PRIV_FROM_CHAN(chan, wp_tdmv_bri_t);
if(wr == NULL) return;
if(wr->card == NULL) return;
card = wr->card;
@ -478,7 +500,7 @@ static void wp_tdmv_bri_hwec_free(struct dahdi_chan *chan, struct dahdi_echocan_
return;
}
if (card->wandev.ec_enable) {
if (card->wandev.ec_enable && wr->hwec == WANOPT_YES) {
DEBUG_TDMV("[TDMV_BRI]: %s: %s(): channel %d\n",
wr->devname, __FUNCTION__, chan->chanpos);
@ -512,8 +534,8 @@ static int wp_bri_zap_hwec(struct zt_chan *chan, int enable)
BRI_FUNC();
WAN_ASSERT2(chan == NULL, -ENODEV);
WAN_ASSERT2(chan->pvt == NULL, -ENODEV);
wr = chan->pvt;
wr = WP_PRIV_FROM_CHAN(chan, wp_tdmv_bri_t);
WAN_ASSERT2(wr == NULL, -ENODEV);
WAN_ASSERT2(wr->card == NULL, -ENODEV);
card = wr->card;
fe = &card->fe;
@ -525,7 +547,7 @@ static int wp_bri_zap_hwec(struct zt_chan *chan, int enable)
wan_clear_bit(chan->chanpos-1,&card->wandev.rtp_tap_call_map);
}
if (card->wandev.ec_enable){
if (card->wandev.ec_enable && wr->hwec == WANOPT_YES){
DEBUG_EVENT("[TDMV_BRI]: %s: %s(): channel %d\n",
wr->devname, __FUNCTION__, chan->chanpos);
@ -536,10 +558,8 @@ static int wp_bri_zap_hwec(struct zt_chan *chan, int enable)
wr->devname, __FUNCTION__, chan->chanpos);
err = 0;
}
}else{
DEBUG_EVENT("[TDMV_BRI]: %s: %s(): card->wandev.ec_enable == NULL!!!!!!\n",
wr->devname, __FUNCTION__);
}
return err;
}
@ -1523,8 +1543,8 @@ static int wp_tdmv_tx_dchan(struct zt_chan *chan, int len)
int err = 0;
WAN_ASSERT2(chan == NULL, -ENODEV);
WAN_ASSERT2(chan->pvt == NULL, -ENODEV);
wp = chan->pvt;
wp = WP_PRIV_FROM_CHAN(chan, wp_tdmv_bri_t);
WAN_ASSERT2(wp == NULL, -ENODEV);
WAN_ASSERT(wp->dchan_dev == NULL);
if (len <= 2){
@ -1712,8 +1732,8 @@ static void wp_tdmv_tx_hdlc_hard(struct zt_chan *chan)
sdla_t *card = NULL;
WAN_ASSERT_VOID(chan == NULL);
WAN_ASSERT_VOID(chan->pvt == NULL);
wp = chan->pvt;
wp = WP_PRIV_FROM_CHAN(chan, wp_tdmv_bri_t);
WAN_ASSERT_VOID(wp == NULL);
WAN_ASSERT_VOID(wp->dchan_dev == NULL);
WAN_ASSERT_VOID(wp->card == NULL);
card = wp->card;

View File

@ -0,0 +1,672 @@
/*****************************************************************************
* sdla_gsm.c
*
* WANPIPE(tm) AFT W400 Hardware Support
*
* Authors: Moises Silva <moy@sangoma.com>
*
* Copyright: (c) 2011 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.
* ============================================================================
* Oct 06, 2011 Moises Silva Initial Version
*****************************************************************************/
/*
* The GSM card does not really have front end access, all register access should be done through card->hw_iface instead of fe-> pointer
*/
# 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"
# include "aft_core.h" /* for private_area_t */
# include "sdla_gsm.h"
extern WAN_LIST_HEAD(, wan_tdmv_) wan_tdmv_head;
static int wp_gsm_config(void *pfe);
static int wp_gsm_unconfig(void *pfe);
static int wp_gsm_post_init(void *pfe);
static int wp_gsm_post_unconfig(void* pfe);
static int wp_gsm_if_config(void *pfe, u32 mod_map, u8);
static int wp_gsm_if_unconfig(void *pfe, u32 mod_map, u8);
static int wp_gsm_disable_irq(void *pfe);
static int wp_gsm_intr(sdla_fe_t *);
static int wp_gsm_dchan_tx(sdla_fe_t *fe, void *src_data_buffer, u32 buffer_len);
static int wp_gsm_check_intr(sdla_fe_t *);
static int wp_gsm_polling(sdla_fe_t*);
static int wp_gsm_udp(sdla_fe_t*, void*, unsigned char*);
static unsigned int wp_gsm_active_map(sdla_fe_t* fe, unsigned char);
static unsigned char wp_gsm_fe_media(sdla_fe_t *fe);
static int wp_gsm_set_dtmf(sdla_fe_t*, int, unsigned char);
static int wp_gsm_intr_ctrl(sdla_fe_t*, int, u_int8_t, u_int8_t, unsigned int);
static int wp_gsm_event_ctrl(sdla_fe_t*, wan_event_ctrl_t*);
static int wp_gsm_get_link_status(sdla_fe_t *fe, unsigned char *status,int mod_no);
#if defined(AFT_TDM_API_SUPPORT)
static int wp_gsm_watchdog(void *card_ptr);
#endif
static void wp_gsm_toggle_pcm_loopback(sdla_t *card)
{
u32 reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_GLOBAL_REG, &reg);
if (wan_test_bit(AFT_GSM_GLOBAL_PCM_LOOPBACK_BIT, &reg)) {
wan_clear_bit(AFT_GSM_GLOBAL_PCM_LOOPBACK_BIT, &reg);
DEBUG_EVENT("%s: PCM Loopback is now disabled\n", card->devname);
} else {
wan_set_bit(AFT_GSM_GLOBAL_PCM_LOOPBACK_BIT, &reg);
DEBUG_EVENT("%s: PCM Loopback is now enabled\n", card->devname);
}
card->hw_iface.bus_write_4(card->hw, AFT_GSM_GLOBAL_REG, reg);
}
static void wp_gsm_dump_configuration(sdla_t *card)
{
u32 reg = 0;
int mod_no = card->wandev.comm_port + 1;
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_GLOBAL_REG, &reg);
DEBUG_EVENT("%s: Dumping Global Configuration (reg=%X)\n", card->devname, reg);
DEBUG_EVENT("%s: PLL Reset: %d\n", card->devname, wan_test_bit(AFT_GSM_PLL_RESET_BIT, &reg));
DEBUG_EVENT("%s: PLL Phase Shift Overflow: %d\n", card->devname, wan_test_bit(AFT_GSM_PLL_PHASE_SHIFT_OVERFLOW_BIT, &reg));
DEBUG_EVENT("%s: PLL Input Clock Lost: %d\n", card->devname, wan_test_bit(AFT_GSM_PLL_INPUT_CLOCK_LOST_BIT, &reg));
DEBUG_EVENT("%s: PLL Output Clock Stopped: %d\n", card->devname, wan_test_bit(AFT_GSM_PLL_OUTPUT_CLOCK_STOPPED_BIT, &reg));
DEBUG_EVENT("%s: PLL Locked Bit: %d\n", card->devname, wan_test_bit(AFT_GSM_PLL_LOCKED_BIT, &reg));
DEBUG_EVENT("%s: SIM Muxing Error: %d\n", card->devname, wan_test_bit(AFT_GSM_SIM_MUXING_ERROR_BIT, &reg));
DEBUG_EVENT("%s: PCM Loopback Bit: %d\n", card->devname, wan_test_bit(AFT_GSM_GLOBAL_PCM_LOOPBACK_BIT, &reg));
DEBUG_EVENT("%s: Global Shutdown Bit: %d\n", card->devname, wan_test_bit(AFT_GSM_GLOBAL_SHUTDOWN_BIT, &reg));
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_CONFIG_REG), &reg);
DEBUG_EVENT("%s: Dumping Module %d Configuration (reg=%X)\n", card->devname, mod_no, reg);
DEBUG_EVENT("%s: Module %d Power: %d\n", card->devname, mod_no, wan_test_bit(AFT_GSM_MOD_POWER_BIT, &reg));
DEBUG_EVENT("%s: Module %d Reset: %d\n", card->devname, mod_no, wan_test_bit(AFT_GSM_MOD_RESET_BIT, &reg));
DEBUG_EVENT("%s: Module %d Power Monitor: %d\n", card->devname, mod_no, wan_test_bit(AFT_GSM_MOD_POWER_MONITOR_BIT, &reg));
DEBUG_EVENT("%s: Module %d Tx Monitor: %d\n", card->devname, mod_no, wan_test_bit(AFT_GSM_MOD_TX_MONITOR_BIT, &reg));
DEBUG_EVENT("%s: Module %d SIM Inserted: %d\n", card->devname, mod_no, wan_test_bit(AFT_GSM_MOD_SIM_INSERTED_BIT, &reg));
DEBUG_EVENT("%s: Module %d SIM Select: 0x%X\n", card->devname, mod_no, aft_gsm_get_sim_no(reg));
DEBUG_EVENT("%s: Module %d UART Baud Rate: 0x%X\n", card->devname, mod_no, aft_gsm_get_uart_baud_rate(reg));
DEBUG_EVENT("%s: Module %d Service: %d\n", card->devname, mod_no, wan_test_bit(AFT_GSM_MOD_SERVICE_BIT, &reg));
}
int wp_gsm_iface_init(void *p_fe, void *pfe_iface)
{
sdla_fe_t *fe = p_fe;
sdla_fe_iface_t *fe_iface = pfe_iface;
fe_iface->config = &wp_gsm_config;
fe_iface->unconfig = &wp_gsm_unconfig;
fe_iface->post_init = &wp_gsm_post_init;
fe_iface->if_config = &wp_gsm_if_config;
fe_iface->if_unconfig = &wp_gsm_if_unconfig;
fe_iface->post_unconfig = &wp_gsm_post_unconfig;
fe_iface->active_map = &wp_gsm_active_map;
fe_iface->isr = &wp_gsm_intr;
fe_iface->disable_irq = &wp_gsm_disable_irq;
fe_iface->check_isr = &wp_gsm_check_intr;
fe_iface->polling = &wp_gsm_polling;
fe_iface->process_udp = &wp_gsm_udp;
fe_iface->get_fe_media = &wp_gsm_fe_media;
fe_iface->set_dtmf = &wp_gsm_set_dtmf;
fe_iface->intr_ctrl = &wp_gsm_intr_ctrl;
fe_iface->event_ctrl = &wp_gsm_event_ctrl;
#if defined(AFT_TDM_API_SUPPORT) || defined(AFT_API_SUPPORT)
fe_iface->watchdog = &wp_gsm_watchdog;
#endif
fe_iface->get_fe_status = &wp_gsm_get_link_status;
/* XXX this should be renamed to dchan_tx since is not BRI-specific XXX */
fe_iface->isdn_bri_dchan_tx = &wp_gsm_dchan_tx;
/*
* XXX Do we need this event initalization?? XXX
* WAN_LIST_INIT(&fe->event);
*/
wan_spin_lock_irq_init(&fe->lockirq, "wan_gsm_lock");
return 0;
}
static int wp_gsm_config(void *pfe)
{
return 0;
}
static int wp_gsm_unconfig(void *pfe)
{
return 0;
}
static int wp_gsm_post_unconfig(void *pfe)
{
return 0;
}
#define UPDATE_SIM_STATUS(card, fe) \
if (card->wandev.te_link_state) { \
card->wandev.te_link_state(card); \
} else { \
DEBUG_ERROR("%s: ERROR: GSM module %d has no te_link_state pointer!\n", card->devname, mod_no); \
} \
if (card->wandev.te_report_alarms) { \
card->wandev.te_report_alarms(card, (fe->fe_status == FE_CONNECTED ? 0 : 1)); \
}
int wp_gsm_update_sim_status(void *pcard)
{
sdla_t *card = pcard;
u32 reg = 0;
sdla_fe_t *fe = &card->fe;
int sim_inserted = 0;
int mod_no = card->wandev.comm_port + 1;
mod_no = card->wandev.comm_port + 1;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_CONFIG_REG), &reg);
sim_inserted = wan_test_bit(AFT_GSM_MOD_SIM_INSERTED_BIT, &reg) ? WAN_FALSE : WAN_TRUE;
if (sim_inserted && fe->fe_status != FE_CONNECTED) {
DEBUG_EVENT("%s: GSM module %d has a SIM inserted! (%s -> %s)\n", card->devname, mod_no,
FE_STATUS_DECODE(fe->fe_status), FE_STATUS_DECODE(FE_CONNECTED));
fe->fe_status = FE_CONNECTED;
UPDATE_SIM_STATUS(card, fe);
} else if (!sim_inserted && fe->fe_status != FE_DISCONNECTED){
DEBUG_EVENT("%s: GSM module %d has no SIM inserted! (%s -> %s)\n", card->devname, mod_no,
FE_STATUS_DECODE(fe->fe_status), FE_STATUS_DECODE(FE_DISCONNECTED));
fe->fe_status = FE_DISCONNECTED;
UPDATE_SIM_STATUS(card, fe);
}
return 0;
}
static int wp_gsm_post_init(void *pfe)
{
sdla_fe_t *fe = pfe;
sdla_t *card = fe->card;
wp_gsm_update_sim_status(card);
return 0;
}
static int wp_gsm_if_config(void *pfe, u32 mod_map, u8 usedby)
{
return 0;
}
static int wp_gsm_if_unconfig(void *pfe, u32 mod_map, u8 usedby)
{
return 0;
}
static int wp_gsm_disable_irq(void *pfe)
{
return 0;
}
/* voice active map (not dchan) */
static unsigned int wp_gsm_active_map(sdla_fe_t* fe, unsigned char line)
{
return (0x01 << (WAN_FE_LINENO(fe)));
}
static unsigned char wp_gsm_fe_media(sdla_fe_t *fe)
{
return fe->fe_cfg.media;
}
static int wp_gsm_set_dtmf(sdla_fe_t *fe, int mod_no, unsigned char val)
{
return -EINVAL;
}
static int wp_gsm_polling(sdla_fe_t* fe)
{
return 0;
}
static int wp_gsm_event_ctrl(sdla_fe_t *fe, wan_event_ctrl_t *ectrl)
{
return 0;
}
#include "sdla_gsm_inline.h"
static int wp_gsm_udp(sdla_fe_t *fe, void *p_udp_cmd, unsigned char *data)
{
wan_cmd_t *udp_cmd = (wan_cmd_t *)p_udp_cmd;
wan_femedia_t *fe_media = NULL;
sdla_t *card = fe->card;
wan_gsm_udp_t *gsm_udp = (wan_gsm_udp_t *)data;
int mod_no = 0;
u32 reg = 0;
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 = 0x00;
fe_media->max_ports = MAX_GSM_MODULES;
udp_cmd->wan_cmd_return_code = WAN_CMD_OK;
udp_cmd->wan_cmd_data_len = sizeof(wan_femedia_t);
}
break;
case WAN_GSM_REGDUMP:
{
udp_cmd->wan_cmd_return_code = WAN_CMD_OK;
udp_cmd->wan_cmd_data_len = 0;
wp_gsm_dump_configuration(card);
}
break;
case WAN_GSM_UART_DEBUG:
{
udp_cmd->wan_cmd_return_code = WAN_CMD_OK;
udp_cmd->wan_cmd_data_len = 0;
if (gsm_udp && gsm_udp->u.uart_debug == WAN_TRUE) {
wan_set_bit(AFT_GSM_UART_DEBUG_ENABLED_BIT, &card->TracingEnabled);
DEBUG_EVENT("%s: UART debugging enabled\n", card->devname);
} else {
wan_clear_bit(AFT_GSM_UART_DEBUG_ENABLED_BIT, &card->TracingEnabled);
DEBUG_EVENT("%s: UART debugging disabled\n", card->devname);
}
}
break;
case WAN_GSM_AUDIO_DEBUG:
{
udp_cmd->wan_cmd_return_code = WAN_CMD_OK;
udp_cmd->wan_cmd_data_len = 0;
DEBUG_EVENT("%s: Audio debugging toggled\n", card->devname);
wan_set_bit(AFT_GSM_AUDIO_DEBUG_TOGGLE_BIT, &card->TracingEnabled);
}
break;
case WAN_GSM_PLL_RESET:
{
udp_cmd->wan_cmd_return_code = WAN_CMD_OK;
udp_cmd->wan_cmd_data_len = 0;
wp_gsm_pll_reset(card);
}
break;
case WAN_GSM_POWER_TOGGLE:
{
int map = 0;
udp_cmd->wan_cmd_return_code = WAN_CMD_OK;
udp_cmd->wan_cmd_data_len = 0;
reg = 0;
mod_no = card->wandev.comm_port + 1;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_CONFIG_REG), &reg);
DEBUG_EVENT("%s: Performing power toggle on module %d\n", card->devname, mod_no);
if (wan_test_bit(AFT_GSM_MOD_POWER_MONITOR_BIT, &reg)) {
map = wp_gsm_toggle_power(card->hw, (1 << (mod_no - 1)), WAN_FALSE);
} else {
map = wp_gsm_toggle_power(card->hw, (1 << (mod_no - 1)), WAN_TRUE);
}
if (map) {
DEBUG_ERROR("%s: Error: Timed out performing power toggle for module %d (mod_map=0x%X)\n", card->devname, mod_no, map);
udp_cmd->wan_cmd_return_code = WAN_CMD_TIMEOUT;
}
}
break;
case WAN_GSM_UPDATE_SIM_STATUS:
{
udp_cmd->wan_cmd_return_code = WAN_CMD_OK;
udp_cmd->wan_cmd_data_len = 0;
wp_gsm_update_sim_status(card);
}
break;
case WAN_GSM_PCM_LOOPBACK:
{
udp_cmd->wan_cmd_return_code = WAN_CMD_OK;
udp_cmd->wan_cmd_data_len = 0;
wp_gsm_toggle_pcm_loopback(card);
}
break;
default:
{
udp_cmd->wan_cmd_return_code = WAN_UDP_INVALID_CMD;
udp_cmd->wan_cmd_data_len = 0;
}
break;
}
return 0;
}
static int wp_gsm_watchdog(void *card_ptr)
{
wan_smp_flag_t flags;
sdla_t *card = card_ptr;
sdla_fe_t *fe = &card->fe;
sdla_gsm_param_t *gsm_data = &fe->fe_param.gsm;
private_area_t *chan = NULL;
netskb_t *skb = NULL;
unsigned char *skb_data_area = NULL;
char uart_rx_buffer[AFT_GSM_UART_RX_FIFO_SIZE];
int txlen = 0;
int avail = 0;
int kick_user = 0;
#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE)
if (card->wan_tdmv.sc) {
/* Do nothing if configured in TDM VOICE mode (DAHDI), the UART is serviced in the DAHDI tx/rx loop code */
return 0;
}
#endif
wp_gsm_update_sim_status(card);
chan = card->u.aft.dev_to_ch_map[GSM_DCHAN_LOGIC_CHAN];
/* tx until done and call wanpipe_wake_stack() when finished */
wan_spin_lock_irq(&fe->lockirq, &flags);
/* check if we have something to transmit and space to transmit it */
if (gsm_data->uart_txbuf_len) {
avail = wp_gsm_uart_check_tx_fifo(card);
if (avail) {
txlen = avail > (gsm_data->uart_txbuf_len - gsm_data->uart_tx_cnt)
? (gsm_data->uart_txbuf_len - gsm_data->uart_tx_cnt)
: avail;
wp_gsm_uart_tx_fifo(card, (gsm_data->uart_txbuf + gsm_data->uart_tx_cnt), txlen);
gsm_data->uart_tx_cnt += txlen;
if (gsm_data->uart_tx_cnt == gsm_data->uart_txbuf_len) {
/* everything was transmitted */
gsm_data->uart_txbuf_len = 0;
gsm_data->uart_tx_cnt = 0;
chan = card->u.aft.dev_to_ch_map[GSM_DCHAN_LOGIC_CHAN];
kick_user++;
}
}
}
/* service the rx fifo */
avail = wp_gsm_uart_rx_fifo(card, uart_rx_buffer, sizeof(uart_rx_buffer));
if (avail) {
skb = wan_skb_alloc(avail);
if (skb) {
skb_data_area = wan_skb_put(skb, avail);
memcpy(skb_data_area, uart_rx_buffer, avail);
wan_skb_queue_tail(&chan->wp_rx_bri_dchan_complete_list, skb);
WAN_TASKLET_SCHEDULE((&chan->common.bh_task));
}
}
wan_spin_unlock_irq(&fe->lockirq, &flags);
if (kick_user) {
wanpipe_wake_stack(chan);
}
return 0;
}
static int wp_gsm_intr_ctrl(sdla_fe_t *fe, int mod_no, u_int8_t type, u_int8_t mode, unsigned int ts_map)
{
return 0;
}
static int wp_gsm_check_intr(sdla_fe_t *fe)
{
return 0;
}
static int wp_gsm_intr(sdla_fe_t *fe)
{
return 0;
}
static int wp_gsm_dchan_tx(sdla_fe_t *fe, void *src_data_buffer, u32 buffer_len)
{
wan_smp_flag_t flags;
sdla_t *card = fe->card;
sdla_gsm_param_t *gsm_data = &fe->fe_param.gsm;
int ret = 0;
if (!card) {
DEBUG_ERROR("No card attached to GSM front end!\n");
return 0;
}
wan_spin_lock_irq(&fe->lockirq, &flags);
if (!src_data_buffer) {
/* they want us to perform a space check */
ret = gsm_data->uart_txbuf_len;
goto done;
}
if (gsm_data->uart_txbuf_len) {
ret = -EBUSY;
goto done;
}
if (buffer_len > GSM_MAX_UART_FRAME_LEN) {
/* too big of a frame to transmit for us */
ret = -EFBIG;
goto done;
}
memcpy(gsm_data->uart_txbuf, src_data_buffer, buffer_len);
gsm_data->uart_txbuf_len = buffer_len;
done:
wan_spin_unlock_irq(&fe->lockirq, &flags);
return ret;
}
static int wp_gsm_get_link_status(sdla_fe_t *fe, unsigned char *status, int mod_no)
{
u32 reg = 0;
sdla_t *card = fe->card;
if (!card) {
DEBUG_ERROR("No card attached to GSM front end!\n");
return 0;
}
/* ignore the provided module (that one is used for multiple modules in the same line/port */
mod_no = card->wandev.comm_port + 1;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_CONFIG_REG), &reg);
if (!wan_test_bit(AFT_GSM_MOD_SIM_INSERTED_BIT, &reg)) {
*status = FE_CONNECTED;
} else {
*status = FE_DISCONNECTED;
}
return 0;
}
static char *format_uart_data(char *dest, void *indata, int len)
{
int i;
uint8_t *data = indata;
char *p = dest;
for (i = 0; i < len; i++) {
switch(data[i]) {
case '\r':
sprintf(p, "\\r");
p+=2;
break;
case '\n':
sprintf(p, "\\n");
p+=2;
break;
case 0x1a:
sprintf(p, "<sub>");
p+=5;
break;
default:
*p = data[i];
p++;
}
}
*p = '\0';
return dest;
}
int wp_gsm_uart_rx_fifo(void *pcard, unsigned char *rx_buff, int reqlen)
{
u32 reg = 0;
int i = 0;
int mod_no = 0;
int num_bytes = 0;
char rx_debug[AFT_GSM_UART_RX_FIFO_SIZE * 2];
sdla_t *card = pcard;
mod_no = card->wandev.comm_port + 1;
/* Check UART status */
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_UART_STAT_REG), &reg);
if (wan_test_bit(AFT_GSM_UART_RX_FIFO_OVERFLOW_BIT, &reg)) {
DEBUG_ERROR("%s: RX UART FIFO overflow!\n", card->devname, mod_no);
wan_clear_bit(AFT_GSM_UART_RX_FIFO_OVERFLOW_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_UART_STAT_REG), reg);
}
if (reqlen > AFT_GSM_UART_RX_FIFO_SIZE) {
DEBUG_ERROR("%s: Can't read more than UART FIFO size %d bytes, requested = %d!\n", card->devname, AFT_GSM_UART_RX_FIFO_SIZE, reqlen);
return 0;
}
/* Try to read from the UART if needed */
num_bytes = (reg >> AFT_GSM_UART_RX_FIFO_DATA_COUNT_OFFSET) & AFT_GSM_UART_RX_FIFO_DATA_COUNT_MASK;
if (num_bytes > 0 && AFT_GSM_UART_RX_FIFO_SIZE >= num_bytes) {
for (i = 0; i < num_bytes; i++) {
card->hw_iface.bus_read_4(card->hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_UART_RX_REG), &reg);
rx_buff[i] = (reg & 0xFF);
}
if (wan_test_bit(AFT_GSM_UART_DEBUG_ENABLED_BIT, &card->TracingEnabled)) {
DEBUG_EVENT("%s: UART RX %d bytes: %s\n", card->devname, num_bytes, format_uart_data(rx_debug, rx_buff, num_bytes));
}
return num_bytes;
} else if (num_bytes > 0) {
DEBUG_ERROR("%s: wtf? there is %d bytes to be received in the UART of GSM module %d "
"(max expected size = %d, requested = %d)\n", card->devname, num_bytes, mod_no, AFT_GSM_UART_RX_FIFO_SIZE, reqlen);
}
return 0;
}
int wp_gsm_uart_check_tx_fifo(void *pcard)
{
u32 reg = 0;
int mod_no = 0;
int num_bytes = 0;
sdla_t *card = pcard;
mod_no = card->wandev.comm_port + 1;
/* Check UART status */
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_UART_STAT_REG), &reg);
num_bytes = AFT_GSM_UART_TX_FIFO_SIZE - (reg & AFT_GSM_UART_TX_FIFO_DATA_COUNT_MASK);
if (num_bytes < 0) {
DEBUG_ERROR("%s: wtf? available tx bytes in UART = %d\n", card->devname, (reg & AFT_GSM_UART_TX_FIFO_DATA_COUNT_MASK));
return 0;
}
return num_bytes;
}
int wp_gsm_uart_tx_fifo(void *pcard, unsigned char *tx_buff, int len)
{
u32 reg = 0;
int i = 0;
int mod_no = 0;
int num_bytes = 0;
char tx_debug[AFT_GSM_UART_TX_FIFO_SIZE * 2];
sdla_t *card = pcard;
mod_no = card->wandev.comm_port + 1;
/* Check UART status */
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_UART_STAT_REG), &reg);
/* Verify overflow (should we do something else?) */
if (wan_test_bit(AFT_GSM_UART_TX_FIFO_OVERFLOW_BIT, &reg)) {
DEBUG_ERROR("%s: TX UART FIFO overflow in GSM module %d!\n", card->devname, mod_no);
wan_clear_bit(AFT_GSM_UART_TX_FIFO_OVERFLOW_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_UART_STAT_REG), reg);
}
reg = 0;
num_bytes = AFT_GSM_UART_TX_FIFO_SIZE - (reg & AFT_GSM_UART_TX_FIFO_DATA_COUNT_MASK);
if (num_bytes < 0) {
DEBUG_ERROR("%s: wtf? available tx bytes in UART = %d\n", card->devname, (reg & AFT_GSM_UART_TX_FIFO_DATA_COUNT_MASK));
return 0;
}
if (!num_bytes) {
DEBUG_ERROR("%s: Can't transmit anything to GSM UART module %d at the moment (requested = %d)\n", card->devname, len);
return 0;
}
if (num_bytes < len) {
DEBUG_ERROR("%s: Can't transmit more than %d bytes to GSM UART module %d at the moment (requested = %d)\n", card->devname, num_bytes, len);
len = num_bytes;
}
/* write to the UART */
for (i = 0; i < len; i++) {
reg = (tx_buff[i] & 0xFF);
card->hw_iface.bus_write_4(card->hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_UART_TX_REG), reg);
}
if (wan_test_bit(AFT_GSM_UART_DEBUG_ENABLED_BIT, &card->TracingEnabled)) {
DEBUG_EVENT("%s: UART TX %d bytes: %s\n", card->devname, len, format_uart_data(tx_debug, tx_buff, len));
}
return len;
}
int wp_gsm_pll_reset(void *pcard)
{
u32 reg = 0;
int timeout_loops = 0;
sdla_t *card = pcard;
/* Reset GSM PLL (This allows UART communication) */
DEBUG_EVENT("%s: Resetting GSM PLL (UART)\n", card->devname);
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_GLOBAL_REG, &reg);
wan_set_bit(AFT_GSM_PLL_RESET_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_GSM_GLOBAL_REG, reg);
WP_DELAY(10);
wan_clear_bit(AFT_GSM_PLL_RESET_BIT, &reg);
card->hw_iface.bus_write_4(card->hw, AFT_GSM_GLOBAL_REG, reg);
WP_DELAY(10);
for (timeout_loops = (AFT_GSM_PLL_ENABLE_TIMEOUT_MS / AFT_GSM_PLL_ENABLE_CHECK_INTERVAL_MS);
timeout_loops;
timeout_loops--) {
reg = 0;
card->hw_iface.bus_read_4(card->hw, AFT_GSM_GLOBAL_REG, &reg);
if (wan_test_bit(AFT_GSM_PLL_LOCKED_BIT, &reg)) {
break;
}
timeout_loops--;
WP_DELAY(AFT_GSM_MODULE_POWER_TOGGLE_CHECK_INTERVAL_MS * 1000);
}
return 0;
}

View File

@ -0,0 +1,737 @@
/*****************************************************************************
* sdla_gsm_tdmv.c
*
* WANPIPE(tm) AFT W400 Hardware Support for DAHDI (AKA Zaptel)
*
* Authors: Moises Silva <moy@sangoma.com>
*
* Copyright: (c) 2011 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.
* ============================================================================
* Oct 11, 2011 Moises Silva 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"
# include "sdla_gsm.h"
# include "sdla_gsm_tdmv.h"
# include "sdla_gsm_demo.h"
# include "zapcompat.h"
# include "wanpipe_dahdi_abstr.h"
#define WP_TDMV_REGISTER 1 /*0x01*/
/* our GSM hardware gives us linear audio */
#define GSM_CHUNKSIZE ZT_CHUNKSIZE * 2
#define gsm_swap16(sample) (((sample >> 8) & 0x00FF) | ((sample << 8) & 0xFF00))
extern WAN_LIST_HEAD(, wan_tdmv_) wan_tdmv_head;
static int wp_gsm_no = 0;
/*******************************************************************************
* FUNCTION PROTOTYPES
*******************************************************************************/
static int wp_tdmv_gsm_check_mtu(void* pcard, unsigned long timeslot_map, int *mtu);
static int wp_tdmv_gsm_create(void* pcard, wan_tdmv_conf_t*);
static void wp_tdmv_gsm_report_alarms(void* pcard, uint32_t te_alarm);
static int wp_tdmv_gsm_remove(void* pcard);
static int wp_tdmv_gsm_reg(void* pcard, wan_tdmv_if_conf_t*, unsigned int, unsigned char,netdevice_t*);
static int wp_tdmv_gsm_unreg(void* pcard, unsigned long ts_map);
static int wp_tdmv_gsm_software_init(wan_tdmv_t *wan_tdmv);
static int wp_tdmv_gsm_state(void* pcard, int state);
static int wp_tdmv_gsm_running(void* pcard);
static int wp_tdmv_gsm_is_rbsbits(wan_tdmv_t *wan_tdmv);
static int wp_tdmv_gsm_rx_tx_span(void *pcard);
static int wp_tdmv_gsm_rx_chan(wan_tdmv_t*, int,unsigned char*,unsigned char*);
static int wp_tdmv_gsm_rx_dchan(wan_tdmv_t*, int,unsigned char*,unsigned int);
static int wp_tdmv_gsm_ec_span(void *pcard);
#ifdef DAHDI_25
static int wp_gsm_chanconfig(struct file *file, struct zt_chan *chan, int sigtype);
#else
static int wp_gsm_chanconfig(struct zt_chan *chan, int sigtype);
#endif
static int wp_gsm_zap_open(struct zt_chan *chan);
static int wp_gsm_zap_close(struct zt_chan *chan);
static int wp_gsm_zap_hooksig(struct zt_chan *chan, zt_txsig_t txsig);
static int wp_gsm_zap_watchdog(struct zt_span *span, int event);
static int wp_gsm_zap_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data);
static void wp_tdmv_gsm_service_uart(wp_tdmv_gsm_t *gsm_span, int flush);
#if defined(DAHDI_24) || defined(DAHDI_25)
static const struct dahdi_span_ops wp_tdm_span_ops = {
.owner = THIS_MODULE,
.chanconfig = wp_gsm_chanconfig,
.open = wp_gsm_zap_open,
.close = wp_gsm_zap_close,
.ioctl = wp_gsm_zap_ioctl,
.hooksig = wp_gsm_zap_hooksig,
.watchdog = wp_gsm_zap_watchdog,
.echocan_create = NULL,
};
#endif
static int wp_gsm_zap_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data)
{
wp_tdmv_gsm_t *gsm_span = NULL;
sdla_t *card = NULL;
gsm_span = WP_PRIV_FROM_CHAN(chan, wp_tdmv_gsm_t);
WAN_ASSERT2(gsm_span == NULL, -ENODEV);
WAN_ASSERT(gsm_span->card == NULL);
card = gsm_span->card;
switch (cmd) {
case ZT_TONEDETECT:
return -ENOTTY;
break;
default:
DEBUG_ERROR("%s: GSM channel %d can't perform operation %d\n", gsm_span->devname, chan->chanpos, cmd);
DEBUG_ERROR("%s: chan=%d, cmd=0x%x\n", gsm_span->devname, chan->chanpos, cmd);
DEBUG_ERROR("%s: IOC_TYPE=0x%02X\n", gsm_span->devname, _IOC_TYPE(cmd));
DEBUG_ERROR("%s: IOC_DIR=0x%02X\n", gsm_span->devname, _IOC_DIR(cmd));
DEBUG_ERROR("%s: IOC_NR=0x%02X\n", gsm_span->devname, _IOC_NR(cmd));
DEBUG_ERROR("%s: IOC_SIZE=0x%02X\n", gsm_span->devname, _IOC_SIZE(cmd));
dump_stack();
return -ENOTTY;
break;
}
return 0;
}
static int wp_gsm_zap_hooksig(struct zt_chan *chan, zt_txsig_t txsig)
{
wp_tdmv_gsm_t *gsm_span = NULL;
sdla_t *card = NULL;
gsm_span = WP_PRIV_FROM_CHAN(chan, wp_tdmv_gsm_t);
WAN_ASSERT2(gsm_span == NULL, -ENODEV);
WAN_ASSERT(gsm_span->card == NULL);
card = gsm_span->card;
DEBUG_ERROR("%s: GSM Module %d can't perform hook operations\n", gsm_span->devname, chan->chanpos);
return -EINVAL;
}
static int wp_gsm_zap_open(struct zt_chan *chan)
{
wp_tdmv_gsm_t *gsm_span = NULL;
sdla_t *card = NULL;
WAN_ASSERT2(chan == NULL, -ENODEV);
gsm_span = WP_PRIV_FROM_CHAN(chan, wp_tdmv_gsm_t);
WAN_ASSERT2(gsm_span == NULL, -ENODEV);
WAN_ASSERT2(gsm_span->card == NULL, -ENODEV);
card = gsm_span->card;
gsm_span->usecount++;
wanpipe_open(card);
DEBUG_EVENT("%s: GSM Open (usecount=%d, channo=%d, chanpos=%d)...\n",
gsm_span->devname,
gsm_span->usecount,
chan->channo,
chan->chanpos);
/* Make sure there is nothing in the FIFOs */
wp_tdmv_gsm_service_uart(gsm_span, 1);
return 0;
}
static int wp_gsm_zap_close(struct zt_chan *chan)
{
sdla_t *card = NULL;
wp_tdmv_gsm_t *gsm_span = NULL;
sdla_fe_t *fe = NULL;
WAN_ASSERT2(chan == NULL, -ENODEV);
gsm_span = WP_PRIV_FROM_CHAN(chan, wp_tdmv_gsm_t);
WAN_ASSERT2(gsm_span == NULL, -ENODEV);
card = gsm_span->card;
fe = &card->fe;
gsm_span->usecount--;
wanpipe_close(card);
return 0;
}
static int wp_gsm_zap_watchdog(struct zt_span *span, int event)
{
DEBUG_ERROR("GSM Watchdog?!!\n");
return -1;
}
static int wp_tdmv_gsm_hook(sdla_fe_t *fe, int mod_no, int off_hook)
{
DEBUG_ERROR("GSM hook?!!\n");
return -EINVAL;
}
static int wp_tdmv_gsm_check_hook(sdla_fe_t *fe, int mod_no)
{
DEBUG_ERROR("GSM check hook?!!\n");
return -EINVAL;
}
static int wp_tdmv_gsm_buf_rotate(void *pcard, u32 buf_sz, unsigned long mask, int circ_buf_len)
{
return 0;
}
int wp_tdmv_gsm_init(wan_tdmv_iface_t *iface)
{
WAN_ASSERT(iface == NULL);
memset(iface, 0, sizeof(wan_tdmv_iface_t));
iface->check_mtu = wp_tdmv_gsm_check_mtu;
iface->create = wp_tdmv_gsm_create;
iface->remove = wp_tdmv_gsm_remove;
iface->reg = wp_tdmv_gsm_reg;
iface->unreg = wp_tdmv_gsm_unreg;
iface->software_init = wp_tdmv_gsm_software_init;
iface->state = wp_tdmv_gsm_state;
iface->running = wp_tdmv_gsm_running;
iface->is_rbsbits = wp_tdmv_gsm_is_rbsbits;
iface->rx_tx_span = wp_tdmv_gsm_rx_tx_span;
iface->rx_chan = wp_tdmv_gsm_rx_chan;
iface->rx_dchan = wp_tdmv_gsm_rx_dchan;
iface->ec_span = wp_tdmv_gsm_ec_span;
iface->buf_rotate = wp_tdmv_gsm_buf_rotate;
return 0;
}
#ifdef DAHDI_25
static int wp_gsm_chanconfig(struct file *file, struct zt_chan *chan, int sigtype)
#else
static int wp_gsm_chanconfig(struct zt_chan *chan, int sigtype)
#endif
{
wp_tdmv_gsm_t *gsm_span = NULL;
sdla_t *card = NULL;
WAN_ASSERT2(chan == NULL, -ENODEV);
gsm_span = WP_PRIV_FROM_CHAN(chan, wp_tdmv_gsm_t);
WAN_ASSERT2(gsm_span == NULL, -ENODEV);
card = gsm_span->card;
DEBUG_EVENT("%s: Configuring GSM chan %d with sigtype %d ...\n", gsm_span->devname, chan->chanpos, sigtype);
return 0;
}
static int wp_tdmv_gsm_software_init(wan_tdmv_t *wan_tdmv)
{
sdla_t *card = NULL;
sdla_fe_t *fe = NULL;
wp_tdmv_gsm_t *gsm_span = wan_tdmv->sc;
WAN_ASSERT(gsm_span == NULL);
WAN_ASSERT(gsm_span->card == NULL);
card = gsm_span->card;
fe = &card->fe;
if (wan_test_bit(WP_TDMV_REGISTER, &gsm_span->flags)){
DEBUG_EVENT("%s: Wanpipe device is already registered to DAHDI span # %d!\n", gsm_span->devname, gsm_span->span.spanno);
return 0;
}
/* Fill in DAHDI fields */
sprintf(gsm_span->span.name, "WGSM/%d", gsm_span->num);
sprintf(gsm_span->span.desc, "Wanpipe GSM Board %d", gsm_span->num + 1);
switch(fe->fe_cfg.tdmv_law){
case WAN_TDMV_ALAW:
gsm_span->span.deflaw = ZT_LAW_ALAW;
break;
case WAN_TDMV_MULAW:
gsm_span->span.deflaw = ZT_LAW_MULAW;
break;
}
/* Setup the voice channel */
sprintf(gsm_span->chans[GSM_VOICE_CHANNEL].name, "WGSM/%d/1", gsm_span->num);
gsm_span->chans[GSM_VOICE_CHANNEL].sigcap = ZT_SIG_CLEAR;
gsm_span->chans[GSM_VOICE_CHANNEL].chanpos = 1;
gsm_span->chans[GSM_VOICE_CHANNEL].pvt = gsm_span;
/* Setup the UART (d-chan) channel */
sprintf(gsm_span->chans[GSM_UART_CHANNEL].name, "WGSM/%d/2", gsm_span->num);
gsm_span->chans[GSM_UART_CHANNEL].sigcap = ZT_SIG_HARDHDLC;
gsm_span->chans[GSM_UART_CHANNEL].chanpos = 2;
gsm_span->chans[GSM_UART_CHANNEL].pvt = gsm_span;
#if defined(DAHDI_24) || defined(DAHDI_25)
gsm_span->span.ops = &wp_tdm_span_ops;
#else
gsm_span->span.pvt = gsm_span;
#if defined(DAHDI_23)
gsm_span->span.owner = THIS_MODULE;
#endif
gsm_span->span.hooksig = wp_gsm_zap_hooksig;
gsm_span->span.open = wp_gsm_zap_open;
gsm_span->span.close = wp_gsm_zap_close;
gsm_span->span.ioctl = wp_gsm_zap_ioctl;
gsm_span->span.watchdog = wp_gsm_zap_watchdog;
gsm_span->span.chanconfig = wp_gsm_chanconfig;
#endif
#ifdef DAHDI_ISSUES
gsm_span->span.chans = gsm_span->chans_ptrs;
#else
gsm_span->span.chans = gsm_span->chans;
#endif
gsm_span->span.channels = MAX_GSM_CHANNELS;
#if defined(__LINUX__)
#ifndef DAHDI_25
init_waitqueue_head(&gsm_span->span.maintq);
#endif
#endif
if (wp_dahdi_register_device(gsm_span)) {
DEBUG_EVENT("%s: Unable to register zaptel span\n", gsm_span->devname);
return -EINVAL;
}
if (gsm_span->span.spanno != gsm_span->spanno +1){
DEBUG_EVENT("\n");
DEBUG_EVENT("WARNING: Span number %d is already used by another device!\n", gsm_span->spanno + 1);
DEBUG_EVENT(" Possible cause: Another TDM driver already loaded!\n");
DEBUG_EVENT(" Solution: Unload wanpipe and check currently\n");
DEBUG_EVENT(" used spans in /proc/zaptel directory.\n");
DEBUG_EVENT(" Reconfiguring device %s to new span number # %d\n",
gsm_span->devname, gsm_span->span.spanno);
DEBUG_EVENT("\n");
gsm_span->spanno = gsm_span->span.spanno - 1;
} else {
DEBUG_EVENT("%s: Wanpipe GSM device is registered to Zaptel span # %d!\n", gsm_span->devname, gsm_span->span.spanno);
}
wan_set_bit(WP_TDMV_REGISTER, &gsm_span->flags);
return 0;
}
static void wp_tdmv_gsm_release(wp_tdmv_gsm_t *gsm_span)
{
WAN_ASSERT1(gsm_span == NULL);
if (wan_test_bit(WP_TDMV_REGISTER, &gsm_span->flags)){
DEBUG_EVENT("%s: Unregistering Wanpipe GSM from DAHDI!\n", gsm_span->devname);
wp_dahdi_unregister_device(gsm_span);
wan_clear_bit(WP_TDMV_REGISTER, &gsm_span->flags);
}
wp_dahdi_free_device(gsm_span);
wan_free(gsm_span);
return;
}
static int wp_tdmv_gsm_check_mtu(void *pcard, unsigned long timeslot_map, int *mtu)
{
*mtu = GSM_CHUNKSIZE;
return 0;
}
static void wp_tdmv_gsm_report_alarms(void *pcard, uint32_t te_alarm)
{
sdla_t *card = (sdla_t*)pcard;
wan_tdmv_t *wan_tdmv = &card->wan_tdmv;
wp_tdmv_gsm_t *gsm_span = wan_tdmv->sc;
if (te_alarm == 0){
gsm_span->span.alarms = ZT_ALARM_NONE;
zt_alarm_notify(&gsm_span->span);
} else {
gsm_span->span.alarms = ZT_ALARM_RED;
zt_alarm_notify(&gsm_span->span);
}
}
static int wp_tdmv_gsm_create(void *pcard, wan_tdmv_conf_t *tdmv_conf)
{
sdla_t *card = (sdla_t*)pcard;
wp_tdmv_gsm_t *gsm_span = NULL;
wan_tdmv_t *tmp = NULL;
sdla_fe_t *fe = NULL;
#ifdef DAHDI_ISSUES
int i;
#endif
WAN_ASSERT(card == NULL);
WAN_ASSERT(tdmv_conf->span_no == 0);
fe = &card->fe;
WAN_LIST_FOREACH(tmp, &wan_tdmv_head, next){
if (tmp->spanno == tdmv_conf->span_no){
DEBUG_EVENT("%s: Registering GSM device with an incorrect span number!\n",
card->devname);
DEBUG_EVENT("%s: Another Wanpipe device already configured to span #%d!\n",
card->devname, tdmv_conf->span_no);
return -EINVAL;
}
if (!WAN_LIST_NEXT(tmp, next)){
break;
}
}
memset(&card->wan_tdmv, 0x0, sizeof(wan_tdmv_t));
card->wan_tdmv.max_timeslots = MAX_GSM_CHANNELS;
card->wan_tdmv.spanno = tdmv_conf->span_no;
card->wandev.fe_notify_iface.hook_state = wp_tdmv_gsm_hook;
card->wandev.fe_notify_iface.check_hook_state = wp_tdmv_gsm_check_hook;
gsm_span = wan_malloc(sizeof(*gsm_span));
if (gsm_span == NULL){
return -ENOMEM;
}
memset(gsm_span, 0, sizeof(*gsm_span));
card->wan_tdmv.sc = gsm_span;
gsm_span->spanno = tdmv_conf->span_no - 1;
#ifdef DAHDI_ISSUES
if (wp_dahdi_create_device(card,gsm_span)) {
wan_free(gsm_span);
return -ENOMEM;
}
WP_DAHDI_SET_STR_INFO(gsm_span,manufacturer,"Sangoma Technologies");
switch(card->adptr_type){
case AFT_ADPTR_W400:
WP_DAHDI_SET_STR_INFO(gsm_span,devicetype,"W400");
break;
default:
WP_DAHDI_SET_STR_INFO(gsm_span,devicetype,"nsupported GSM Adapter");
break;
}
WP_DAHDI_SET_STR_INFO(gsm_span,location,"SLOT=%d, BUS=%d", card->wandev.S514_slot_no, card->wandev.S514_bus_no);
#endif
#ifndef DAHDI_26
gsm_span->span.irq = card->wandev.irq;
#endif
gsm_span->num = wp_gsm_no++;
gsm_span->card = card;
gsm_span->devname = card->devname;
#ifdef DAHDI_ISSUES
for (i = 0; i < sizeof(gsm_span->chans)/sizeof(gsm_span->chans[0]); i++) {
gsm_span->chans_ptrs[i] = &gsm_span->chans[i];
}
#endif
if (tmp) {
WAN_LIST_INSERT_AFTER(tmp, &card->wan_tdmv, next);
} else {
WAN_LIST_INSERT_HEAD(&wan_tdmv_head, &card->wan_tdmv, next);
}
card->wandev.te_report_alarms = wp_tdmv_gsm_report_alarms;
if (fe->fe_status != FE_CONNECTED) {
gsm_span->span.alarms = ZT_ALARM_RED;
}
return 0;
}
static int wp_tdmv_gsm_reg(void *pcard, wan_tdmv_if_conf_t *tdmv_conf,
unsigned int active_ch,
unsigned char ec_enable,
netdevice_t *dev)
{
sdla_t *card = (sdla_t*)pcard;
wan_tdmv_t *wan_tdmv = &card->wan_tdmv;
wp_tdmv_gsm_t *gsm_span = NULL;
WAN_ASSERT(wan_tdmv->sc == NULL);
gsm_span = wan_tdmv->sc;
if (wan_test_bit(WP_TDMV_REGISTER, &gsm_span->flags)){
DEBUG_ERROR("%s: Error: Master device has already been configured!\n", card->devname);
return -EINVAL;
}
/* 1 is voice channel ... anything else must be the D-channel */
if (active_ch != 1) {
return GSM_UART_CHANNEL;
}
memset(gsm_span->chans[GSM_VOICE_CHANNEL].sreadchunk, 0, ZT_CHUNKSIZE);
memset(gsm_span->chans[GSM_VOICE_CHANNEL].swritechunk, 0, ZT_CHUNKSIZE);
gsm_span->chans[GSM_VOICE_CHANNEL].readchunk = gsm_span->chans[GSM_VOICE_CHANNEL].sreadchunk;
gsm_span->chans[GSM_VOICE_CHANNEL].writechunk = gsm_span->chans[GSM_VOICE_CHANNEL].swritechunk;
return GSM_VOICE_CHANNEL;
}
static int wp_tdmv_gsm_unreg(void* pcard, unsigned long ts_map)
{
sdla_t *card = (sdla_t*)pcard;
wan_tdmv_t *wan_tdmv = &card->wan_tdmv;
wp_tdmv_gsm_t *gsm_span = NULL;
WAN_ASSERT(wan_tdmv->sc == NULL);
gsm_span = wan_tdmv->sc;
memset(gsm_span->chans[GSM_VOICE_CHANNEL].sreadchunk, 0, ZT_CHUNKSIZE);
memset(gsm_span->chans[GSM_VOICE_CHANNEL].swritechunk, 0, ZT_CHUNKSIZE);
gsm_span->chans[GSM_VOICE_CHANNEL].readchunk = gsm_span->chans[GSM_VOICE_CHANNEL].sreadchunk;
gsm_span->chans[GSM_VOICE_CHANNEL].writechunk = gsm_span->chans[GSM_VOICE_CHANNEL].swritechunk;
return 0;
}
static int wp_tdmv_gsm_remove(void *pcard)
{
wp_tdmv_gsm_t *gsm_span = NULL;
sdla_t *card = (sdla_t*)pcard;
wan_tdmv_t *wan_tdmv = &card->wan_tdmv;
gsm_span = wan_tdmv->sc;
if (!gsm_span){
return -EINVAL;
}
if (gsm_span->usecount) {
DEBUG_ERROR("%s: ERROR: Wanpipe is still in use!\n", card->devname);
return -EINVAL;
}
wan_tdmv->sc = NULL;
WAN_LIST_REMOVE(wan_tdmv, next);
wp_tdmv_gsm_release(gsm_span);
return 0;
}
static int wp_tdmv_gsm_state(void *pcard, int state)
{
sdla_t *card = (sdla_t*)pcard;
wan_tdmv_t *wan_tdmv = &card->wan_tdmv;
wp_tdmv_gsm_t *gsm_span = NULL;
WAN_ASSERT(wan_tdmv->sc == NULL);
gsm_span = (wp_tdmv_gsm_t *)wan_tdmv->sc;
switch(state){
case WAN_CONNECTED:
DEBUG_EVENT("%s: TDMV GSM state is CONNECTED!\n", gsm_span->devname);
break;
case WAN_DISCONNECTED:
DEBUG_EVENT("%s: TDMV GSM state is DISCONNECTED!\n", gsm_span->devname);
break;
}
return 0;
}
static int wp_tdmv_gsm_running(void *pcard)
{
sdla_t *card = (sdla_t*)pcard;
wan_tdmv_t *wan_tdmv = &card->wan_tdmv;
wp_tdmv_gsm_t *gsm_span = NULL;
gsm_span = wan_tdmv->sc;
if (gsm_span && gsm_span->usecount){
DEBUG_EVENT("%s: WARNING: Span is still in use!\n", card->devname);
return -EINVAL;
}
return 0;
}
static int wp_tdmv_gsm_is_rbsbits(wan_tdmv_t *wan_tdmv)
{
return -EINVAL;
}
static void wp_tdmv_gsm_service_uart(wp_tdmv_gsm_t *gsm_span, int flush)
{
struct zt_chan *uart_chan = NULL;
int num_bytes = 0;
int hdlc_bytes = 0;
int res = 0;
int mod_no = 0;
char uart_rx_buffer[AFT_GSM_UART_RX_FIFO_SIZE];
char uart_tx_buffer[AFT_GSM_UART_TX_FIFO_SIZE];
sdla_t *card = gsm_span->card;
card = gsm_span->card;
mod_no = card->wandev.comm_port + 1;
uart_chan = &gsm_span->span.chans[GSM_UART_CHANNEL];
num_bytes = wp_gsm_uart_rx_fifo(card, uart_rx_buffer, sizeof(uart_rx_buffer));
if (num_bytes) {
if (flush) {
DEBUG_WARNING("%s: Dropping %d bytes from UART of GSM module %d\n", gsm_span->devname, num_bytes, mod_no);
} else {
zt_hdlc_putbuf(uart_chan, uart_rx_buffer, num_bytes);
zt_hdlc_finish(uart_chan);
}
}
if (flush) {
/* We can't flush the write fifos so we're done here */
return;
}
num_bytes = wp_gsm_uart_check_tx_fifo(card);
/* Try to write to the UART if there is something to write and if possible (UART ready) */
if (num_bytes > 0) {
/* There is space available to transmit something, check if there is anything to transmit in the HDLC buffers */
hdlc_bytes = num_bytes;
res = zt_hdlc_getbuf(uart_chan, uart_tx_buffer, &hdlc_bytes);
if (hdlc_bytes) {
wp_gsm_uart_tx_fifo(card, uart_tx_buffer, hdlc_bytes);
}
}
}
static int wp_tdmv_gsm_rx_dchan(wan_tdmv_t *wan_tdmv, int channo, unsigned char *buf, unsigned int len)
{
sdla_t *card = NULL;
wp_tdmv_gsm_t *gsm_span = wan_tdmv->sc;
WAN_ASSERT2(gsm_span == NULL, -EINVAL);
card = gsm_span->card;
DEBUG_ERROR("%s: Error: I should never be called??! (chan = %d)\n", card->devname, len);
return 0;
}
static int wp_tdmv_gsm_rx_chan(wan_tdmv_t *wan_tdmv, int channo, unsigned char *rxbuf, unsigned char *txbuf)
{
sdla_t *card = NULL;
wp_tdmv_gsm_t *gsm_span = wan_tdmv->sc;
struct zt_chan *voice_chan = NULL;
WAN_ASSERT2(gsm_span == NULL, -EINVAL);
card = gsm_span->card;
voice_chan = &gsm_span->span.chans[GSM_VOICE_CHANNEL];
/* Save the DMA tx/rx buffers provided by wanpipe, we'll write/read to/from them in wp_tdmv_gsm_rx_tx_span */
voice_chan->readchunk = rxbuf;
voice_chan->writechunk = txbuf;
/* This should be used without SWRING */
zt_ec_chunk(voice_chan, voice_chan->readchunk, gsm_span->ec_chunk);
memcpy(gsm_span->ec_chunk, voice_chan->writechunk, ZT_CHUNKSIZE);
wp_tdmv_gsm_service_uart(gsm_span, 0);
wp_gsm_update_sim_status(card);
return 0;
}
static int wp_tdmv_gsm_rx_tx_span(void *pcard)
{
sdla_t *card = (sdla_t*)pcard;
wan_tdmv_t *wan_tdmv = &card->wan_tdmv;
wp_tdmv_gsm_t *gsm_span = NULL;
unsigned short *gsm_rx_samples = NULL;
unsigned char *gsm_tx_samples = NULL;
unsigned char rx_samples[ZT_CHUNKSIZE];
unsigned short tx_samples[ZT_CHUNKSIZE];
int mod_no = 0;
int i = 0;
int debug_i = 0;
struct zt_chan *voice_chan = NULL;
WAN_ASSERT(wan_tdmv->sc == NULL);
gsm_span = wan_tdmv->sc;
mod_no = card->wandev.comm_port + 1;
voice_chan = &gsm_span->span.chans[GSM_VOICE_CHANNEL];
if (wan_test_bit(AFT_GSM_AUDIO_DEBUG_TOGGLE_BIT, &card->TracingEnabled)) {
if (!gsm_span->audio_debug_i) {
DEBUG_EVENT("%s: Starting playback of debug audio\n", card->devname);
wan_clear_bit(AFT_GSM_AUDIO_DEBUG_TOGGLE_BIT, &card->TracingEnabled);
gsm_span->audio_debug_i = 1; /* always skip sample zero */
} else {
DEBUG_EVENT("%s: Stopping playback of debug audio\n", card->devname);
wan_clear_bit(AFT_GSM_AUDIO_DEBUG_TOGGLE_BIT, &card->TracingEnabled);
gsm_span->audio_debug_i = 0;
}
}
gsm_rx_samples = (short *)voice_chan->readchunk;
if (gsm_span->audio_debug_i) {
debug_i = gsm_span->audio_debug_i;
for (i = 0; i < ZT_CHUNKSIZE; i++) {
short demo_sample = ZT_MULAW(gsm_demo_congrats[debug_i]);
rx_samples[i] = ZT_LIN2X(demo_sample, voice_chan);
debug_i++;
}
} else {
for (i = 0; i < ZT_CHUNKSIZE; i++) {
rx_samples[i] = ZT_LIN2X(gsm_swap16(gsm_rx_samples[i]), voice_chan);
}
}
/* XXX FIXME: optimize this and transcode without helper buffer rx_samples to avoid this memcpy XXX */
memcpy(voice_chan->readchunk, rx_samples, ZT_CHUNKSIZE);
zt_receive(&gsm_span->span);
zt_transmit(&gsm_span->span);
gsm_tx_samples = voice_chan->writechunk;
if (gsm_span->audio_debug_i) {
debug_i = gsm_span->audio_debug_i;
for (i = 0; i < ZT_CHUNKSIZE; i++) {
tx_samples[i] = gsm_swap16(ZT_MULAW(gsm_demo_congrats[debug_i]));
debug_i++;
}
} else {
for (i = 0; i < ZT_CHUNKSIZE; i++) {
tx_samples[i] = gsm_swap16(ZT_XLAW(gsm_tx_samples[i], voice_chan));
}
}
memcpy(voice_chan->writechunk, tx_samples, GSM_CHUNKSIZE);
if (gsm_span->audio_debug_i) {
gsm_span->audio_debug_i += ZT_CHUNKSIZE;
if (gsm_span->audio_debug_i >= sizeof(gsm_demo_congrats)) {
DEBUG_EVENT("%s: Wrapping playback of debug audio\n", card->devname);
gsm_span->audio_debug_i = 1; /* start over skipping sample 0 which is used as a flag */
}
}
return 0;
}
static int wp_tdmv_gsm_ec_span(void *pcard)
{
sdla_t *card = (sdla_t*)pcard;
wan_tdmv_t *wan_tdmv = &card->wan_tdmv;
wp_tdmv_gsm_t *gsm_span = NULL;
WAN_ASSERT(wan_tdmv->sc == NULL);
gsm_span = wan_tdmv->sc;
zt_ec_span(&gsm_span->span);
return 0;
}

View File

@ -37,10 +37,13 @@
# include "wanpipe_dahdi_abstr.h" /* Map of Zaptel -> DAHDI definitions */
#endif
#if 0
#ifdef DEBUG_TEST
#undef DEBUG_TEST
#define DEBUG_TEST DEBUG_EVENT
#endif
#endif
/*******************************************************************************
** DEFINES AND MACROS
*******************************************************************************/
@ -125,6 +128,10 @@ static void wp_tdmv_remora_hwec_free(struct dahdi_chan *chan,
struct dahdi_echocan_state *ec);
#endif
#ifdef DAHDI_25
static const char *wp_tdmv_remora_hwec_name(const struct zt_chan *chan);
#endif
#if 0
#define WAN_SYNC_RX_TX_TEST 1
#warning "WAN_SYNC_RX_TX_TEST: Test option Enabled"
@ -151,6 +158,9 @@ static const struct dahdi_span_ops wp_tdm_span_ops = {
.dacs = ,
#endif
.echocan_create = wp_tdmv_remora_hwec_create,
#ifdef DAHDI_25
.echocan_name = wp_tdmv_remora_hwec_name,
#endif
};
#endif
@ -170,6 +180,7 @@ static const struct dahdi_echocan_features wp_tdmv_remora_ec_features = {
static const struct dahdi_echocan_ops wp_tdmv_remora_ec_ops = {
#ifndef DAHDI_25
/* This option is used on dahdi 2.4 or lower */
.name = "WANPIPE_HWEC",
#endif
.echocan_free = wp_tdmv_remora_hwec_free,
@ -501,7 +512,25 @@ static int wp_remora_zap_watchdog(struct zt_span *span, int event)
return 0;
}
#ifdef DAHDI_25
/* This funciton is used for dahdi 2.5 or higher */
static const char *wp_tdmv_remora_hwec_name(const struct zt_chan *chan)
{
wp_tdmv_remora_t *wr = NULL;
sdla_t *card = NULL;
WAN_ASSERT2(chan == NULL, NULL);
wr = WP_PRIV_FROM_CHAN(chan,wp_tdmv_remora_t);
WAN_ASSERT2(wr == NULL, NULL);
WAN_ASSERT2(wr->card == NULL, NULL);
card = wr->card;
if (card->wandev.ec_enable && wr->hwec == WANOPT_YES){
return "WANPIPE_HWEC";
}
return NULL;
}
#endif
#ifdef DAHDI_22
@ -538,7 +567,7 @@ static int wp_tdmv_remora_hwec_create(struct dahdi_chan *chan,
wan_set_bit(chan->chanpos-1,&card->wandev.rtp_tap_call_map);
wp_fax_tone_timeout_set(wr,(chan->chanpos-1));
if (card->wandev.ec_enable){
if (card->wandev.ec_enable && wr->hwec == WANOPT_YES){
/* The ec persist flag enables and disables
* persistent echo control. In persist mode
* echo cancellation is enabled regardless of
@ -558,6 +587,7 @@ static int wp_tdmv_remora_hwec_create(struct dahdi_chan *chan,
(err==0) ? "Enable" : "Disable",
chan->chanpos);
}
return err;
}
@ -584,7 +614,7 @@ static void wp_tdmv_remora_hwec_free(struct dahdi_chan *chan, struct dahdi_echoc
wan_clear_bit(chan->chanpos-1, &card->wandev.rtp_tap_call_map);
if (card->wandev.ec_enable) {
if (card->wandev.ec_enable && wr->hwec == WANOPT_YES) {
/* The ec persist flag enables and disables
* persistent echo control. In persist mode
* echo cancellation is enabled regardless of
@ -635,7 +665,7 @@ static int wp_remora_zap_hwec(struct zt_chan *chan, int enable)
wan_clear_bit(chan->chanpos-1,&card->wandev.rtp_tap_call_map);
}
if (card->wandev.ec_enable){
if (card->wandev.ec_enable && wr->hwec == WANOPT_YES){
/* The ec persist flag enables and disables
* persistent echo control. In persist mode
* echo cancellation is enabled regardless of
@ -1443,11 +1473,12 @@ static int wp_tdmv_remora_rx_tx_span(void *pcard)
static int wp_tdmv_remora_ec_span(void *pcard)
{
sdla_t *card = (sdla_t*)pcard;
wan_tdmv_t *wan_tdmv = &card->wan_tdmv;
wp_tdmv_remora_t *wr = NULL;
wan_tdmv_t *wan_tdmv = &card->wan_tdmv;
wp_tdmv_remora_t *wr = NULL;
WAN_ASSERT(wan_tdmv->sc == NULL);
wr = wan_tdmv->sc;
WAN_ASSERT(wan_tdmv->sc == NULL);
wr = wan_tdmv->sc;
zt_ec_span(&wr->span);

View File

@ -283,6 +283,10 @@ static void wp_tdmv_hwec_free(struct dahdi_chan *chan,
static int wp_tdmv_hwec(struct zt_chan *chan, int enable);
#endif
#ifdef DAHDI_25
static const char *wp_tdmv_hwec_name(const struct zt_chan *chan);
#endif
#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN) && defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE_DCHAN_ZAPTEL)
static void wp_tdmv_tx_hdlc_hard(struct zt_chan *chan);
@ -345,6 +349,10 @@ static const struct dahdi_span_ops wp_tdm_span_ops = {
.dacs = ,
#endif
.echocan_create = wp_tdmv_hwec_create,
#ifdef DAHDI_25
.echocan_name = wp_tdmv_hwec_name,
#endif
};
#endif
@ -426,9 +434,9 @@ static int wp_tdmv_create(void* pcard, wan_tdmv_conf_t *tdmv_conf)
sdla_t *card = (sdla_t*)pcard;
wp_tdmv_softc_t *wp = NULL;
wan_tdmv_t *tmp = NULL;
int err=0;
#ifdef DAHDI_ISSUES
int err=0;
int i;
#endif
@ -2264,6 +2272,26 @@ wp_tdmv_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data)
return err;
}
#ifdef DAHDI_25
/* This funciton is used for dahdi 2.5 or higher */
static const char *wp_tdmv_hwec_name(const struct zt_chan *chan)
{
wp_tdmv_softc_t *wr = NULL;
sdla_t *card = NULL;
WAN_ASSERT2(chan == NULL, NULL);
wr = WP_PRIV_FROM_CHAN(chan,wp_tdmv_softc_t);
WAN_ASSERT2(wr == NULL, NULL);
WAN_ASSERT2(wr->card == NULL, NULL);
card = wr->card;
if (card->wandev.ec_enable && wr->hwec == WANOPT_YES){
return "WANPIPE_HWEC";
}
return NULL;
}
#endif
#ifdef DAHDI_22
/******************************************************************************
@ -2303,7 +2331,7 @@ static int wp_tdmv_hwec_create(struct dahdi_chan *chan,
wp_fax_tone_timeout_set(wp, chan->chanpos-1);
if (card->wandev.ec_enable){
if (card->wandev.ec_enable && wp->hwec == WANOPT_YES){
DEBUG_TDMV("[TDMV] %s: %s HW echo canceller on channel %d\n",
wp->devname,
"Enable",
@ -2348,7 +2376,7 @@ static void wp_tdmv_hwec_free(struct dahdi_chan *chan, struct dahdi_echocan_stat
wan_clear_bit(chan->chanpos-1, &card->wandev.rtp_tap_call_map);
if (card->wandev.ec_enable) {
if (card->wandev.ec_enable && wp->hwec == WANOPT_YES) {
DEBUG_TDMV("[TDMV] %s: Disable HW echo canceller on channel %d\n",
wp->devname, chan->chanpos);
@ -2398,7 +2426,7 @@ static int wp_tdmv_hwec(struct zt_chan *chan, int enable)
wan_clear_bit(chan->chanpos-1,&card->wandev.rtp_tap_call_map);
}
if (card->wandev.ec_enable){
if (card->wandev.ec_enable && wp->hwec == WANOPT_YES){
DEBUG_TDMV("[TDMV] %s: %s HW echo canceller on channel %d\n",
wp->devname,
(enable) ? "Enable" : "Disable",

View File

@ -1461,11 +1461,13 @@ static int wp_usb_tdmv_remora_create(void* pcard, wan_tdmv_conf_t *tdmv_conf)
return -ENOMEM;
}
#ifdef DAHDI_ISSUES
WP_DAHDI_SET_STR_INFO(wr,manufacturer,"Sangoma Technologies");
WP_DAHDI_SET_STR_INFO(wr,devicetype, "U100");
WP_DAHDI_SET_STR_INFO(wr,location,"SLOT=%d, BUS=%d", card->wandev.S514_slot_no, card->wandev.S514_bus_no);
#ifdef DAHDI_ISSUES
for (i = 0; i < sizeof(wr->chans)/sizeof(wr->chans[0]); i++) {
wr->chans_ptrs[i] = &wr->chans[i];
}

View File

@ -224,6 +224,12 @@
#define MODULE2 2
#define MODULE3 4
#define AFT_CHIP_CFG_REG 0x40
#define AFT_CHIPCFG_SFR_IN_BIT 2
#define AFT_CHIPCFG_SFR_EX_BIT 1
#define AFT_CHIPCFG_B600_EC_CHIP_PRESENT_BIT 20
#define AFT_CHIPCFG_B600_EC_RESET_BIT 25
#if 0
static unsigned char wan_index_map[24][32][32];
static unsigned char wan_index_cnt=0;
@ -435,6 +441,11 @@ extern u_int8_t __sdla_a600_read_fe (void* phw, ...);
extern u_int8_t sdla_a600_read_fe (void* phw, ...);
extern void sdla_a600_reset_fe (void* fe);
extern int sdla_w400_write_fe (void* phw, ...);
extern u_int8_t __sdla_w400_read_fe (void* phw, ...);
extern u_int8_t sdla_w400_read_fe (void* phw, ...);
extern void sdla_w400_reset_fe (void* fe);
extern int sdla_b800_write_fe (void* phw, ...);
extern u_int8_t __sdla_b800_read_fe (void* phw, ...);
extern u_int8_t sdla_b800_read_fe (void* phw, ...);
@ -909,6 +920,11 @@ static __inline void SDLA_PROBE_SPRINT(char *str,...)
#define SDLA_HWPROBE_USB_FORMAT_DUMP \
"|ID=%s|BUSID=%s|V=%02X"
#define SDLA_HWPROBE_W400_SH_FORMAT \
"%-10s : SLOT=%d : BUS=%d : IRQ=%d : PORT=%d : V=%02X"
#define SDLA_HWPROBE_W400_SH_FORMAT_DUMP \
"|ID=%s|SLOT=%d|BUS=%d|IRQ=%d|PORT=%d|V=%02X"
static int
sdla_save_hw_probe (sdlahw_t* hw, int port)
{
@ -1094,6 +1110,17 @@ sdla_save_hw_probe (sdlahw_t* hw, int port)
port ? "SEC" : "PRI");
}
break;
case AFT_ADPTR_W400:
SDLA_PROBE_SPRINT(hwprobe->hw_info,
sizeof(hwprobe->hw_info),
SDLA_HWPROBE_W400_SH_FORMAT,
hwcpu->hwcard->adptr_name,
hwcpu->hwcard->u_pci.slot_no,
hwcpu->hwcard->u_pci.bus_no,
hwcpu->irq,
hw->line_no+1, /* Physical line number */
hwcpu->hwcard->core_rev);
break;
case AFT_ADPTR_ISDN:
case AFT_ADPTR_B500:
SDLA_PROBE_SPRINT(hwprobe->hw_info,
@ -1388,7 +1415,158 @@ sdla_hwdev_serial_register(sdlahw_cpu_t* hwcpu, int max_line_no)
return first_hw;
}
/* ideally this function should be used as well in sdla_get_hw_info() which resets
* the fpga for different type of hardware, but the sequence seems to be the same */
static void sdla_reset_fpga(sdlahw_t *hw)
{
u32 reg = 0;
wan_set_bit(AFT_CHIPCFG_SFR_IN_BIT, &reg);
wan_set_bit(AFT_CHIPCFG_SFR_EX_BIT, &reg);
sdla_bus_write_4(hw, SDLA_REG_OFF(hw->hwcpu->hwcard, AFT_CHIP_CFG_REG), reg);
WP_DELAY(10);
wan_clear_bit(AFT_CHIPCFG_SFR_IN_BIT, &reg);
wan_clear_bit(AFT_CHIPCFG_SFR_EX_BIT, &reg);
sdla_bus_write_4(hw, SDLA_REG_OFF(hw->hwcpu->hwcard, AFT_CHIP_CFG_REG), reg);
WP_DELAY(10);
}
#include "sdla_gsm_inline.h"
static sdlahw_t *sdla_hwdev_w400_register(sdlahw_cpu_t *hwcpu, int *lines_number)
{
sdlahw_t *hw = NULL;
sdlahw_t *mod_hw[MAX_GSM_MODULES];
sdlahw_port_t *curr_port = NULL;
int mod_no = 0;
int line_no = 0;
int mod_map = 0;
int ret_map = 0;
u32 line_map = 0;
if ((hw = sdla_hw_register(hwcpu, 0)) == NULL){
return NULL;
}
if (sdla_memory_map(hw)){
sdla_hw_unregister(hw);
return NULL;
}
/* In order to check for module presence we must reset the fpga */
sdla_reset_fpga(hw);
/* check for present modules */
#ifndef WAN_GSM_SLOW_HWPROBE
/* Fast hwprobe uses gsm registry configuration to determine if the module is present,
* our hw guys do not seem very sure this is reliable as they are checking some pin
* in the gsm module and are unsure of whether that is always low/high when booting
* or something. I remember seeing once that wanrouter hwprobe did not return
* the modules I had present. However at that point I was messing up with the driver and
* probably I left the module turned-on on port stop or something and on reboot things
* did not work, so I think this is reliable as long as the driver properly turns off
* the GSM module on shutdown, in case that was not the case, we try to turn them off now if needed */
ret_map = wp_gsm_toggle_power(hw, AFT_GSM_ALL_MODULES_MASK, WAN_FALSE);
if (ret_map) {
DEBUG_ERROR("%s: Error: Some GSM modules were not turned off before hwprobe (mod_map=%X)\n", hw->devname, ret_map);
}
for (mod_no = 1; mod_no <= MAX_GSM_MODULES; mod_no++) {
u32 reg = 0;
/* Check if there is a module present in this line */
reg = 0;
sdla_bus_read_4(hw, AFT_GSM_MOD_REG(mod_no, AFT_GSM_CONFIG_REG), &reg);
if (wan_test_bit(AFT_GSM_MOD_PRESENT_BIT, &reg)) {
DEBUG_EVENT("%s: GSM module found at line %d\n", hw->devname, mod_no);
wan_set_bit(AFT_GSM_MOD_BIT(mod_no), &mod_map);
} else {
DEBUG_EVENT("%s: GSM module not found at line %d ...\n", hw->devname, mod_no);
}
}
#else /* SLOW hardware probe */
/* Try to power on the modules to determine which ones are present ...
* aft_gsm_toggle_power returns a mask of modules that failed to be turned on
* but we want the inverse of that (the modules that succeeded), therefore we invert
* the mask and then make sure only take the bits corresponding to the modules (AFT_GSM_ALL_MODULES_MASK) */
ret_map = wp_gsm_toggle_power(hw, AFT_GSM_ALL_MODULES_MASK, WAN_TRUE);
if (ret_map) {
for (mod_no = 1; mod_no <= MAX_GSM_MODULES; mod_no++) {
if (!wan_test_bit(AFT_GSM_MOD_BIT(mod_no), &ret_map)) {
DEBUG_EVENT("%s: GSM module found at line %d\n", hw->devname, mod_no);
} else {
DEBUG_EVENT("%s: GSM module not found at line %d ...\n", hw->devname, mod_no);
}
}
}
mod_map = ((~ret_map) & AFT_GSM_ALL_MODULES_MASK);
/* what if we don't turn them off to speed up things? */
ret_map = wp_gsm_toggle_power(hw, AFT_GSM_ALL_MODULES_MASK, WAN_FALSE);
if (ret_map) {
for (mod_no = 1; mod_no <= MAX_GSM_MODULES; mod_no++) {
if (!wan_test_bit(AFT_GSM_MOD_BIT(mod_no), &ret_map)) {
continue;
}
DEBUG_ERROR("%s: Failed to turn off GSM module %d\n", hw->devname);
}
}
#endif
sdla_hwdev_common_unregister(hwcpu);
hw = NULL;
for (line_no = 0; line_no < MAX_GSM_MODULES; line_no++) {
mod_no = line_no + 1;
/* if the module is not present */
if (!wan_test_bit(AFT_GSM_MOD_BIT(mod_no), &mod_map)) {
continue;
}
if ((hw = sdla_hw_register(hwcpu, line_no)) == NULL){
goto error;
}
/* Populate some basic hw information */
if (sdla_get_hw_info(hw)) {
goto error;
}
/* Create the HW probe string information */
if (sdla_save_hw_probe(hw, 0)){
goto error;
}
mod_hw[line_no] = hw;
/* add some GSM specific information to the hw probe string */
curr_port = &hw->hwport[hw->max_port_no - 1];
/* Initialize the line */
hw->adptr_type = AFT_ADPTR_W400;
/* 1 bchan per module */
hw->chans_map = 0x01;
hw->max_chans_num = 1;
(*lines_number)++;
hwcpu->lines_info[AFT_ADPTR_W400].total_line_no++;
line_map |= (1 << (mod_no));
}
hwcpu->lines_info[AFT_ADPTR_W400].line_map = line_map;
if (hw) {
sdla_memory_unmap(hw);
}
return hw;
error:
DEBUG_ERROR("%s: Failed to register Wireless GSM modules\n", hw->devname);
if (hw) {
sdla_memory_unmap(hw);
}
sdla_hwdev_common_unregister(hwcpu);
return NULL;
}
static sdlahw_t*
sdla_hwdev_a600_register(sdlahw_cpu_t* hwcpu, int *line_num)
@ -2112,12 +2290,6 @@ static int sdla_pcibridge_info(sdlahw_t* hw)
return 0;
}
#define AFT_CHIP_CFG_REG 0x40
#define AFT_CHIPCFG_SFR_IN_BIT 2
#define AFT_CHIPCFG_SFR_EX_BIT 1
#define AFT_CHIPCFG_B600_EC_CHIP_PRESENT_BIT 20
#define AFT_CHIPCFG_B600_EC_RESET_BIT 25
#if !defined(__WINDOWS__)
static
#endif
@ -2135,7 +2307,6 @@ int sdla_get_hw_info(sdlahw_t* hw)
hwcpu = hw->hwcpu;
hwcard = hwcpu->hwcard;
/* Only AFT cards have CPLD that include all hw info */
if (hwcard->type != SDLA_AFT){
goto get_hw_info_done;
}
@ -2330,6 +2501,19 @@ int sdla_get_hw_info(sdlahw_t* hw)
sdla_bus_write_4(hw, SDLA_REG_OFF(hwcard, AFT_CHIP_CFG_REG), reg);
}
/* Restore original value */
sdla_bus_write_4(hw, SDLA_REG_OFF(hwcard, AFT_CHIP_CFG_REG), reg1);
break;
case AFT_ADPTR_W400:
/* Enable memory access */
sdla_bus_read_4(hw, SDLA_REG_OFF(hwcard, AFT_CHIP_CFG_REG), &reg1);
reg = reg1;
wan_clear_bit(AFT_CHIPCFG_SFR_IN_BIT, &reg);
wan_clear_bit(AFT_CHIPCFG_SFR_EX_BIT, &reg);
sdla_bus_write_4(hw, SDLA_REG_OFF(hwcard, AFT_CHIP_CFG_REG), reg);
WP_DELAY(1);
/* Restore original value */
sdla_bus_write_4(hw, SDLA_REG_OFF(hwcard, AFT_CHIP_CFG_REG), reg1);
break;
@ -2979,6 +3163,25 @@ static int sdla_aft_hw_select (sdlahw_card_t* hwcard, int cpu_no, int irq, void*
hwcard->core_rev,
hwcard->u_pci.bus_no, hwcard->u_pci.slot_no, irq);
break;
case AFT_ADPTR_W400:
hwcard->cfg_type = WANOPT_AFT_GSM;
sdla_adapter_cnt.aft_w400_adapters++;
if ((hwcpu = sdla_hwcpu_register(hwcard, cpu_no, irq, dev)) == NULL){
return 0;
}
if ((hw = sdla_hwdev_w400_register(hwcpu, &number_of_cards)) == NULL){
sdla_hwcpu_unregister(hwcpu);
return 0;
}
number_of_cards++;
DEBUG_EVENT("%s: %s %s Wireless GSM card found (Firmware rev.%X), cpu(s) 1, bus #%d, slot #%d, irq #%d\n",
wan_drvname,
hwcard->adptr_name,
AFT_PCITYPE_DECODE(hwcard),
hwcard->core_rev,
hwcard->u_pci.bus_no, hwcard->u_pci.slot_no, irq);
break;
case AFT_ADPTR_B610:
hwcard->cfg_type = WANOPT_AFT_ANALOG;
sdla_adapter_cnt.aft_b610_adapters++;
@ -3335,6 +3538,10 @@ sdla_pci_probe_aft(sdlahw_t *hw, int bus_no, int slot_no, int irq)
hwcard->adptr_subtype = AFT_SUBTYPE_SHARK;
break;
#endif
case AFT_W400_SUBSYS_VENDOR:
hwcard->adptr_type = AFT_ADPTR_W400;
hwcard->adptr_subtype = AFT_SUBTYPE_SHARK;
break;
default:
DEBUG_EVENT(
"%s: Unsupported SubVendor ID:%04X (bus=%d, slot=%d)\n",
@ -3366,6 +3573,7 @@ sdla_pci_probe_aft(sdlahw_t *hw, int bus_no, int slot_no, int irq)
case AFT_B800_SUBSYS_VENDOR:
#endif
case A700_SHARK_SUBSYS_VENDOR:
case AFT_W400_SUBSYS_VENDOR:
sdla_pcibridge_detect(hwcard);
break;
}
@ -3594,7 +3802,7 @@ static int sdla_pci_probe(sdlahw_t *hw)
pci_dev=NULL;
while((pci_dev = pci_get_device(SANGOMA_PCI_VENDOR, PCI_ANY_ID, pci_dev)) != NULL){
tmp_hwcard->u_pci.pci_dev = pci_dev;
tmp_hwcard->u_pci.pci_dev = pci_dev;
number_pci_cards += sdla_pci_probe_aft(
hw,
pci_dev->bus->number,
@ -3838,7 +4046,6 @@ EXPORT_SYMBOL(sdla_hw_probe);
#if defined(__LINUX__)
unsigned int sdla_hw_probe(void)
{
sdlahw_card_t *tmp_hwcard;
sdlahw_cpu_t *tmp_hwcpu;
sdlahw_t *tmp_hw;
@ -4765,7 +4972,7 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname
if (sdla_register_check(conf, devname)){
return NULL;
}
hw = sdla_find_adapter(conf, devname);
if (hw == NULL || hw->used >= hw->max_port_no){
@ -4889,6 +5096,7 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname
case WANOPT_AFT_ISDN:
case WANOPT_AFT_56K:
case WANOPT_AFT_SERIAL:
case WANOPT_AFT_GSM:
hwcard->type = SDLA_AFT;
hw_iface->set_bit = sdla_set_bit;
hw_iface->clear_bit = sdla_clear_bit;
@ -5003,6 +5211,12 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname
hw_iface->fe_write = sdla_a600_write_fe;
hw_iface->reset_fe = sdla_a600_reset_fe;
break;
case AFT_ADPTR_W400:
hw_iface->fe_read = sdla_w400_read_fe;
hw_iface->__fe_read = __sdla_w400_read_fe;
hw_iface->fe_write = sdla_w400_write_fe;
hw_iface->reset_fe = sdla_w400_reset_fe;
break;
#if defined(CONFIG_PRODUCT_WANPIPE_AFT_B601)
case AFT_ADPTR_B601:
if(hw->cfg_type == WANOPT_AFT_ANALOG) {
@ -5043,6 +5257,7 @@ void* sdla_register(sdlahw_iface_t* hw_iface, wandev_conf_t* conf, char* devname
#if defined(CONFIG_PRODUCT_WANPIPE_AFT_B800)
case AFT_ADPTR_B800:
#endif
case AFT_ADPTR_W400:
DEBUG_EVENT("%s: Found: %s card, CPU %c, PciBus=%d, PciSlot=%d, Port=%d\n",
devname,
SDLA_DECODE_CARDTYPE(hwcard->cfg_type),
@ -5405,6 +5620,15 @@ static int sdla_register_check (wandev_conf_t* conf, char* devname)
}
break;
#endif
case WANOPT_AFT_GSM:
if (conf->auto_hw_detect && sdla_adapter_cnt.aft_w400_adapters > 1){
DEBUG_EVENT( "%s: HW Auto PCI failed: Multiple AFT-W400 cards found! \n"
"%s: Disable the Autodetect feature and supply\n"
"%s: the PCI Slot and Bus numbers for each card.\n",
devname,devname,devname);
return -EINVAL;
}
break;
default:
DEBUG_EVENT("%s: Unsupported Sangoma Card (0x%X) requested by user!\n",
@ -6236,6 +6460,7 @@ static int sdla_down (void* phw)
#if defined(CONFIG_PRODUCT_WANPIPE_AFT_B800)
case AFT_ADPTR_B800:
#endif
case AFT_ADPTR_W400:
if (hwcpu->used > 1){
break;
}
@ -8038,6 +8263,7 @@ static int sdla_memory_map(sdlahw_t* hw)
case AFT_ADPTR_ISDN:
case AFT_ADPTR_B500:
case AFT_ADPTR_A600:
case AFT_ADPTR_W400:
case AFT_ADPTR_B610:
#if defined(CONFIG_PRODUCT_WANPIPE_AFT_B601)
case AFT_ADPTR_B601:
@ -8390,8 +8616,7 @@ sdlahw_t* sdla_find_adapter(wandev_conf_t* conf, char* devname)
}
DBG_SDLADRV_HW_IFACE("%s(): devname: %s, conf->card_type: 0x%X (%s), conf->fe_cfg.line_no: %d\n",
__FUNCTION__, devname, conf->card_type, CARD_WANOPT_DECODE(conf->card_type),
conf->fe_cfg.line_no);
__FUNCTION__, devname, conf->card_type, CARD_WANOPT_DECODE(conf->card_type), conf->fe_cfg.line_no);
WAN_LIST_FOREACH(hw, &sdlahw_head, next){
@ -8570,6 +8795,16 @@ sdlahw_t* sdla_find_adapter(wandev_conf_t* conf, char* devname)
}
break;
#endif
case WANOPT_AFT_GSM:
if ((hwcpu->hwcard->u_pci.slot_no == conf->PCI_slot_no) &&
(hwcpu->hwcard->u_pci.bus_no == conf->pci_bus_no) &&
(hw->cfg_type == conf->card_type) &&
(hw->line_no == conf->fe_cfg.line_no-1)){
DEBUG_EVENT("%s: Found adapter for GSM card configuration (slot=%d, bus=%d, line=%d)\n",
devname, conf->PCI_slot_no, conf->pci_bus_no);
goto adapter_found;
}
break;
default:
DEBUG_EVENT("%s: Unknown card type (%x) requested by user!\n",
@ -8607,6 +8842,16 @@ adapter_found:
break;
#endif
case AFT_ADPTR_W400:
if (conf->fe_cfg.line_no < 1 || conf->fe_cfg.line_no > MAX_GSM_MODULES){
DEBUG_ERROR("%s: Error, Invalid GSM module selected %d (Min=1 Max=%d)\n",
devname, conf->fe_cfg.line_no, MAX_GSM_MODULES);
return NULL;
}
conf->fe_cfg.line_no--;
conf->comm_port = 0;
break;
#if defined(CONFIG_PRODUCT_WANPIPE_AFT_BRI)
case AFT_ADPTR_ISDN:
case AFT_ADPTR_B500:
@ -8810,14 +9055,14 @@ adapter_found:
#if defined(WAN_ISA_SUPPORT)
case WANOPT_S50X:
DEBUG_EVENT(
"%s: Error, Sangoma ISA card not found on ioport #%x, %s\n",
devname, conf->ioport, COMPORT_DECODE(conf->comm_port));
"%s:%s:%d Error, Sangoma ISA card not found on ioport #%x, %s\n",
devname, __FILE__, __LINE__, conf->ioport, COMPORT_DECODE(conf->comm_port));
break;
#endif
case WANOPT_S51X:
DEBUG_EVENT(
"%s: Error, %s card not found on bus #%d, slot #%d, cpu %c, %s\n",
devname,
"%s:%s:%d: Error, %s card not found on bus #%d, slot #%d, cpu %c, %s\n",
devname, __FILE__, __LINE__,
SDLA_DECODE_CARDTYPE(conf->card_type),
conf->pci_bus_no,
conf->PCI_slot_no,
@ -8826,8 +9071,8 @@ adapter_found:
break;
case WANOPT_ADSL:
DEBUG_EVENT(
"%s: Error, %s card not found on bus #%d, slot #%d\n",
devname,
"%s:%s:%d: Error, %s card not found on bus #%d, slot #%d\n",
devname, __FILE__, __LINE__,
SDLA_DECODE_CARDTYPE(conf->card_type),
conf->pci_bus_no,
conf->PCI_slot_no);
@ -8843,8 +9088,8 @@ adapter_found:
case WANOPT_AFT_56K:
case WANOPT_AFT_SERIAL:
DEBUG_EVENT(
"%s: Error, %s card not found on bus #%d, slot #%d, cpu %c, line %d\n",
devname,
"%s:%s:%d: Error, %s card not found on bus #%d, slot #%d, cpu %c, line %d\n",
devname, __FILE__, __LINE__,
SDLA_DECODE_CARDTYPE(conf->card_type),
conf->pci_bus_no,
conf->PCI_slot_no,
@ -8854,8 +9099,8 @@ adapter_found:
#if defined(CONFIG_PRODUCT_WANPIPE_USB)
case WANOPT_USB_ANALOG:
DEBUG_EVENT(
"%s: Error, %s card not found on busid #%s\n",
devname,
"%s:%s:%d: Error, %s card not found on busid #%s\n",
devname, __FILE__, __LINE__,
SDLA_DECODE_CARDTYPE(conf->card_type),
conf->usb_busid);
#if 0
@ -8870,8 +9115,8 @@ adapter_found:
default:
DEBUG_EVENT(
"%s: Error, %s card not found!\n",
devname,
"%s:%s:%d: Error, %s card not found!\n",
devname, __FILE__, __LINE__,
SDLA_DECODE_CARDTYPE(conf->card_type));
break;
}

View File

@ -2539,5 +2539,31 @@ u_int8_t sdla_b601_te1_read_fe (void *phw, ...)
#endif
void sdla_w400_reset_fe (void *fe)
{
sdla_t *card = NULL;
card = (sdla_t*)((sdla_fe_t*)fe)->card;
DEBUG_ERROR ("%s I should not be called! (%s:%d)\n", ((sdla_fe_t*)fe)->name, __FUNCTION__, __LINE__);
}
int sdla_w400_write_fe (void *phw, ...)
{
sdlahw_t *hw = (sdlahw_t*)phw;
DEBUG_ERROR ("%s I should not be called! (%s:%d)\n", hw->devname, __FUNCTION__, __LINE__);
return 0xFF;
}
u_int8_t __sdla_w400_read_fe (void *phw, ...)
{
sdlahw_t *hw = (sdlahw_t*)phw;
DEBUG_ERROR ("%s I should not be called! (%s:%d)\n", hw->devname, __FUNCTION__, __LINE__);
return 0xFF;
}
u_int8_t sdla_w400_read_fe (void *phw, ...)
{
sdlahw_t *hw = (sdlahw_t*)phw;
DEBUG_ERROR ("%s I should not be called! (%s:%d)\n", hw->devname, __FUNCTION__, __LINE__);
return 0xFF;
}

View File

@ -726,6 +726,7 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf)
case WANOPT_AFT_ANALOG:
case WANOPT_AFT_56K:
case WANOPT_AFT_SERIAL:
case WANOPT_AFT_GSM:
err=0;
if ((err=check_aft_conflicts(card,conf,&irq)) != 0){
@ -1035,6 +1036,10 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf)
err = wp_usb_init(card,conf);
break;
#endif
case WANCONFIG_AFT_GSM:
DEBUG_EVENT("%s: Starting GSM Hardware Init.\n", card->devname);
err = wp_aft_w400_init(card, conf);
break;
default:
DEBUG_EVENT("%s: Error, Protocol is not supported %u!\n",
wandev->name, conf->config_id);

View File

@ -105,3 +105,28 @@ int wanpipe_codec_free(void)
DEBUG_EVENT("WANPIPE: TDM Codecs unloaded.\n");
return 0;
}
int wanpipe_codec_convert_to_linear(u8 pcm_value,u8 codecType)
{
int ret = 0;
switch(codecType)
{
case WP_ALAW:
{
ret = wanpipe_codec_get_alaw_to_linear(pcm_value);
break;
}
case WP_MULAW:
{
ret = wanpipe_codec_get_ulaw_to_linear(pcm_value);
break;
}
default:
{
DEBUG_ERROR("%s(): Invalid CodecType[%d]\n",__FUNCTION__,codecType);
break;
}
}
return ret;
}

View File

@ -400,3 +400,36 @@ int wanpipe_codec_law_init(void)
return 0;
}
/*! \brief Decode an u-law sample to a linear value.
\param ulaw The u-law sample to decode.
\return The linear value.
*/
int wanpipe_codec_get_ulaw_to_linear(u8 ulaw)
{
int t;
/* Complement to obtain normal u-law value. */
ulaw = ~ulaw;
/*
* Extract and bias the quantization bits. Then
* shift up by the segment number and subtract out the bias.
*/
t = (((ulaw & 0x0F) << 3) + G711_ULAW_BIAS) << (((int) ulaw & 0x70) >> 4);
return (int16_t) ((ulaw & 0x80) ? (G711_ULAW_BIAS - t) : (t - G711_ULAW_BIAS));
}
int wanpipe_codec_get_alaw_to_linear(u8 alaw)
{
int i;
int seg;
alaw ^= G711_ALAW_AMI_MASK;
i = ((alaw & 0x0F) << 4);
seg = (((int) alaw & 0x70) >> 4);
if (seg)
i = (i + 0x108) << (seg - 1);
else
i += 8;
return (int) ((alaw & 0x80) ? i : -i);
}

View File

@ -79,6 +79,8 @@
#undef DEBUG_API_WRITE
#undef DEBUG_API_POLL
#define WP_TDM_DEF_FAKE_POLARITY_THRESHOLD 16000
#ifdef __WINDOWS__
# define wptdm_os_lock_irq(card,flags) wan_spin_lock_irq(card,flags)
# define wptdm_os_unlock_irq(card,flags) wan_spin_unlock_irq(card,flags)
@ -116,6 +118,8 @@ static void wp_tdmapi_ringtrip(void* card_id, wan_event_t*);
static void wp_tdmapi_ringdetect (void* card_id, wan_event_t *event);
static void wp_tdmapi_linkstatus(void* card_id, wan_event_t*);
static void wp_tdmapi_polarityreverse(void* card_id, wan_event_t*);
static __inline int wp_tdmapi_check_fakepolarity(u8 *buf, int len, wanpipe_tdm_api_dev_t* tdm_api);
static void wp_tdmapi_report_fakepolarityreverse(void* card_id,u_int8_t channel);
static int store_tdm_api_pointer_in_card(sdla_t *card, wanpipe_tdm_api_dev_t *tdm_api);
@ -3295,12 +3299,18 @@ static int wanpipe_tdm_api_channelized_rx (wanpipe_tdm_api_dev_t *tdm_api, u8 *r
int err=-EINVAL;
int skblen;
int hdrsize = sizeof(wp_api_hdr_t);
sdla_t *card = (sdla_t*)tdm_api->card;
if (wan_test_bit(0,&tdm_api->cfg.rx_disable)) {
err=0;
goto wanpipe_tdm_api_rx_error;
}
if (card && (WANCONFIG_AFT_ANALOG == card->wandev.config_id)) {
/*Only for Analog card - check and report fake polarity event(If applicable)*/
wp_tdmapi_check_fakepolarity(rx_data,len,tdm_api);
}
if (wan_skb_queue_len(&tdm_api->wp_rx_list) >= (int)tdm_api->cfg.rx_queue_sz) {
WP_AFT_CHAN_ERROR_STATS(tdm_api->cfg.stats,rx_dropped);
wp_wakeup_rx_tdmapi(tdm_api);
@ -3383,6 +3393,87 @@ wanpipe_tdm_api_rx_error:
return err;
}
static __inline int wp_tdmapi_check_fakepolarity(u8 *buf, int len, wanpipe_tdm_api_dev_t* tdm_api)
{
sdla_fe_t *fe = NULL;
wp_remora_fxo_t *fxo = NULL;
int channo = 0;
sdla_t *card = NULL;
int upper_thres_val = 0;
int lower_thres_val = 0;
int i = 0;
int linear_sample = 0;
int fake_polarity_thres = 0;
if(!buf || !tdm_api || !len || !tdm_api->card) {
return 0 ;
}
card = (sdla_t*)tdm_api->card;
fe = &card->fe;
channo = tdm_api->tdm_chan;
fxo = &fe->rm_param.mod[channo].u.fxo;
if (WANOPT_NO == card->fe.fe_cfg.cfg.remora.fake_polarity) {
/*RM_FAKE_POLARITY disabled */
return 0;
}
/* only look for sound on the line if its an fxo card and state is onhook*/
if (MOD_TYPE_FXO != fe->rm_param.mod[channo].type) {
return 0;
}
if (fxo->offhook) {
fxo->cidtimer = fe->rm_param.intcount;
return 0;
}
/* If no possible CID has been reported yet, scan the signal looking for samples bigger than the user-specified threshold */
if (!fxo->readcid && !fxo->wasringing && fe->rm_param.intcount > fxo->cidtimer + 400) {
fake_polarity_thres = card->fe.fe_cfg.cfg.remora.fake_polarity_thres;
if(0 == fake_polarity_thres) {
/*threshold value not configured...but RM_FAKE_POLARITY enable ,
* hence considering default threshold value*/
fake_polarity_thres = WP_TDM_DEF_FAKE_POLARITY_THRESHOLD;
}
upper_thres_val = fake_polarity_thres;
lower_thres_val = -1 * fake_polarity_thres;
for (i=0;i<len;i++) {
linear_sample = wanpipe_codec_convert_to_linear(buf[i],tdm_api->cfg.hw_tdm_coding);
if (linear_sample > upper_thres_val || linear_sample < lower_thres_val) {
DEBUG_EVENT("%s: Possible CID signal detected, faking polarity reverse event on module %d\n", card->devname, channo);
wp_tdmapi_report_fakepolarityreverse(card,channo);
fxo->readcid = 1;
fxo->cidtimer = fe->rm_param.intcount;
return 1;
}
}
} else if (fxo->readcid && fe->rm_param.intcount > fxo->cidtimer + 2000) {
fxo->cidtimer = fe->rm_param.intcount;
fxo->readcid = 0;
}
return 0;
}
static void wp_tdmapi_report_fakepolarityreverse(void* card_id,u_int8_t channel)
{
wan_event_t event;
memset(&event,0,sizeof(event));
event.channel = channel;
event.type = WAN_EVENT_RM_POLARITY_REVERSE;
event.polarity_reverse = WAN_EVENT_POLARITY_REV_POSITIVE_NEGATIVE;
wp_tdmapi_polarityreverse(card_id, &event);
return;
}
#undef AFT_TDM_ROTATE_DEBUG
#ifdef AFT_TDM_ROTATE_DEBUG
#warning "AFT_TDM_ROTATE_DEBUG Enabled"

View File

@ -708,6 +708,7 @@ int wan_device_setup (wan_device_t *wandev, wandev_conf_t *u_conf, int user)
if (conf->card_type == WANOPT_ADSL ||
conf->card_type == WANOPT_AFT ||
conf->card_type == WANOPT_AFT_GSM ||
conf->card_type == WANOPT_AFT104 ||
conf->card_type == WANOPT_AFT300 ||
conf->config_id == WANCONFIG_DEBUG){

View File

@ -91,6 +91,7 @@
(prot == WANCONFIG_AFT) ? ((cap)?"AFT TE1":"aft te1") : \
(prot == WANCONFIG_AFT_SERIAL) ? ((cap)?"A-SERIAL":"aft serial") : \
(prot == WANCONFIG_AFT_ANALOG) ? ((cap)?"A-ANALOG":"aft analog") : \
(prot == WANCONFIG_AFT_GSM) ? ((cap)?"AFT GSM":"aft gsm") : \
(prot == WANCONFIG_AFT_ISDN_BRI) ? ((cap)?"AFT ISDN":"aft isdn") : \
(prot == WANCONFIG_AFT_56K) ? ((cap)?"AFT 56K":"aft 56k") : \
(prot == WANCONFIG_AFT_TE1) ? ((cap)?"AFT TE1":"aft te1") : \
@ -770,6 +771,7 @@ static int interfaces_get_info(char* buf, char** start, off_t offs, int len, int
PROC_ADD_RET(m);
}
#define SANGOMA_COUNT_MESSAGE "\nSangoma Card Count: "
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(LINUX_2_4)
STATIC int probe_get_info(char* buf, char** start, off_t offs, int len)
#else
@ -820,8 +822,7 @@ static int probe_get_info(char* buf, char** start, off_t offs, int len, int dumm
}
hw_cnt=(sdla_hw_type_cnt_t*)sdla_get_hw_adptr_cnt();
PROC_ADD_LINE(m, "\nCard Cnt: ");
PROC_ADD_LINE(m, SANGOMA_COUNT_MESSAGE);
if (hw_cnt->s508_adapters){
PROC_ADD_LINE(m, "S508=%d ", hw_cnt->s508_adapters);
}
@ -876,6 +877,9 @@ static int probe_get_info(char* buf, char** start, off_t offs, int len, int dumm
if (hw_cnt->aft_b800_adapters){
PROC_ADD_LINE(m, "B800=%d ", hw_cnt->aft_b800_adapters);
}
if (hw_cnt->aft_w400_adapters){
PROC_ADD_LINE(m, "W400=%d ", hw_cnt->aft_w400_adapters);
}
PROC_ADD_LINE(m, "\n");
PROC_ADD_RET(m);
@ -993,7 +997,7 @@ static int probe_get_info_verbose(char* buf, char** start, off_t offs, int len,
hw_cnt=(sdla_hw_type_cnt_t*)sdla_get_hw_adptr_cnt();
PROC_ADD_LINE(m, "\nCard Cnt: ");
PROC_ADD_LINE(m, SANGOMA_COUNT_MESSAGE);
if (hw_cnt->s508_adapters){
PROC_ADD_LINE(m, "S508=%d ", hw_cnt->s508_adapters);
}
@ -1042,6 +1046,9 @@ static int probe_get_info_verbose(char* buf, char** start, off_t offs, int len,
if (hw_cnt->aft_b800_adapters){
PROC_ADD_LINE(m, "B800=%d ", hw_cnt->aft_b800_adapters);
}
if (hw_cnt->aft_w400_adapters){
PROC_ADD_LINE(m, "W400=%d ", hw_cnt->aft_w400_adapters);
}
PROC_ADD_LINE(m, "\n");
PROC_ADD_RET(m);

View File

@ -1,6 +1,6 @@
%define WANPIPE_VER wanpipe-modules
%define name %{WANPIPE_VER}
%define version 3.5.25
%define version 3.5.26
%define release 0
%define serial 1
%define MODULES_DIR /lib/modules
@ -59,13 +59,48 @@ fi
%changelog
* Tue Apr 24 2012 Nenad Corbic <ncorbic@sangoma.com> - 3.5.26
==================================================================
- Wanpipe W400 GSM support: Asterisk/Dahdi & FreeSWITCH/FreeTDM
- Wanpipe B610 FXS support
- Fixed Dahdi 2.5 and higher hwec autodetection
For dahdi 2.5 and higher the HWEC option was needed in
dahdi/system.conf to enable onboard hwec.
This fix allows default mg2 software echo to be specified
in dahdi/system.conf, and dahdi will autodetect the sangoma onboard hwec.
- Fixed sangoma hwec boards to use dahdi software ec if hwec is turned off.
Wanpipe driver did not allow sangoma hwec enabled boards to use dahdi
software ec even if hwec was turned off in wanpipe1.conf
This has now been fixed.
If TDMV_HWEC=NO is set in wanpipe1.conf dahdi will now use software ec.
- Fixed BRI dchan reliability
- Fixed BRI for 64bit
The fix for audio issue in 3.5.25 caused the issue on 64bit.
- Dahdi build bug fixes for Trixbox
- Zaptel build bug fixes from 3.5.25
- Build fixes for 3.1.X kernel.
- Fake polarity feature used for Euro Caller ID
- E1 NCRC CAS Framer Configuration for Latin America
Previous NCRC Framer config did not work in all cases.
Affects protocols such as MFC-R2 or CAS
- Analog boards with network sync option set to yes:
Default to fax mode buffering.
Use "when full" dahdi buffer policy.
Improves faxing from PRI to Analog with sync cable.
- Fixed wancfg_dahdi to:
start asterisk using safe_asterisk
to properly detect dahdi version
* Tue Feb 21 2012 Nenad Corbic <ncorbic@sangoma.com> - 3.5.25
==================================================================
- Dahdi 2.6 support
- Linux 3.2.6 support
- Support for B610 Single FXS card
- Support for B500 4 port BRI card
- Support for B610 Single FXS board
- Support for B500 4 port BRI board
- Reduced memory foot print of the driver
by removing some unused statistics structures
- New HWEC firmare v1.7.4 fixes delayed fax issus
@ -102,7 +137,7 @@ fi
* Wed Aug 24 2011 Nenad Corbic <ncorbic@sangoma.com> - 3.5.22
==================================================================
- Bug introducted in .21 release for analog card.
- Bug introducted in .21 release for analog board.
Changed the way wanpipe enumerates analog channels
breaks backward compatibility. Reverted to original.
@ -213,7 +248,7 @@ fi
- Added SW HDLC into the core. B
- B601 is now supported on FreeTDM/FreeSWITCH and TMDAPI
- Added wan_fxotune utility to utils directory
Used to tune fxo cards under TDM API or FreeSWITCH mode.
Used to tune fxo boards under TDM API or FreeSWITCH mode.
@ -232,7 +267,7 @@ fi
dma overruns.
- Bug fix in tdmapi where excessive memory was allocated on pre-allocation buffers.
- Bug fix tdmapi defaults to 20ms chunk size instead of 10ms
- Bug fix broken support for A101/2 legacy EOL cards.
- Bug fix broken support for A101/2 legacy EOL boards.
- New XEN Support
TDM Voice will now work properly on xen virtualized machines
- Fix for 64bit 8gig issues
@ -265,11 +300,11 @@ fi
===================================================================
- Fixed Dahdi 2.3 Support
- Fixed FreeSwitch Openzap HardHDLC option for AFT cards
- Fixed wanpipemon support for non aft cards.
- Fixed FreeSwitch Openzap HardHDLC option for AFT boards
- Fixed wanpipemon support for non aft boards.
- Merged USB FXO code from 3.6 release
- USB FXO bug fix for 2.6.32 kernels
- Support for B800 Analog card
- Support for B800 Analog board
- Fixed alarm reporting in DAHDI/ZAPTEL
- Added Extra EC DSP Configuration Options
@ -362,7 +397,7 @@ fi
- Fixed Tx Tristate
- Updated yellow alarm handling for Dallas maxim cards
- Updated yellow alarm handling for Dallas maxim boards
(A101/2/4/8)
- Autodetect USB support so that driver will compile
@ -376,7 +411,7 @@ fi
- Update to T1 Yellow Alarm handling.
In some cases Yellow alarm did not turn off poperly causing
line to stay down an card startup.
line to stay down an board startup.
- Update configuration utility
wancfg_fs updated for sangoma_prid configuration. Added wancfg_openzap
for OpenZap Configuration
@ -392,10 +427,10 @@ fi
- Updated for 2.6.30 kernel
- New firmawre feature for A101/2/5/8: Free Run Timer Interrupt
The AFT T1/E1 cards will now provide perfect timing to zatpel/dahdi
The AFT T1/E1 boards will now provide perfect timing to zatpel/dahdi
even when the ports are not connected. The free run interrupt
will be enabled when all zaptel/dahdi ports are down, or on
inital card start. To test this feature just start a wanpipe
inital board start. To test this feature just start a wanpipe
port with zaptel/dahdi and run zttest.
A108 firmare V38
A104/2/1/ firmware V36
@ -433,7 +468,7 @@ fi
- TDM API
Updated the Global TDM Device
This device can be used to read events an all cards configured in
This device can be used to read events an all boards configured in
TDM API mode.
- Libsangoma verion 3.1.0
@ -504,7 +539,7 @@ fi
* Fri May 08 2009 Nenad Corbic <ncorbic@sangoma.com> - 3.5.2
===================================================================
- B700 PCIe cards were being displayed as PCI cards in hwprobe
- B700 PCIe boards were being displayed as PCI boards in hwprobe
- Bug fix in wancfg_zaptel
* Thu May 07 2009 Nenad Corbic <ncorbic@sangoma.com> - 3.5.1
@ -528,7 +563,7 @@ fi
- Unified driver for Linux & Windows
- Updated BRI Stack and Support
- New BRI A500 & B700 firmware that fixes PCI parity errors.
On some systems A500 & B700 cards can generate parity errors.
On some systems A500 & B700 boards can generate parity errors.
- FreeSwitch Tested
- Update for 2.6.26 kernel

View File

@ -1,6 +1,6 @@
%define WANPIPE_VER wanpipe-util
%define name %{WANPIPE_VER}
%define version 3.5.25
%define version 3.5.26
%define release 0
%define serial 1
%define UTILS_DIR /usr/sbin
@ -229,13 +229,48 @@ chmod 755 /usr/local/sbin/setup-sangoma
%changelog
* Tue Apr 24 2012 Nenad Corbic <ncorbic@sangoma.com> - 3.5.26
==================================================================
- Wanpipe W400 GSM support: Asterisk/Dahdi & FreeSWITCH/FreeTDM
- Wanpipe B610 FXS support
- Fixed Dahdi 2.5 and higher hwec autodetection
For dahdi 2.5 and higher the HWEC option was needed in
dahdi/system.conf to enable onboard hwec.
This fix allows default mg2 software echo to be specified
in dahdi/system.conf, and dahdi will autodetect the sangoma onboard hwec.
- Fixed sangoma hwec boards to use dahdi software ec if hwec is turned off.
Wanpipe driver did not allow sangoma hwec enabled boards to use dahdi
software ec even if hwec was turned off in wanpipe1.conf
This has now been fixed.
If TDMV_HWEC=NO is set in wanpipe1.conf dahdi will now use software ec.
- Fixed BRI dchan reliability
- Fixed BRI for 64bit
The fix for audio issue in 3.5.25 caused the issue on 64bit.
- Dahdi build bug fixes for Trixbox
- Zaptel build bug fixes from 3.5.25
- Build fixes for 3.1.X kernel.
- Fake polarity feature used for Euro Caller ID
- E1 NCRC CAS Framer Configuration for Latin America
Previous NCRC Framer config did not work in all cases.
Affects protocols such as MFC-R2 or CAS
- Analog boards with network sync option set to yes:
Default to fax mode buffering.
Use "when full" dahdi buffer policy.
Improves faxing from PRI to Analog with sync cable.
- Fixed wancfg_dahdi to:
start asterisk using safe_asterisk
to properly detect dahdi version
* Tue Feb 21 2012 Nenad Corbic <ncorbic@sangoma.com> - 3.5.25
==================================================================
- Dahdi 2.6 support
- Linux 3.2.6 support
- Support for B610 Single FXS card
- Support for B500 4 port BRI card
- Support for B610 Single FXS board
- Support for B500 4 port BRI board
- Reduced memory foot print of the driver
by removing some unused statistics structures
- New HWEC firmare v1.7.4 fixes delayed fax issus
@ -272,7 +307,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
* Wed Aug 24 2011 Nenad Corbic <ncorbic@sangoma.com> - 3.5.22
==================================================================
- Bug introducted in .21 release for analog card.
- Bug introducted in .21 release for analog board.
Changed the way wanpipe enumerates analog channels
breaks backward compatibility. Reverted to original.
@ -383,7 +418,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
- Added SW HDLC into the core. B
- B601 is now supported on FreeTDM/FreeSWITCH and TMDAPI
- Added wan_fxotune utility to utils directory
Used to tune fxo cards under TDM API or FreeSWITCH mode.
Used to tune fxo boards under TDM API or FreeSWITCH mode.
@ -402,7 +437,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
dma overruns.
- Bug fix in tdmapi where excessive memory was allocated on pre-allocation buffers.
- Bug fix tdmapi defaults to 20ms chunk size instead of 10ms
- Bug fix broken support for A101/2 legacy EOL cards.
- Bug fix broken support for A101/2 legacy EOL boards.
- New XEN Support
TDM Voice will now work properly on xen virtualized machines
- Fix for 64bit 8gig issues
@ -435,11 +470,11 @@ chmod 755 /usr/local/sbin/setup-sangoma
===================================================================
- Fixed Dahdi 2.3 Support
- Fixed FreeSwitch Openzap HardHDLC option for AFT cards
- Fixed wanpipemon support for non aft cards.
- Fixed FreeSwitch Openzap HardHDLC option for AFT boards
- Fixed wanpipemon support for non aft boards.
- Merged USB FXO code from 3.6 release
- USB FXO bug fix for 2.6.32 kernels
- Support for B800 Analog card
- Support for B800 Analog board
- Fixed alarm reporting in DAHDI/ZAPTEL
- Added Extra EC DSP Configuration Options
@ -532,7 +567,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
- Fixed Tx Tristate
- Updated yellow alarm handling for Dallas maxim cards
- Updated yellow alarm handling for Dallas maxim boards
(A101/2/4/8)
- Autodetect USB support so that driver will compile
@ -546,7 +581,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
- Update to T1 Yellow Alarm handling.
In some cases Yellow alarm did not turn off poperly causing
line to stay down an card startup.
line to stay down an board startup.
- Update configuration utility
wancfg_fs updated for sangoma_prid configuration. Added wancfg_openzap
for OpenZap Configuration
@ -562,10 +597,10 @@ chmod 755 /usr/local/sbin/setup-sangoma
- Updated for 2.6.30 kernel
- New firmawre feature for A101/2/5/8: Free Run Timer Interrupt
The AFT T1/E1 cards will now provide perfect timing to zatpel/dahdi
The AFT T1/E1 boards will now provide perfect timing to zatpel/dahdi
even when the ports are not connected. The free run interrupt
will be enabled when all zaptel/dahdi ports are down, or on
inital card start. To test this feature just start a wanpipe
inital board start. To test this feature just start a wanpipe
port with zaptel/dahdi and run zttest.
A108 firmare V38
A104/2/1/ firmware V36
@ -603,7 +638,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
- TDM API
Updated the Global TDM Device
This device can be used to read events an all cards configured in
This device can be used to read events an all boards configured in
TDM API mode.
- Libsangoma verion 3.1.0
@ -674,7 +709,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
* Fri May 08 2009 Nenad Corbic <ncorbic@sangoma.com> - 3.5.2
===================================================================
- B700 PCIe cards were being displayed as PCI cards in hwprobe
- B700 PCIe boards were being displayed as PCI boards in hwprobe
- Bug fix in wancfg_zaptel
* Thu May 07 2009 Nenad Corbic <ncorbic@sangoma.com> - 3.5.1
@ -698,7 +733,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
- Unified driver for Linux & Windows
- Updated BRI Stack and Support
- New BRI A500 & B700 firmware that fixes PCI parity errors.
On some systems A500 & B700 cards can generate parity errors.
On some systems A500 & B700 boards can generate parity errors.
- FreeSwitch Tested
- Update for 2.6.26 kernel

View File

@ -1,7 +1,7 @@
%define KERNEL_VERSION %{?kern_ver}
%define WANPIPE_VER wanpipe
%define name %{WANPIPE_VER}
%define version 3.5.25
%define version 3.5.26
%define release 0
%define serial 1
%define UTILS_DIR /usr/sbin
@ -246,13 +246,48 @@ chmod 755 /usr/local/sbin/setup-sangoma
%changelog
* Tue Apr 24 2012 Nenad Corbic <ncorbic@sangoma.com> - 3.5.26
==================================================================
- Wanpipe W400 GSM support: Asterisk/Dahdi & FreeSWITCH/FreeTDM
- Wanpipe B610 FXS support
- Fixed Dahdi 2.5 and higher hwec autodetection
For dahdi 2.5 and higher the HWEC option was needed in
dahdi/system.conf to enable onboard hwec.
This fix allows default mg2 software echo to be specified
in dahdi/system.conf, and dahdi will autodetect the sangoma onboard hwec.
- Fixed sangoma hwec boards to use dahdi software ec if hwec is turned off.
Wanpipe driver did not allow sangoma hwec enabled boards to use dahdi
software ec even if hwec was turned off in wanpipe1.conf
This has now been fixed.
If TDMV_HWEC=NO is set in wanpipe1.conf dahdi will now use software ec.
- Fixed BRI dchan reliability
- Fixed BRI for 64bit
The fix for audio issue in 3.5.25 caused the issue on 64bit.
- Dahdi build bug fixes for Trixbox
- Zaptel build bug fixes from 3.5.25
- Build fixes for 3.1.X kernel.
- Fake polarity feature used for Euro Caller ID
- E1 NCRC CAS Framer Configuration for Latin America
Previous NCRC Framer config did not work in all cases.
Affects protocols such as MFC-R2 or CAS
- Analog boards with network sync option set to yes:
Default to fax mode buffering.
Use "when full" dahdi buffer policy.
Improves faxing from PRI to Analog with sync cable.
- Fixed wancfg_dahdi to:
start asterisk using safe_asterisk
to properly detect dahdi version
* Tue Feb 21 2012 Nenad Corbic <ncorbic@sangoma.com> - 3.5.25
==================================================================
- Dahdi 2.6 support
- Linux 3.2.6 support
- Support for B610 Single FXS card
- Support for B500 4 port BRI card
- Support for B610 Single FXS board
- Support for B500 4 port BRI board
- Reduced memory foot print of the driver
by removing some unused statistics structures
- New HWEC firmare v1.7.4 fixes delayed fax issus
@ -289,7 +324,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
* Wed Aug 24 2011 Nenad Corbic <ncorbic@sangoma.com> - 3.5.22
==================================================================
- Bug introducted in .21 release for analog card.
- Bug introducted in .21 release for analog board.
Changed the way wanpipe enumerates analog channels
breaks backward compatibility. Reverted to original.
@ -400,7 +435,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
- Added SW HDLC into the core. B
- B601 is now supported on FreeTDM/FreeSWITCH and TMDAPI
- Added wan_fxotune utility to utils directory
Used to tune fxo cards under TDM API or FreeSWITCH mode.
Used to tune fxo boards under TDM API or FreeSWITCH mode.
@ -419,7 +454,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
dma overruns.
- Bug fix in tdmapi where excessive memory was allocated on pre-allocation buffers.
- Bug fix tdmapi defaults to 20ms chunk size instead of 10ms
- Bug fix broken support for A101/2 legacy EOL cards.
- Bug fix broken support for A101/2 legacy EOL boards.
- New XEN Support
TDM Voice will now work properly on xen virtualized machines
- Fix for 64bit 8gig issues
@ -452,11 +487,11 @@ chmod 755 /usr/local/sbin/setup-sangoma
===================================================================
- Fixed Dahdi 2.3 Support
- Fixed FreeSwitch Openzap HardHDLC option for AFT cards
- Fixed wanpipemon support for non aft cards.
- Fixed FreeSwitch Openzap HardHDLC option for AFT boards
- Fixed wanpipemon support for non aft boards.
- Merged USB FXO code from 3.6 release
- USB FXO bug fix for 2.6.32 kernels
- Support for B800 Analog card
- Support for B800 Analog board
- Fixed alarm reporting in DAHDI/ZAPTEL
- Added Extra EC DSP Configuration Options
@ -549,7 +584,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
- Fixed Tx Tristate
- Updated yellow alarm handling for Dallas maxim cards
- Updated yellow alarm handling for Dallas maxim boards
(A101/2/4/8)
- Autodetect USB support so that driver will compile
@ -563,7 +598,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
- Update to T1 Yellow Alarm handling.
In some cases Yellow alarm did not turn off poperly causing
line to stay down an card startup.
line to stay down an board startup.
- Update configuration utility
wancfg_fs updated for sangoma_prid configuration. Added wancfg_openzap
for OpenZap Configuration
@ -579,10 +614,10 @@ chmod 755 /usr/local/sbin/setup-sangoma
- Updated for 2.6.30 kernel
- New firmawre feature for A101/2/5/8: Free Run Timer Interrupt
The AFT T1/E1 cards will now provide perfect timing to zatpel/dahdi
The AFT T1/E1 boards will now provide perfect timing to zatpel/dahdi
even when the ports are not connected. The free run interrupt
will be enabled when all zaptel/dahdi ports are down, or on
inital card start. To test this feature just start a wanpipe
inital board start. To test this feature just start a wanpipe
port with zaptel/dahdi and run zttest.
A108 firmare V38
A104/2/1/ firmware V36
@ -620,7 +655,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
- TDM API
Updated the Global TDM Device
This device can be used to read events an all cards configured in
This device can be used to read events an all boards configured in
TDM API mode.
- Libsangoma verion 3.1.0
@ -691,7 +726,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
* Fri May 08 2009 Nenad Corbic <ncorbic@sangoma.com> - 3.5.2
===================================================================
- B700 PCIe cards were being displayed as PCI cards in hwprobe
- B700 PCIe boards were being displayed as PCI boards in hwprobe
- Bug fix in wancfg_zaptel
* Thu May 07 2009 Nenad Corbic <ncorbic@sangoma.com> - 3.5.1
@ -715,7 +750,7 @@ chmod 755 /usr/local/sbin/setup-sangoma
- Unified driver for Linux & Windows
- Updated BRI Stack and Support
- New BRI A500 & B700 firmware that fixes PCI parity errors.
On some systems A500 & B700 cards can generate parity errors.
On some systems A500 & B700 boards can generate parity errors.
- FreeSwitch Tested
- Update for 2.6.26 kernel

View File

@ -2228,7 +2228,7 @@ init_global_params()
{
if [ $OSYSTEM = "Linux" ]; then
ROUTER_VERSION=3.5.25
ROUTER_VERSION=3.5.26
IFCONFIG_LIST=ifconfig
MODULE_STAT=lsmod
WAN_DRIVERS="wanpipe"

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -552,6 +552,7 @@ int board_reset(wan_aft_cpld_t *cpld, int clear)
switch(cpld->core_info->board_id) {
case AFT_A600_SUBSYS_VENDOR:
case AFT_B601_SUBSYS_VENDOR:
case AFT_W400_SUBSYS_VENDOR:
iface_reg_off = 0x1040;
break;
default:
@ -644,6 +645,7 @@ int board_reset(wan_aft_cpld_t *cpld, int clear)
break;
case AFT_A600_SUBSYS_VENDOR:
case AFT_B601_SUBSYS_VENDOR:
case AFT_W400_SUBSYS_VENDOR:
if (clear) data &= ~0x06;
else data |= 0x06;
break;

View File

@ -191,8 +191,12 @@ aft_core_info_t aft_core_table[] = {
"A140_0100_V", "A140_0100_V*.BIN", AFT_CORE_X1000_SIZE },
{ AFT_A600_SUBSYS_VENDOR, AFT_CHIP_X250, AFT_ANALOG_FE_CORE_ID, 0x20, 0x5B,
"B600_0025_V", "B600_0025_V*.BIN", AFT_CORE_X250_SIZE },
{ AFT_B610_SUBSYS_VENDOR, AFT_CHIP_X250, AFT_ANALOG_FE_CORE_ID, 0x20, 0x5B,
"B610_0025_V", "B610_0025_V*.BIN", AFT_CORE_X250_SIZE },
{ AFT_B601_SUBSYS_VENDOR, AFT_CHIP_X250, AFT_ANALOG_FE_CORE_ID, 0x20, 0x5B,
"B601_0025_V", "B601_0025_V*.BIN", AFT_CORE_X250_SIZE },
{ AFT_W400_SUBSYS_VENDOR, AFT_CHIP_X250, AFT_ANALOG_FE_CORE_ID, 0x20, 0x5B,
"W400_0025_V", "W400_0025_V*.BIN", AFT_CORE_X250_SIZE },
#if 0
{ AFT_TE1_ATM_CORE_ID,
NULL, NULL, 0x00,
@ -433,6 +437,7 @@ static int wan_aftup_gettype(wan_aftup_t *aft, char *type)
aft->cpld.iface = &aftup_shark_flash_iface;
break;
case AFT_ADPTR_A600:
case AFT_ADPTR_W400:
aft->cpld.iface = &aftup_a600_flash_iface;
break;
case U100_ADPTR:
@ -507,6 +512,9 @@ static int wan_aftup_gettype(wan_aftup_t *aft, char *type)
}else if (strncmp(type,"AFT-B601",8) == 0) {
aft->cpld.adptr_type = AFT_ADPTR_B601;
aft->cpld.iface = &aftup_a600_flash_iface;
}else if (strncmp(type,"AFT-W400",8) == 0) {
aft->cpld.adptr_type = AFT_ADPTR_W400;
aft->cpld.iface = &aftup_a600_flash_iface;
}else if (strncmp(type,"U100",8) == 0){
//strcpy(aft->prefix_fw, "AFT_RM");
aft->cpld.adptr_type = U100_ADPTR;
@ -682,10 +690,10 @@ static int wan_aftup_program_card(wan_aftup_t *aft)
if(aft->flash_rev < 3) {
if (aft->flash_new > 2) {
/* B600's and B601's with firmware revision less 2 or lower are physically different from
* the new cards (missing resistor), so it is not possible to update from firmware 2 to 3
* on these cards */
* the new cards (missing resistor), so it is not possible to update from firmware 2 to 3
* on these cards */
printf("%s: Error: Firmware update not possible on this A600 (max:2)\n", aft->if_name);
printf("%s: Error: Firmware update not possible on this A600 (max:2)\n", aft->if_name);
return -EINVAL;
}
}
@ -694,9 +702,9 @@ static int wan_aftup_program_card(wan_aftup_t *aft)
if (err){
return -EINVAL;
}
printf("%s: Current Sangoma Flash: Revision=%X ID=0x%04X\n",
printf("%s: Current Sangoma Flash: Revision=%02X ID=0x%04X\n",
aft->if_name,
aft->flash_rev,
aft->flash_rev & 0xFF,
flash_id);
err = update_flash(
@ -988,6 +996,7 @@ static int wan_aftup_update_card(wan_aftup_t *aft)
break;
case AFT_A600_SUBSYS_VENDOR:
case AFT_B601_SUBSYS_VENDOR:
case AFT_W400_SUBSYS_VENDOR:
aft->cpld.iface = &aftup_a600_flash_iface;
break;
default:
@ -1036,6 +1045,7 @@ static int wan_aftup_update_card(wan_aftup_t *aft)
break;
case AFT_A600_SUBSYS_VENDOR:
case AFT_B601_SUBSYS_VENDOR:
case AFT_W400_SUBSYS_VENDOR:
aft->cpld.chip_id = AFT_CHIP_X250;
aft->cpld.flash = &aft_a600_flash;
break;
@ -1111,6 +1121,7 @@ static int wan_pcie_ctrl(struct wan_aftup_head_t *head)
case AFT_B800_SUBSYS_VENDOR:
case AFT_A600_SUBSYS_VENDOR:
case AFT_B601_SUBSYS_VENDOR:
case AFT_W400_SUBSYS_VENDOR:
break;
case A300_UTE3_SHARK_SUBSYS_VENDOR:
break;

View File

@ -650,6 +650,7 @@ look_up_t conf_if_def_tables[] =
{ WANCONFIG_BITSTRM, bitstrm_if_conftab },
{ WANCONFIG_AFT, xilinx_if_conftab },
{ WANCONFIG_AFT_TE3, xilinx_if_conftab },
{ WANCONFIG_AFT_GSM, xilinx_if_conftab },
{ 0, NULL }
};
@ -693,6 +694,7 @@ look_up_t config_id_str[] =
{ WANCONFIG_MLINK_PPP, (void*)"WAN_MLINK_PPP" },
{ WANCONFIG_TTY, (void*)"WAN_TTY" }, //????
{ WANCONFIG_AFT_ANALOG, (void*)"WAN_AFT_ANALOG" },
{ WANCONFIG_AFT_GSM, (void*)"WAN_AFT_GSM" },
{ WANCONFIG_AFT_ISDN_BRI, (void*)"WAN_AFT_ISDN_BRI" },
{ WANCONFIG_AFT_SERIAL, (void*)"WAN_AFT_SERIAL" },
{ 0, NULL, }
@ -780,6 +782,7 @@ look_up_t sym_table[] =
{ WAN_MEDIA_STS1, (void*)"STS-1" },
{ WAN_MEDIA_E3, (void*)"E3" },
{ WAN_MEDIA_FXOFXS, (void*)"FXO/FXS" },
{ WAN_MEDIA_GSM, (void*)"GSM" },
{ WAN_MEDIA_BRI, (void*)"BRI" },
{ WAN_LCODE_AMI, (void*)"AMI" },

View File

@ -15,6 +15,7 @@ sub new {
_tdm_law => 'MULAW',
_rm_network_sync => 'NO',
_analog_modules => undef,
_fe_line => undef,
};
bless $self, $class;
return $self;

182
util/wancfg_zaptel/W40x.pm Normal file
View File

@ -0,0 +1,182 @@
#class W240x
#for W400 series cards
package W40x;
use Card;
use strict;
#constructor
sub new {
my ($class) = @_;
my $self = {
_is_tdm_api => undef,
_card => undef,
_tdm_law => 'ALAW',
_fe_line => undef,
};
bless $self, $class;
return $self;
}
sub card {
my ( $self, $card ) = @_;
$self->{_card} = $card if defined($card);
return $self->{_card};
}
sub fe_line {
my ( $self, $fe_line ) = @_;
$self->{_fe_line} = $fe_line if defined($fe_line);
return $self->{_fe_line};
}
sub tdm_law {
my ( $self, $tdm_law ) = @_;
$self->{_tdm_law} = $tdm_law if defined($tdm_law);
return $self->{_tdm_law};
}
sub is_tdm_api {
my ( $self, $is_tdm_api ) = @_;
$self->{_is_tdm_api} = $is_tdm_api if defined($is_tdm_api);
return $self->{_is_tdm_api};
}
sub prompt_user{
my($promptString, $defaultValue) = @_;
if ($defaultValue) {
print $promptString, "[", $defaultValue, "]: ";
} else {
print $promptString, ": ";
}
$| = 1; # force a flush after our print
$_ = <STDIN>; # get the input from STDIN (presumably the keyboard)
chomp;
if ("$defaultValue") {
return $_ ? $_ : $defaultValue; # return $_ if it has a value
} else {
return $_;
}
}
sub prompt_user_list{
my @list = @_;
my $i;
my $valid = 0;
for $i (0..$#list) {
printf(" %s\. %s\n",$i+1, @list[$i]);
}
while ($valid == 0){
$| = 1; # force a flush after our print
$_ = <STDIN>; # get the input from STDIN (presumably the keyboard)
chomp;
if ( $_ =~ /(\d+)/ ){
if ( $1 > $#list+1) {
print "Invalid option: Value out of range \n";
} else {
return $1-1 ;
}
} else {
print "Invalid option: Input an integer\n";
}
}
}
sub print {
my ($self) = @_;
$self->card->print();
}
sub gen_wanpipe_conf{
my ($self, $is_freebsd) = @_;
my $wanpipe_conf_template = $self->card->current_dir."/templates/wanpipe.tdm.w400";
my $wanpipe_conf_file = $self->card->current_dir."/".$self->card->cfg_dir."/wanpipe".$self->card->device_no.".conf";
my $device_no = $self->card->device_no;
my $tdmv_span_no = $self->card->tdmv_span_no;
my $pci_slot = $self->card->pci_slot;
my $pci_bus = $self->card->pci_bus;
my $tdm_law = $self->tdm_law;
my $is_tdm_api = $self->is_tdm_api;
my $tdm_voice_op_mode = "TDM_VOICE";
my $fe_line = $self->fe_line;
my $tdmv_span_no = $self->card->tdmv_span_no;
if($self->is_tdm_api eq '0') {
$tdm_voice_op_mode = "TDM_VOICE_API";
}
open(FH, $wanpipe_conf_template) or die "Can open $wanpipe_conf_template";
my $wp_file='';
while (<FH>) {
$wp_file .= $_;
}
close (FH);
open(FH, ">$wanpipe_conf_file") or die "Cant open $wanpipe_conf_file";
$wp_file =~ s/DEVNUM/$device_no/g;
$wp_file =~ s/IFNUM/$device_no/g;
$wp_file =~ s/FELINE/$fe_line/g;
$wp_file =~ s/TDM_VOICE_OP_MODE/$tdm_voice_op_mode/g;
$wp_file =~ s/SLOTNUM/$pci_slot/g;
$wp_file =~ s/BUSNUM/$pci_bus/g;
$wp_file =~ s/TDM_LAW/$tdm_law/g;
$wp_file =~ s/TDMVSPANNO/$tdmv_span_no/g;
print FH $wp_file;
close (FH);
# print "\n created $fname for A$card_model $devnum SLOT $slot BUS $bus HWEC $hwec_mode\n";
}
sub gen_zaptel_conf
{
my ($self) = @_;
my $zp_file='';
my $tmpstr='';
my $tmpchan=1;
$zp_file.="\n\#Sangoma AFT-W".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] <wanpipe".$self->card->device_no.">\n";
$zp_file.="bchan=".$self->card->first_chan."\n";
$tmpstr.="echocanceller=mg2,".$self->card->first_chan."\n";
if ($self->card->dahdi_echo eq 'NO') {
$zp_file.="#";
}
$zp_file.=$tmpstr;
$tmpchan=$self->card->first_chan+1;
$zp_file.="hardhdlc=".$tmpchan."\n";
return $zp_file;
}
sub gen_zapata_conf
{
my ($self) = @_;
my $zp_file='';
my $tmpchan=1;
$zp_file.="\n\;Sangoma AFT-W".$self->card->card_model." port ".$self->fe_line." [slot:".$self->card->pci_slot." bus:".$self->card->pci_bus." span:".$self->card->tdmv_span_no."] <wanpipe".$self->card->device_no.">\n";
$zp_file.="context = ".$self->card->zap_context."\n";
$zp_file.="group = ".$self->card->zap_group."\n";
if ($self->card->dahdi_echo eq 'NO') {
$zp_file.="echocancel = no\n";
$zp_file.="echocancelwhenbridged = no\n";
} else {
$zp_file.="echocancel = yes\n";
$zp_file.="echocancelwhenbridged = yes\n";
}
$zp_file.="signalling = gsm\n";
$zp_file.="wat_moduletype = telit\n";
$zp_file.="channel => ".$self->card->first_chan."\n";
return $zp_file;
}
1;

View File

@ -0,0 +1,39 @@
#================================================
# WANPIPE1 Configuration File
#================================================
#
# Date: Mon Jul 31 18:10:23 EDT 2006
#
# Note: This file was generated automatically
# by /usr/local/sbin/setup-sangoma program.
#
# If you want to edit this file, it is
# recommended that you use wancfg program
# to do so.
#================================================
# Sangoma Technologies Inc.
#================================================
[devices]
wanpipeDEVNUM = WAN_AFT_GSM, Comment
[interfaces]
wIFNUMg1 = wanpipeDEVNUM, , TDM_VOICE_OP_MODE, Comment
[wanpipeDEVNUM]
CARD_TYPE = AFT_GSM
S514CPU = A
CommPort = PRI
AUTO_PCISLOT = NO
PCISLOT = SLOTNUM
PCIBUS = BUSNUM
FE_MEDIA = GSM
FE_LINE = FELINE
TDMV_LAW = TDM_LAW
MTU = 1500
UDPPORT = 9000
TDMV_SPAN = TDMVSPANNO
[wIFNUMg1]
ACTIVE_CH = ALL
MTU = 16

View File

@ -88,6 +88,7 @@ use Card;
use A10x;
use A10u;
use A20x;
use W40x;
use A50x;
use U10x;
use analogspan;
@ -155,8 +156,9 @@ my $woomera_conf="";
my $devnum=1;
my $current_zap_span=1;
my $current_tdmapi_span=1;
#my $current_bri_span=1;
my $current_zap_channel=1;
my $num_gsm_devices=0;
my $num_gsm_devices_total=0;
my $num_analog_devices=0;
my $num_analog_devices_total=0;
my $num_usb_devices_total=0;
@ -208,6 +210,7 @@ my $bri_trunk_type='';
my $def_femedia='';
my $def_feclock='';
my $def_hw_port_map='DEFAULT';
my $def_gsm_option='';
my $def_bri_option='';
my $def_bri_default_tei='';
my $def_bri_default_tei_opt=$FALSE;
@ -465,7 +468,10 @@ if( $zaptel_installed==$TRUE && $os_type_list =~ m/Linux/ && $is_fs == $FALSE) {
prepare_files();
config_t1e1();
config_bri();
config_gsm();
config_analog();
if($usb_device_support == $TRUE && $os_type_list =~ m/Linux/) {
config_usbfxo();
}
@ -500,15 +506,12 @@ print "Sangoma cards configuration complete, exiting...\n\n";
#######################################FUNCTIONS##################################################
sub get_card_name{
my ($card_name) = @_;
if ( $card_name eq '600' || $card_name eq '601' || $card_name eq '610' || $card_name eq '700') {
if ( $card_name eq '400') {
$card_name = "W".$card_name;
} elsif ( $card_name eq '600' || $card_name eq '601' || $card_name eq '610' || $card_name eq '700') {
$card_name = "B".$card_name;
} else {
#if ( $is_trillium == $TRUE ){
# $card_name = $card_name;
#}
#else {
$card_name = "A".$card_name;
#}
$card_name = "A".$card_name;
}
return $card_name;
}
@ -854,9 +857,9 @@ sub check_dahdi_ver
my $ver_major;
my $ver_minor;
my $str_tmp;
my $strDahdi="DAHDI Tools Version";
my $strDahdi="DAHDI Version";
$str_tmp = `dahdi_cfg -v 2>&1 | grep \"$strDahdi\" `;
$str_tmp = `dahdi_cfg -vt 2>&1 | grep \"$strDahdi\" `;
if ($str_tmp =~ m/(\d).(\d)/) {
$ver_major = $1;
$ver_minor = $2;
@ -864,13 +867,16 @@ sub check_dahdi_ver
}
$dahdi_echo='mg2';
if ($ver_major > $dahdi_ver_major) {
$dahdi_echo='HWEC';
} elsif ($ver_major == $dahdi_ver_major) {
if ($ver_minor > $dahdi_ver_minor) {
$dahdi_echo='HWEC';
}
}
# NC: This is not necessary as there was a bug in a driver
# NC: that did not allow dahdi to autodetec hwec.
# if ($ver_major > $dahdi_ver_major) {
# $dahdi_echo='HWEC';
# } elsif ($ver_major == $dahdi_ver_major) {
# if ($ver_minor > $dahdi_ver_minor) {
# $dahdi_echo='HWEC';
# }
# }
}
@ -962,9 +968,12 @@ sub apply_changes{
if ($res =~ m/now/){
$asterisk_version1 = `asterisk -V | cut -d' ' -f 2 | cut -d '.' -f 2`;
$asterisk_version2 = `asterisk -V | cut -d' ' -f 2 | cut -d '.' -f 3`;
if (($asterisk_version1 >= 6) && ($asterisk_version2 >= 2)){
if ($asterisk_version1 =~ m/UNKNOWN/) {
$asterisk_command='core stop now';
}else{
} elsif (($asterisk_version1 >= 6) && ($asterisk_version2 >= 2)) {
$asterisk_command='core stop now';
} else {
$asterisk_command='stop now';
}
} else {
@ -983,25 +992,15 @@ sub apply_changes{
if (`(pidof asterisk)` != 0 ){
print "\nStopping Asterisk...\n";
exec_command("asterisk -rx \"$asterisk_command\"");
sleep 2;
sleep 5;
while (`(pidof asterisk)` != 0 ){
if ($asterisk_command eq "stop now"){
print "Failed to stop asterisk using command: \'$asterisk_command\' \n";
my @options=("Force Stop - Send KILL signal to asterisk", "Wait - Wait for asterisk to stop", "Exit - Do not apply changes");
my $res=&prompt_user_list(@options,"");
if ( $res =~ m/Force Stop/){
execute_command("kill -KILL \$(pidof asterisk)");
} elsif ( $res =~ m/Exit/ ){
exit(1);
} else {
print "Waiting for asterisk to stop...\n";
sleep 5;
exec_command("asterisk -rx \"$asterisk_command\"");
}
print "Failed to stop asterisk using command: \'$asterisk_command\' Forcing Asterisk Down \n";
execute_command("killall -9 safe_asterisk");
execute_command("killall -9 asterisk");
} else {
#stop when convenient option was selected
print "Waiting for asterisk to stop...\n";
print "Waiting for asterisk to stop when convenient...\n";
sleep 3;
}
}
@ -1145,7 +1144,7 @@ sub apply_changes{
sleep 2;
}elsif($config_zapata==$TRUE){
print "\nStarting Asterisk...\n";
exec_command("asterisk");
exec_command("safe_asterisk");
sleep 2;
@ -1631,6 +1630,7 @@ sub summary{
print(" $num_digital_devices_total T1/E1 port(s) detected, $num_digital_devices configured\n");
print(" $num_bri_devices_total ISDN BRI port(s) detected, $num_bri_devices configured\n");
print(" $num_analog_devices_total analog card(s) detected, $num_analog_devices configured\n");
print(" $num_gsm_devices_total GSM card(s) detected, $num_gsm_devices configured\n");
print(" $num_usb_devices_total usb device(s) detected, $num_usb_devices configured\n");
@ -2177,9 +2177,6 @@ sub get_bri_conn_type{
exit 1;
}
sub config_bri{
my $a50x;
if (!$first_cfg && $silent==$FALSE) {
@ -2297,7 +2294,7 @@ select_bri_option:
}
}
}else{
printf ("%s on slot:%s bus:%s port:%s not configured\n", get_card_name($card->card_model), $3, $4, $5);
printf ("%s on slot:%s bus:%s port:%s not configured\n", get_card_name($card->card_model), $3, $4, $5);
prompt_user("Press any key to continue");
}
@ -2366,8 +2363,6 @@ select_bri_option:
$a50x->gen_wanpipe_conf(0);
}
# $a50x->gen_wanpipe_conf();
if ( $dev =~ /(\d+):NT/ ){
$bri_conf.=$a50x->gen_bri_conf($bri_pos,"bri_nt", $group, $country, $operator, $conn_type, '');
if($is_fs == $TRUE) {
@ -2445,6 +2440,112 @@ select_bri_option:
}
}
sub config_gsm {
my $w40x;
$first_cfg=0;
print "------------------------------------\n";
print "Configuring GSM cards [W400]\n";
print "------------------------------------\n";
my $skip_card=$FALSE;
$zaptel_conf.="\n";
$zapata_conf.="\n";
foreach my $dev (@hwprobe) {
if ($dev =~ /.*AFT-W400(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\d+).*/) {
$skip_card=$FALSE;
my $card = eval {new Card(); } or die ($@);
$card->first_chan($current_zap_channel);
$card->current_dir($current_dir);
$card->cfg_dir($cfg_dir);
$card->device_no($devnum);
$card->card_model("400");
$card->pci_slot($2);
$card->pci_bus($3);
if($dahdi_installed == $TRUE) {
$card->dahdi_conf('YES');
$card->dahdi_echo('NO')
}
$num_gsm_devices_total++;
if ($silent == $FALSE) {
system('clear');
print "\n-----------------------------------------------------------\n";
printf("AFT-%s detected on slot:%d bus:%d port:%d\n", get_card_name($card->card_model), $card->pci_slot, $card->pci_bus, $4);
print "-----------------------------------------------------------\n";
}
if ($is_trixbox == $FALSE) {
if($silent==$FALSE){
printf ("\nWould you like to configure AFT-%s port %s on slot:%d bus:%d\n",
get_card_name($card->card_model), $4, $card->pci_slot, $card->pci_bus);
my @options=("YES", "NO", "Exit");
$def_gsm_option=&prompt_user_list(@options,$def_gsm_option);
} else {
$def_gsm_option="YES";
}
}
if($def_gsm_option eq 'YES') {
$w40x = eval {new W40x(); } or die ($@);
$w40x->card($card);
$w40x->fe_line($4);
if ($#silent_tdm_laws >= 0) {
$silent_tdm_law = pop(@silent_tdm_laws);
$w40x->tdm_law($silent_tdm_law);
} else {
$w40x->tdm_law(&prompt_tdm_law());
}
$startup_string.="wanpipe$devnum ";
$cfg_string.="wanpipe$devnum ";
if($silent==$FALSE){
prompt_user("Press any key to continue");
}
if( $is_tdm_api == $FALSE) {
printf ("AFT-%s configured on slot:%d bus:%d span:%s\n", get_card_name($card->card_model), $card->pci_slot, $card->pci_bus, $current_zap_span);
$current_zap_channel+=2;
$num_zaptel_config++;
$card->tdmv_span_no($current_zap_span);
$current_zap_span++;
$zaptel_conf.=$w40x->gen_zaptel_conf($dchan_str);
$w40x->card->zap_context(&get_zapata_context($w40x->card->card_model, $w40x->fe_line));
$w40x->card->zap_group(&get_zapata_group($w40x->card->card_model, $w40x->fe_line, $w40x->card->zap_context));
$zapata_conf.=$w40x->gen_zapata_conf();
} else {
printf ("AFT-%s configured on slot:%s bus:%s span:$current_tdmapi_span\n", get_card_name($card->card_model), $card->pci_slot, $card->pci_bus);
$w40x->is_tdm_api($TRUE);
$card->tdmv_span_no($current_tdmapi_span);
$current_tdmapi_span++;
}
$w40x->gen_wanpipe_conf();
$devnum++;
$num_gsm_devices++;
} else {
printf ("AFT-%s on slot:%s bus:%s not configured\n", get_card_name($card->card_model), $card->pci_slot, $card->pci_bus);
prompt_user("Press any key to continue");
}
} # if ($dev =~ /.*AFT-W400(.*):.*SLOT=(\d+).*BUS=(\d+).*PORT=(\d+).*HWEC=(\w+)
}
if($num_gsm_devices_total!=0){
print("\nGSM cards configuration complete.\n");
} else {
print("\nNo Sangoma GSM cards detected\n\n");
}
if ($silent==$FALSE) {
prompt_user("Press any key to continue");
}
}
#------------------------------T1/E1 FUNCTIONS------------------------------------#
@ -3584,14 +3685,19 @@ ENDSS7CONFIG:
}
}
if($num_digital_devices_total!=0){
print("\nT1/E1 card configuration complete.\n");
if($silent==$FALSE){
prompt_user("Press any key to continue");
}
$first_cfg=0;
} else {
print("\nNo Sangoma ISDN T1/E1 cards detected\n\n");
if($silent==$FALSE){
prompt_user("Press any key to continue");
}
}
# close SCR;
}
@ -4321,7 +4427,7 @@ sub config_smg_ctrl_boot {
my @boot_scripts= ('smg_ctrl','smg_ctrl_safe');
foreach my $boot_scripts (@boot_scripts) {
print"Remvoing old $boot_scripts boot";
print"Removing old $boot_scripts boot";
if ($have_update_rc_d) {#debian/ubuntu
$command = "update-rc.d -f $boot_scripts remove >>/dev/null 2>>/dev/null";
if (system($command) == 0){

View File

@ -1149,7 +1149,7 @@ int build_linkdef_list (FILE* file)
config_id = name2val(token[1], config_id_str);
if (!config_id) {
if (verbose) printf(
" * Media ID %s is invalid!\n", token[1]);
" * Media ID %s is invalid!\n", token[1]);
err = ERR_CONFIG;
show_error(err);
break;
@ -1439,7 +1439,7 @@ int configure_link (link_def_t* def, char init)
return ERR_CONFIG;
}
if (err){
fprintf(stderr,"\n\tError parsing %s configuration file\n",conf_file);
fprintf(stderr,"\n\tError parsing %s configuration file. Token (%s = %s)\n", conf_file, token[0], token[1]);
if(weanie_flag) fprintf(stderr,"\tPlease check %s for errors\n", verbose_log);
fprintf(stderr, "\n");
return err;

View File

@ -318,6 +318,7 @@ static key_word_t common_conftab[] = /* Common configuration parameters */
{ "RM_RINGAMPL", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, fxs_ringampl), DTYPE_INT },
{ "RM_RELAXCFG", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, relaxcfg), DTYPE_UCHAR },
{ "RM_FAKE_POLARITY", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, fake_polarity), DTYPE_UCHAR },
{ "RM_FAKE_POLARITY_THRESHOLD", offsetof(wandev_conf_t, fe_cfg)+offsetof(sdla_fe_cfg_t, cfg) + smemof(sdla_remora_cfg_t, fake_polarity_thres), DTYPE_INT },
/* TDMV parameters */
{ "TDMV_SPAN", offsetof(wandev_conf_t, tdmv_conf)+smemof(wan_tdmv_conf_t, span_no), DTYPE_UCHAR},
@ -1015,9 +1016,10 @@ static look_up_t conf_if_def_tables[] =
{ WANCONFIG_AFT_TE1, xilinx_if_conftab },
{ WANCONFIG_AFT_TE3, xilinx_if_conftab },
{ WANCONFIG_AFT_ANALOG, xilinx_if_conftab },
{ WANCONFIG_AFT_GSM, xilinx_if_conftab },
{ WANCONFIG_AFT_ISDN_BRI, xilinx_if_conftab },
{ WANCONFIG_AFT_SERIAL, xilinx_if_conftab },
{ WANCONFIG_AFT_56K, xilinx_if_conftab },
{ WANCONFIG_AFT_56K, xilinx_if_conftab },
{ WANCONFIG_ASYHDLC, chdlc_conftab },
{ 0, NULL }
};
@ -1077,6 +1079,7 @@ static look_up_t config_id_str[] =
{ WANCONFIG_ADCCP, "WAN_ADCCP" },
{ WANCONFIG_MLINK_PPP, "WAN_MLINK_PPP" },
{ WANCONFIG_USB_ANALOG, "WAN_USB_ANALOG" },
{ WANCONFIG_AFT_GSM, "WAN_AFT_GSM" },
{ 0, NULL, }
};
@ -1169,6 +1172,7 @@ static look_up_t sym_table[] =
{ WAN_MEDIA_STS1, "STS-1" },
{ WAN_MEDIA_E3, "E3" },
{ WAN_MEDIA_FXOFXS, "FXO/FXS" },
{ WAN_MEDIA_GSM, "GSM" },
{ WAN_MEDIA_BRI, "BRI" },
{ WAN_LCODE_AMI, "AMI" },
{ WAN_LCODE_B8ZS, "B8ZS" },
@ -1262,6 +1266,7 @@ static look_up_t sym_table[] =
{ WANOPT_ADSL, "S518" },
{ WANOPT_AFT, "AFT" },
{ WANOPT_AFT, "USB" },
{ WANOPT_AFT_GSM, "AFT_GSM" },
/*-------------ADSL options--------------*/
{ RFC_MODE_BRIDGED_ETH_LLC, "ETH_LLC_OA" },

View File

@ -1325,6 +1325,132 @@ ring_stop_again:
return 0;
}
static int aft_gsm_pcm_loopback_toggle(void)
{
wan_udp.wan_udphdr_command = WAN_GSM_PCM_LOOPBACK;
wan_udp.wan_udphdr_return_code = 0xaa;
wan_udp.wan_udphdr_data_len = 0;
DO_COMMAND(wan_udp);
if (wan_udp.wan_udphdr_return_code != WAN_CMD_OK) {
printf("Failed to toggle PCM loopback!\n");
fflush(stdout);
return 0;
}
printf("Done toggling PCM loopback!\n");
fflush(stdout);
return 0;
}
static int aft_gsm_update_sim_status(void)
{
wan_udp.wan_udphdr_command = WAN_GSM_UPDATE_SIM_STATUS;
wan_udp.wan_udphdr_return_code = 0xaa;
wan_udp.wan_udphdr_data_len = 0;
DO_COMMAND(wan_udp);
if (wan_udp.wan_udphdr_return_code != WAN_CMD_OK) {
printf("Failed to update GSM SIM status!\n");
fflush(stdout);
return 0;
}
printf("Done updating GSM status!\n");
fflush(stdout);
return 0;
}
static int aft_gsm_regdump(void)
{
wan_udp.wan_udphdr_command = WAN_GSM_REGDUMP;
wan_udp.wan_udphdr_return_code = 0xaa;
wan_udp.wan_udphdr_data_len = 0;
DO_COMMAND(wan_udp);
if (wan_udp.wan_udphdr_return_code != WAN_CMD_OK) {
printf("Failed to get GSM register dump!\n");
fflush(stdout);
return 0;
}
printf("Done dumping GSM registers!\n");
fflush(stdout);
return 0;
}
static int aft_gsm_uart_debug(int enable)
{
wan_gsm_udp_t *gsm_udp = NULL;
wan_udp.wan_udphdr_command = WAN_GSM_UART_DEBUG;
wan_udp.wan_udphdr_return_code = 0xaa;
gsm_udp = (wan_gsm_udp_t *)get_wan_udphdr_data_ptr(0);
gsm_udp->u.uart_debug = enable ? WAN_TRUE : WAN_FALSE;
wan_udp.wan_udphdr_data_len = sizeof(wan_gsm_udp_t);
DO_COMMAND(wan_udp);
if (wan_udp.wan_udphdr_return_code != WAN_CMD_OK) {
printf("Failed to %s UART debugging!\n", enable ? "enable" : "disable");
fflush(stdout);
return 0;
}
printf("GSM UART debugging is now %s!\n", enable ? "enabled" : "disabled");
fflush(stdout);
return 0;
}
static int aft_gsm_audio_debug()
{
wan_udp.wan_udphdr_command = WAN_GSM_AUDIO_DEBUG;
wan_udp.wan_udphdr_return_code = 0xaa;
wan_udp.wan_udphdr_data_len = 0;
DO_COMMAND(wan_udp);
if (wan_udp.wan_udphdr_return_code != WAN_CMD_OK) {
printf("Failed to toggle audio debugging!\n");
fflush(stdout);
return 0;
}
printf("GSM audio debugging was toggled!\n");
fflush(stdout);
return 0;
}
static int aft_gsm_pll_reset()
{
wan_udp.wan_udphdr_command = WAN_GSM_PLL_RESET;
wan_udp.wan_udphdr_return_code = 0xaa;
wan_udp.wan_udphdr_data_len = 0;
DO_COMMAND(wan_udp);
if (wan_udp.wan_udphdr_return_code != WAN_CMD_OK) {
printf("Failed to reset PLL!\n");
fflush(stdout);
return 0;
}
printf("GSM PLL reset done!\n");
fflush(stdout);
return 0;
}
static int aft_gsm_power_toggle()
{
wan_udp.wan_udphdr_command = WAN_GSM_POWER_TOGGLE;
wan_udp.wan_udphdr_return_code = 0xaa;
wan_udp.wan_udphdr_data_len = 0;
DO_COMMAND(wan_udp);
if (wan_udp.wan_udphdr_return_code != WAN_CMD_OK) {
printf("Failed to toggle power!\n");
fflush(stdout);
return 0;
}
printf("GSM power toggle done!\n");
fflush(stdout);
return 0;
}
static int aft_remora_regdump(int mod_no)
{
wan_remora_udp_t *rm_udp;
@ -1557,6 +1683,15 @@ int AFTUsage(void)
printf("\t a regdump Dumps FXS/FXO registers.\n");
printf("\t ( -m <mod_no> - Module number)\n");
printf("\t a stats Voltage status ( -m <mod_no> - Module number)\n");
printf("\tAFT GSM\n");
printf("\t g regdump Dumps GSM registers to the kernel ring buffer\n");
printf("\t g ude GSM UART debug enable (any UART transmission is logged to the kernel ring buffer)\n");
printf("\t g udd GSM UART debug disable\n");
printf("\t g pr PLL reset (force UART reset)\n");
printf("\t g pt Power toggle (force turn on/off GSM module)\n");
printf("\t g adt Toggle (enable/disable) audio debugging (play demo-congrats at the kernel level ignoring audio from user space)\n");
printf("\t g uss Update GSM SIM status\n");
printf("\t g plt Toggle the PCM audio loopback\n");
printf("\tAFT Debugging\n");
printf("\t d err Enable RX RBS debugging\n");
printf("\t d drr Disable RX RBS debugging\n");
@ -1652,15 +1787,24 @@ static void aft_perf_stats_disable(void)
static void aft_perf_stats( void )
{
aft_driver_performance_stats_t *aft_perf;
aft_driver_performance_stats_t *aft_perf = NULL;
wan_udp.wan_udphdr_command= WANPIPEMON_READ_PERFORMANCE_STATS;
wan_udp.wan_udphdr_return_code = 0xaa;
wan_udp.wan_udphdr_data_len = 0;
wan_udp.wan_udphdr_data[0] = 0;
DO_COMMAND(wan_udp);
if (wan_udp.wan_udphdr_return_code != WAN_CMD_OK) {
fprintf(stderr, "Unable to retrieve AFT performance stats!\n");
return;
}
aft_perf = (aft_driver_performance_stats_t*)&wan_udp.wan_udphdr_data[0];
aft_perf = (aft_driver_performance_stats_t *)&wan_udp.wan_udphdr_data[0];
if (!aft_perf) {
fprintf(stderr, "invalid AFT performance stats retrieved (len = %d)!\n", wan_udp.wan_udphdr_data_len);
return;
}
BANNER("WANPIPE PERFORMANCE STATS");
@ -2168,6 +2312,28 @@ int AFTMain(char *command,int argc, char* argv[])
}
break;
case 'g':
if (!strcmp(opt,"regdump")){ /* Register dump */
aft_gsm_regdump();
} else if (!strcmp(opt, "ude")) { /* UART debug enable */
aft_gsm_uart_debug(1);
} else if (!strcmp(opt, "udd")) { /* UART debug disable */
aft_gsm_uart_debug(0);
} else if (!strcmp(opt, "adt")) { /* Audio Debug Toggle */
aft_gsm_audio_debug();
} else if (!strcmp(opt, "pr")) { /* PLL Reset */
aft_gsm_pll_reset();
} else if (!strcmp(opt, "pt")) { /* Power Toggle */
aft_gsm_power_toggle();
} else if (!strcmp(opt, "uss")) { /* Update SIM Status */
aft_gsm_update_sim_status();
} else if (!strcmp(opt, "plt")) { /* PCM Loopback Toggle */
aft_gsm_pcm_loopback_toggle();
} else {
printf("ERROR: Invalid GSM option '%s', Type wanpipemon <cr> for help\n\n", opt);
}
break;
case 'a':
err = 0;
for(i=0;i<argc;i++){

View File

@ -133,7 +133,7 @@ int pcap_output=0;
int pcap_prot=0;
int pcap_isdn_network=0;
FILE *pcap_output_file;
char pcap_output_file_name[50];
char pcap_output_file_name[1024];
FILE *trace_bin_out;
FILE *trace_bin_in;
@ -272,6 +272,9 @@ struct fun_protocol function_lookup[] = {
{ WANCONFIG_AFT_ANALOG, "aft", AFTConfig, AFTUsage, AFTMain, AFTDisableTrace,
AFTget_main_menu, AFTget_cmd_menu,
NULL,NULL, 2 },
{ WANCONFIG_AFT_GSM, "aft", AFTConfig, AFTUsage, AFTMain, AFTDisableTrace,
AFTget_main_menu, AFTget_cmd_menu,
NULL,NULL, 2 },
#if defined(CONFIG_PRODUCT_WANPIPE_USB)
{ WANCONFIG_USB_ANALOG, "usb", USBConfig, USBUsage, USBMain, NULL,
USBget_main_menu, USBget_cmd_menu,
@ -1167,8 +1170,7 @@ static int init(int argc, char *argv[], char* command)
exit(1);
}
strncpy(pcap_output_file_name, argv[i+1], WAN_IFNAME_SZ);
snprintf(pcap_output_file_name, argv[i+1], sizeof(pcap_output_file_name));
}else if (!strcmp(argv[i], "-x25opt")){
int x;
if (i+1 > argc-1){

View File

@ -285,6 +285,7 @@ extern struct fun_protocol function_lookup[];
(prot==WANCONFIG_AFT_TE3)?"AFT_TE3":\
(prot==WANCONFIG_AFT_ANALOG)?"AFT_ANALOG":\
(prot==WANCONFIG_USB_ANALOG)?"U100_ANALOG":\
(prot==WANCONFIG_AFT_GSM)?"AFT_GSM":\
(prot==WANCONFIG_ZAP)?"Zaptel":\
"Unknown")

View File

@ -25,7 +25,7 @@
#
%define NAME wanpipe
%define VERSION 3.5.25
%define VERSION 3.5.26
%define RELEASE 0
%define KVERSION %{?kernel}
%define KSRC %{?ksrc}
@ -259,13 +259,48 @@ fi
%changelog
* Tue Apr 24 2012 Nenad Corbic <ncorbic@sangoma.com> - 3.5.26
==================================================================
- Wanpipe W400 GSM support: Asterisk/Dahdi & FreeSWITCH/FreeTDM
- Wanpipe B610 FXS support
- Fixed Dahdi 2.5 and higher hwec autodetection
For dahdi 2.5 and higher the HWEC option was needed in
dahdi/system.conf to enable onboard hwec.
This fix allows default mg2 software echo to be specified
in dahdi/system.conf, and dahdi will autodetect the sangoma onboard hwec.
- Fixed sangoma hwec boards to use dahdi software ec if hwec is turned off.
Wanpipe driver did not allow sangoma hwec enabled boards to use dahdi
software ec even if hwec was turned off in wanpipe1.conf
This has now been fixed.
If TDMV_HWEC=NO is set in wanpipe1.conf dahdi will now use software ec.
- Fixed BRI dchan reliability
- Fixed BRI for 64bit
The fix for audio issue in 3.5.25 caused the issue on 64bit.
- Dahdi build bug fixes for Trixbox
- Zaptel build bug fixes from 3.5.25
- Build fixes for 3.1.X kernel.
- Fake polarity feature used for Euro Caller ID
- E1 NCRC CAS Framer Configuration for Latin America
Previous NCRC Framer config did not work in all cases.
Affects protocols such as MFC-R2 or CAS
- Analog boards with network sync option set to yes:
Default to fax mode buffering.
Use "when full" dahdi buffer policy.
Improves faxing from PRI to Analog with sync cable.
- Fixed wancfg_dahdi to:
start asterisk using safe_asterisk
to properly detect dahdi version
* Tue Feb 21 2012 Nenad Corbic <ncorbic@sangoma.com> - 3.5.25
==================================================================
- Dahdi 2.6 support
- Linux 3.2.6 support
- Support for B610 Single FXS card
- Support for B500 4 port BRI card
- Support for B610 Single FXS board
- Support for B500 4 port BRI board
- Reduced memory foot print of the driver
by removing some unused statistics structures
- New HWEC firmare v1.7.4 fixes delayed fax issus
@ -302,7 +337,7 @@ fi
* Wed Aug 24 2011 Nenad Corbic <ncorbic@sangoma.com> - 3.5.22
==================================================================
- Bug introducted in .21 release for analog card.
- Bug introducted in .21 release for analog board.
Changed the way wanpipe enumerates analog channels
breaks backward compatibility. Reverted to original.
@ -413,7 +448,7 @@ fi
- Added SW HDLC into the core. B
- B601 is now supported on FreeTDM/FreeSWITCH and TMDAPI
- Added wan_fxotune utility to utils directory
Used to tune fxo cards under TDM API or FreeSWITCH mode.
Used to tune fxo boards under TDM API or FreeSWITCH mode.
@ -432,7 +467,7 @@ fi
dma overruns.
- Bug fix in tdmapi where excessive memory was allocated on pre-allocation buffers.
- Bug fix tdmapi defaults to 20ms chunk size instead of 10ms
- Bug fix broken support for A101/2 legacy EOL cards.
- Bug fix broken support for A101/2 legacy EOL boards.
- New XEN Support
TDM Voice will now work properly on xen virtualized machines
- Fix for 64bit 8gig issues
@ -465,11 +500,11 @@ fi
===================================================================
- Fixed Dahdi 2.3 Support
- Fixed FreeSwitch Openzap HardHDLC option for AFT cards
- Fixed wanpipemon support for non aft cards.
- Fixed FreeSwitch Openzap HardHDLC option for AFT boards
- Fixed wanpipemon support for non aft boards.
- Merged USB FXO code from 3.6 release
- USB FXO bug fix for 2.6.32 kernels
- Support for B800 Analog card
- Support for B800 Analog board
- Fixed alarm reporting in DAHDI/ZAPTEL
- Added Extra EC DSP Configuration Options
@ -562,7 +597,7 @@ fi
- Fixed Tx Tristate
- Updated yellow alarm handling for Dallas maxim cards
- Updated yellow alarm handling for Dallas maxim boards
(A101/2/4/8)
- Autodetect USB support so that driver will compile
@ -576,7 +611,7 @@ fi
- Update to T1 Yellow Alarm handling.
In some cases Yellow alarm did not turn off poperly causing
line to stay down an card startup.
line to stay down an board startup.
- Update configuration utility
wancfg_fs updated for sangoma_prid configuration. Added wancfg_openzap
for OpenZap Configuration
@ -592,10 +627,10 @@ fi
- Updated for 2.6.30 kernel
- New firmawre feature for A101/2/5/8: Free Run Timer Interrupt
The AFT T1/E1 cards will now provide perfect timing to zatpel/dahdi
The AFT T1/E1 boards will now provide perfect timing to zatpel/dahdi
even when the ports are not connected. The free run interrupt
will be enabled when all zaptel/dahdi ports are down, or on
inital card start. To test this feature just start a wanpipe
inital board start. To test this feature just start a wanpipe
port with zaptel/dahdi and run zttest.
A108 firmare V38
A104/2/1/ firmware V36
@ -633,7 +668,7 @@ fi
- TDM API
Updated the Global TDM Device
This device can be used to read events an all cards configured in
This device can be used to read events an all boards configured in
TDM API mode.
- Libsangoma verion 3.1.0
@ -704,7 +739,7 @@ fi
* Fri May 08 2009 Nenad Corbic <ncorbic@sangoma.com> - 3.5.2
===================================================================
- B700 PCIe cards were being displayed as PCI cards in hwprobe
- B700 PCIe boards were being displayed as PCI boards in hwprobe
- Bug fix in wancfg_zaptel
* Thu May 07 2009 Nenad Corbic <ncorbic@sangoma.com> - 3.5.1
@ -728,7 +763,7 @@ fi
- Unified driver for Linux & Windows
- Updated BRI Stack and Support
- New BRI A500 & B700 firmware that fixes PCI parity errors.
On some systems A500 & B700 cards can generate parity errors.
On some systems A500 & B700 boards can generate parity errors.
- FreeSwitch Tested
- Update for 2.6.26 kernel