/***************************************************************************** * sdladrv_fe.c SDLA FE interface support Module. * * * Author: Alex Feldman * * Copyright: (c) 2006 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. * ============================================================================ * Aug 10, 2006 Alex Feldman Initial version * * July 5, 2007 David Rokhvarg Added support of A500 - ISDN BRI card. *****************************************************************************/ /***************************************************************************** * Notes: * ------ ****************************************************************************/ #define __SDLA_HW_LEVEL #define __SDLADRV__ #define SDLADRV_NEW /*************************************************************************** **** I N C L U D E F I L E S **** ***************************************************************************/ #if defined(__LINUX__)||defined(__KERNEL__) # define _K22X_MODULE_FIX_ #endif #include "wanpipe_includes.h" #include "wanpipe_defines.h" #include "wanpipe_debug.h" #include "wanpipe_common.h" #include "wanpipe.h" #include "sdlasfm.h" /* SDLA firmware module definitions */ #include "sdlapci.h" /* SDLA PCI hardware definitions */ #include "sdladrv.h" /* API definitions */ #if defined(WAN_DEBUG_FE) # if defined(__WINDOWS__) # pragma message("WAN_DEBUG_FE - Debugging Enabled") # else # warning "WAN_DEBUG_FE - Debugging Enabled" # endif #endif #if defined(WAN_DEBUG_REG) # if defined(__WINDOWS__) # pragma message("WAN_DEBUG_REG - Debugging Enabled") # else # warning "WAN_DEBUG_REG - Debugging Enabled" # endif #endif #define AFT_A600_BASE_REG_OFF 0x1000 #define A600_REG_OFF(reg) reg+AFT_A600_BASE_REG_OFF /*************************************************************************** **** M A C R O S / D E F I N E S **** ***************************************************************************/ #define BIT_DEV_ADDR_CLEAR 0x600 #define BIT_DEV_ADDR_CPLD 0x200 #define XILINX_MCPU_INTERFACE 0x44 #define XILINX_MCPU_INTERFACE_ADDR 0x46 /*************************************************************************** **** F U N C T I O N P R O T O T Y P E S **** ***************************************************************************/ extern int sdla_cmd (void* phw, unsigned long offset, wan_mbox_t* mbox); u_int8_t sdla_legacy_read_fe (void *phw, ...); int sdla_legacy_write_fe (void *phw, ...); int sdla_te1_write_fe(void* phw, ...); u_int8_t sdla_te1_read_fe (void* phw, ...); static int __sdla_shark_te1_write_fe(void *phw, ...); int sdla_shark_te1_write_fe(void *phw, ...); u_int8_t __sdla_shark_te1_read_fe (void *phw, ...); u_int8_t sdla_shark_te1_read_fe (void *phw, ...); static int __sdla_shark_rm_write_fe (void* phw, ...); int sdla_shark_rm_write_fe (void* phw, ...); u_int8_t __sdla_shark_rm_read_fe (void* phw, ...); u_int8_t sdla_shark_rm_read_fe (void* phw, ...); void sdla_a200_reset_fe (void* fe); static int __sdla_shark_56k_write_fe(void *phw, ...); int sdla_shark_56k_write_fe(void *phw, ...); u_int8_t __sdla_shark_56k_read_fe (void *phw, ...); u_int8_t sdla_shark_56k_read_fe (void *phw, ...); static int __write_bri_fe_byte(void*,u_int8_t,u_int8_t,u_int8_t); int sdla_shark_bri_write_fe (void* phw, ...); static u_int8_t __read_bri_fe_byte(void*,u_int8_t,u_int8_t,u_int8_t,u_int8_t); u_int8_t sdla_shark_bri_read_fe (void* phw, ...); static int __sdla_shark_serial_write_fe(void *phw, ...); int sdla_shark_serial_write_fe(void *phw, ...); u_int32_t __sdla_shark_serial_read_fe (void *phw, ...); u_int32_t sdla_shark_serial_read_fe (void *phw, ...); int sdla_te3_write_fe(void *phw, ...); u_int8_t sdla_te3_read_fe(void *phw, ...); static int __sdla_a600_write_fe(void *phw, ...); int sdla_a600_write_fe(void *phw, ...); u_int8_t __sdla_a600_read_fe (void *phw, ...); u_int8_t sdla_a600_read_fe (void *phw, ...); void sdla_a600_reset_fe (void *fe); void sdla_a700_reset_fe (void *fe); extern int sdla_bus_write_1(void* phw, unsigned int offset, u8 value); extern int sdla_bus_read_1(void* phw, unsigned int offset, u8* value); extern int sdla_bus_write_2(void* phw, unsigned int offset, u16 value); extern int sdla_bus_read_2(void* phw, unsigned int offset, u16* value); extern int sdla_bus_write_4(void* phw, unsigned int offset, u32 value); extern int sdla_bus_read_4(void* phw, unsigned int offset, u32* value); extern int sdla_hw_fe_test_and_set_bit(void *phw, int value); extern int sdla_hw_fe_test_bit(void *phw, int value); extern int sdla_hw_fe_clear_bit(void *phw, int value); extern int sdla_hw_fe_set_bit(void *phw, int value); #define SDLA_HW_T1E1_FE_ACCESS_BLOCK { u32 breg; sdla_bus_read_4(hw, 0x40, &breg); \ if (breg == (u32)-1) { \ if (WAN_NET_RATELIMIT()) { \ DEBUG_ERROR("%s:%d: wanpipe PCI Error: Illegal Register read: 0x40 = 0xFFFFFFFF\n", \ __FUNCTION__,__LINE__); \ } \ } \ } #define SDLA_HW_T1E1_FE_ACCESS_BLOCK_A600 { u32 breg; sdla_bus_read_4(hw, 0x1040, &breg); \ if (breg == (u32)-1) { \ if (WAN_NET_RATELIMIT()) { \ DEBUG_ERROR("%s:%d: wanpipe PCI Error: Illegal Register read: 0x1040 = 0xFFFFFFFF\n", \ __FUNCTION__,__LINE__); \ } \ } \ } /*************************************************************************** **** G L O B A L D A T A **** ***************************************************************************/ /*************************************************************************** **** F U N C T I O N D E F I N I T I O N **** ***************************************************************************/ /*************************************************************************** Front End DS31/E3 interface ***************************************************************************/ int sdla_te3_write_fe(void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int off, value; WAN_ASSERT(phw == NULL); va_start(args, phw); off = va_arg(args, int); value = va_arg(args, int); va_end(args); off &= ~AFT_BIT_DEV_ADDR_CLEAR; DEBUG_TEST("%s: WRITE FRAMER OFFSET=0x%02X DATA=0x%02X\n", hw->devname, off,value); sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16)off); sdla_bus_write_2(hw, AFT_MCPU_INTERFACE, (u16)value); return 0; } u_int8_t sdla_te3_read_fe(void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int off; u_int8_t value; WAN_ASSERT(phw == NULL); va_start(args, phw); off = va_arg(args, int); va_end(args); off &= ~AFT_BIT_DEV_ADDR_CLEAR; sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16)off); sdla_bus_read_1(hw,AFT_MCPU_INTERFACE, &value); DEBUG_TEST("%s: READ FRAMER OFFSET=0x%02X DATA=0x%02X\n", hw->devname, off, value); return value; } /*************************************************************************** ** Front End T1/E1 interface for S-Series cards ***************************************************************************/ typedef struct { unsigned short register_number; unsigned char register_value; } sdla_legacy_fe_t; wan_mbox_t wan_legacy_mbox; static int sdla_legacy_fe_error (sdlahw_t *hw, int err, u_int8_t cmd) { switch (err) { case WAN_CMD_TIMEOUT: DEBUG_EVENT("%s: command 0x%02X timed out!\n", hw->devname, cmd); break; default: DEBUG_EVENT("%s: command 0x%02X returned 0x%02X!\n", hw->devname, cmd, err); } return 0; } u_int8_t sdla_legacy_read_fe (void *phw, ...) { va_list args; sdlahw_t *hw = (sdlahw_t*)phw; wan_mbox_t *mb = &wan_legacy_mbox; char *data = mb->wan_data; int qaccess, reg, line_no; int err; va_start(args, phw); qaccess = va_arg(args, int); line_no = va_arg(args, int); reg = va_arg(args, int); va_end(args); ((sdla_legacy_fe_t*)data)->register_number = (unsigned short)reg; mb->wan_data_len = sizeof(sdla_legacy_fe_t); mb->wan_command = 0x90; /* Mailbox address 0xE000 */ err = sdla_cmd(hw, 0xE000, mb); if (err){ sdla_legacy_fe_error(hw,err,0x90); } return(((sdla_legacy_fe_t*)data)->register_value); } /*============================================================================ * Write to TE1/56K Front end registers */ int sdla_legacy_write_fe (void *phw, ...) { va_list args; sdlahw_t *hw = (sdlahw_t*)phw; wan_mbox_t *mb = &wan_legacy_mbox; char *data = mb->wan_data; int qaccess, reg, line_no, value; int err, retry=15; va_start(args, phw); qaccess = va_arg(args, int); line_no = va_arg(args, int); reg = va_arg(args, int); value = va_arg(args, int); va_end(args); do { ((sdla_legacy_fe_t*)data)->register_number = (unsigned short)reg; ((sdla_legacy_fe_t*)data)->register_value = (unsigned char)value; mb->wan_data_len = sizeof(sdla_legacy_fe_t); mb->wan_command = 0x91; err = sdla_cmd(hw, 0xE000, mb); if (err){ sdla_legacy_fe_error(hw,err,0x91); } }while(err && --retry); return err; } /*************************************************************************** Front End T1/E1 interface for Normal cards ***************************************************************************/ int sdla_te1_write_fe(void* phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int qaccess, off, line_no, value; // u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; va_start(args, phw); qaccess = va_arg(args, int); line_no = va_arg(args, int); off = va_arg(args, int); value = va_arg(args, int); va_end(args); SDLA_HW_T1E1_FE_ACCESS_BLOCK; off &= ~BIT_DEV_ADDR_CLEAR; sdla_bus_write_2(hw, XILINX_MCPU_INTERFACE_ADDR, (u16)off); /* AF: Sep 10, 2003 * IMPORTANT * This delays are required to avoid bridge optimization * (combining two writes together) */ SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_write_1(hw, XILINX_MCPU_INTERFACE, (u8)value); SDLA_HW_T1E1_FE_ACCESS_BLOCK; return 0; } /*============================================================================ * Read TE1/56K Front end registers */ u_int8_t sdla_te1_read_fe (void* phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int qaccess, line_no, off; u_int8_t tmp; // u8 qaccess = card->wandev.state == WAN_CONNECTED ? 1 : 0; va_start(args, phw); qaccess = va_arg(args, int); line_no = va_arg(args, int); off = va_arg(args, int); va_end(args); SDLA_HW_T1E1_FE_ACCESS_BLOCK; off &= ~BIT_DEV_ADDR_CLEAR; sdla_bus_write_2(hw, XILINX_MCPU_INTERFACE_ADDR, (u16)off); SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_read_1(hw,XILINX_MCPU_INTERFACE, &tmp); SDLA_HW_T1E1_FE_ACCESS_BLOCK; return tmp; } /*************************************************************************** Front End T1/E1 interface for Shark subtype cards ***************************************************************************/ static int __sdla_shark_te1_write_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_cpu_t *hwcpu; sdlahw_card_t *hwcard; va_list args; int org_off=0, qaccess=0, line_no=0, off=0, value=0; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); hwcpu = hw->hwcpu; hwcard = hwcpu->hwcard; va_start(args, phw); qaccess = (u_int16_t)va_arg(args, int); line_no = (u_int16_t)va_arg(args, int); off = (u_int16_t)va_arg(args, int); value = (u_int8_t)va_arg(args, int); va_end(args); WAN_ASSERT(qaccess != 0 && qaccess != 1); if (hwcard->core_id == AFT_PMC_FE_CORE_ID){ off &= ~AFT4_BIT_DEV_ADDR_CLEAR; }else if (hwcard->core_id == AFT_DS_FE_CORE_ID){ if (off & 0x800) off |= 0x2000; if (off & 0x1000) off |= 0x4000; off &= ~AFT8_BIT_DEV_ADDR_CLEAR; if ((hwcard->adptr_type == A101_ADPTR_2TE1 || hwcard->adptr_type == A101_ADPTR_1TE1) && line_no == 1){ off |= AFT8_BIT_DEV_MAXIM_ADDR_CPLD; } } SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16*)&org_off); SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_write_2(hw,AFT_MCPU_INTERFACE_ADDR, (u16)off); /* AF: Sep 10, 2003 * IMPORTANT * This delays are required to avoid bridge optimization * (combining two writes together) */ SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_write_1(hw, AFT_MCPU_INTERFACE, (u8)value); SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16)org_off); SDLA_HW_T1E1_FE_ACCESS_BLOCK; return 0; } int sdla_shark_te1_write_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int qaccess=0, line_no=0, off=0, value=0; WAN_ASSERT(hw->magic != SDLADRV_MAGIC); if (sdla_hw_fe_test_and_set_bit(hw,0)){ if (WAN_NET_RATELIMIT()){ DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); } return -EINVAL; } va_start(args, phw); qaccess = va_arg(args, int); line_no = va_arg(args, int); off = va_arg(args, int); value = va_arg(args, int); va_end(args); DEBUG_REG("%s: Writting T1/E1 Reg: Line:%d: %02X=%02X\n", hw->devname, line_no, off, value); __sdla_shark_te1_write_fe(hw, qaccess, line_no, off, value); sdla_hw_fe_clear_bit(hw,0); return 0; } /*============================================================================ * Read TE1 Front end registers */ u_int8_t __sdla_shark_te1_read_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_cpu_t *hwcpu; sdlahw_card_t *hwcard; va_list args; int org_off=0, qaccess=0, line_no=0, off=0, tmp=0; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); hwcpu = hw->hwcpu; hwcard = hwcpu->hwcard; va_start(args, phw); qaccess = (u_int16_t)va_arg(args, int); line_no = (u_int16_t)va_arg(args, int); off = (u_int16_t)va_arg(args, int); va_end(args); WAN_ASSERT(qaccess != 0 && qaccess != 1); if (hwcard->core_id == AFT_PMC_FE_CORE_ID){ off &= ~AFT4_BIT_DEV_ADDR_CLEAR; }else if (hwcard->core_id == AFT_DS_FE_CORE_ID){ if (off & 0x800) off |= 0x2000; if (off & 0x1000) off |= 0x4000; off &= ~AFT8_BIT_DEV_ADDR_CLEAR; if ((hwcard->adptr_type == A101_ADPTR_1TE1 || hwcard->adptr_type == A101_ADPTR_2TE1) && line_no == 1){ off |= AFT8_BIT_DEV_MAXIM_ADDR_CPLD; } } SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_read_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16*)&org_off); SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16)off); SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_read_1(hw,AFT_MCPU_INTERFACE, (u8*)&tmp); SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_write_2(hw, AFT_MCPU_INTERFACE_ADDR, (u16)org_off); SDLA_HW_T1E1_FE_ACCESS_BLOCK; return (u8)tmp; } u_int8_t sdla_shark_te1_read_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int qaccess=0, line_no=0, off=0; u_int8_t tmp; WAN_ASSERT(hw->magic != SDLADRV_MAGIC); if (sdla_hw_fe_test_and_set_bit(hw,0)){ if (WAN_NET_RATELIMIT()){ DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); } return 0x00; } va_start(args, phw); qaccess = va_arg(args, int); line_no = va_arg(args, int); off = va_arg(args, int); va_end(args); tmp = __sdla_shark_te1_read_fe(hw, qaccess, line_no, off); sdla_hw_fe_clear_bit(hw,0); DEBUG_REG("%s: Reading T1/E1 Reg: Line:%d: %02X=%02X\n", hw->devname, line_no, off, tmp); return tmp; } /*************************************************************************** 56K Front End interface for Shark subtype cards ***************************************************************************/ /*============================================================================ * Write 56k Front end registers */ static int __sdla_shark_56k_write_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int qaccess, line_no, off, value; va_start(args, phw); qaccess = va_arg(args, int); line_no = va_arg(args, int); off = va_arg(args, int); value = va_arg(args, int); va_end(args); off &= ~AFT8_BIT_DEV_ADDR_CLEAR; SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_write_2(hw,0x46, (u16)off); SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_write_2(hw,0x44, (u16)value); SDLA_HW_T1E1_FE_ACCESS_BLOCK; return 0; } int sdla_shark_56k_write_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int qaccess, line_no, off, value; WAN_ASSERT(hw->magic != SDLADRV_MAGIC); if (sdla_hw_fe_test_and_set_bit(hw,0)){ if (WAN_NET_RATELIMIT()){ DEBUG_EVENT( "%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); } return -EINVAL; } va_start(args, phw); qaccess = va_arg(args, int); line_no = va_arg(args, int); off = va_arg(args, int); value = va_arg(args, int); va_end(args); __sdla_shark_56k_write_fe(hw, qaccess, line_no, off, value); sdla_hw_fe_clear_bit(hw,0); return 0; } /*============================================================================ * Read 56k Front end registers */ u_int8_t __sdla_shark_56k_read_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int qaccess, line_no, off, tmp; va_start(args, phw); qaccess = va_arg(args, int); line_no = va_arg(args, int); off = va_arg(args, int); va_end(args); off &= ~AFT8_BIT_DEV_ADDR_CLEAR; SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_write_2(hw, AFT56K_MCPU_INTERFACE_ADDR, (u16)off); SDLA_HW_T1E1_FE_ACCESS_BLOCK; sdla_bus_read_4(hw, AFT56K_MCPU_INTERFACE, &tmp); SDLA_HW_T1E1_FE_ACCESS_BLOCK; return (u_int8_t)tmp; } u_int8_t sdla_shark_56k_read_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int qaccess, line_no, off, tmp; WAN_ASSERT(hw->magic != SDLADRV_MAGIC); if (sdla_hw_fe_test_and_set_bit(hw,0)){ if (WAN_NET_RATELIMIT()){ DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); } return 0x00; } va_start(args, phw); qaccess = va_arg(args, int); line_no = va_arg(args, int); off = va_arg(args, int); va_end(args); tmp = __sdla_shark_56k_read_fe(hw, qaccess, line_no, off); sdla_hw_fe_clear_bit(hw,0); return (u8)tmp; } static int __sdla_a600_write_fe(void *phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain; int reg, value; u32 data = 0; //unsigned char cs = 0x00, ctrl_byte = 0x00; int i; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); value = va_arg(args, int); va_end(args); if (chain) DEBUG_ERROR ("%s :%d Error: chain mode not supported on A600 (%s:%d)\n", hw->devname, mod_no, __FUNCTION__,__LINE__); if (type == MOD_TYPE_FXO){ data |= (mod_no & 0x3) << 24; data &= 0xFF000000; /* Clear data bits */ data |= (value & 0xFF); reg = reg & 0x7F; data |= (reg & 0xFF) << 8; }else if (type == MOD_TYPE_FXS){ wan_set_bit(A600_SPI_REG_CHAN_TYPE_FXS_BIT, &data); /* 1 << 28 */ /* Clear data bits */ data |= (value & 0xFF); reg = reg & 0x7F; data |= (reg & 0xFF) << 8; }else{ DEBUG_EVENT("%s: Module %d: Unsupported module type %d!\n", hw->devname, mod_no, type); return -EINVAL; } sdla_bus_write_4(hw, A600_REG_OFF(SPI_INTERFACE_REG), data); WP_DELAY(10); wan_set_bit(A600_SPI_REG_START_BIT, &data); sdla_bus_write_4(hw, A600_REG_OFF(SPI_INTERFACE_REG), data); for (i=0;i<10;i++) { WP_DELAY(10); sdla_bus_read_4(hw, A600_REG_OFF(SPI_INTERFACE_REG),&data); if (!(wan_test_bit(A600_SPI_REG_SPI_BUSY_BIT, &data))) { goto spi_write_done; } } if (wan_test_bit(A600_SPI_REG_SPI_BUSY_BIT, &data)) { DEBUG_ERROR("%s: ERROR:SPI Iface not ready\n", hw->devname); return -EINVAL; } spi_write_done: return 0; } int sdla_a600_write_fe(void *phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg, value; #if defined(WAN_DEBUG_FE) char *fname; int fline; #endif WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); value = va_arg(args, int); va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); return -EINVAL; } __sdla_a600_write_fe(hw, mod_no, type, chain, reg, value); sdla_hw_fe_clear_bit(hw,0); return 0; } u_int8_t __sdla_a600_read_fe (void *phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg; u32 data = 0; int i; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); va_end(args); if (chain) DEBUG_ERROR ("%s :%d Error: chain mode not supported on A600 (%s:%d)\n", hw->devname, mod_no, __FUNCTION__,__LINE__); wan_set_bit(A600_SPI_REG_READ_ENABLE_BIT, &data); if (type == MOD_TYPE_FXO){ data |= (mod_no & 0x3) << 24; data &= 0xFF000000; reg = reg & 0xFF; data |= (reg & 0xFF) << 8; data &= 0xFFFFFF00; }else if (type == MOD_TYPE_FXS){ wan_set_bit(A600_SPI_REG_CHAN_TYPE_FXS_BIT, &data); reg = reg & 0x7F; data |= (reg & 0xFF) << 8; data &= 0xFFFFFF00; } else { DEBUG_EVENT("%s: Module %d: Unsupported module type %d!\n", hw->devname, mod_no, type); return 0xFF; } sdla_bus_write_4(hw, A600_REG_OFF(SPI_INTERFACE_REG), data); WP_DELAY(10); wan_set_bit(A600_SPI_REG_START_BIT, &data); sdla_bus_write_4(hw, A600_REG_OFF(SPI_INTERFACE_REG), data); for (i=0;i<10;i++) { WP_DELAY(10); sdla_bus_read_4(hw, A600_REG_OFF(SPI_INTERFACE_REG),&data); if (!(wan_test_bit(A600_SPI_REG_SPI_BUSY_BIT, &data))) { goto spi_read_done; } } spi_read_done: if (wan_test_bit(A600_SPI_REG_SPI_BUSY_BIT, &data)) { DEBUG_ERROR("%s: ERROR:SPI Iface not ready\n", hw->devname); data = 0xFF; } return (u8) data; } u_int8_t sdla_a600_read_fe (void *phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg; unsigned char data = 0; WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); return 0x00; } data = __sdla_a600_read_fe (hw, mod_no, type, chain, reg); sdla_hw_fe_clear_bit(hw,0); return data; } /*************************************************************************** Front End FXS/FXO interface for A700 ***************************************************************************/ static int __sdla_a700_analog_write_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain; int reg, value; u32 data = 0; unsigned char cs = 0x00, ctrl_byte = 0x00; int i; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); value = va_arg(args, int); va_end(args); #if 0 if (!wan_test_bit(mod_no, card->fe.fe_param.remora.module_map)){ DEBUG_ERROR("%s: %s:%d: Internal Error: Module %d\n", card->devname, __FUNCTION__,__LINE__,mod_no); return -EINVAL; } #endif if(0)DEBUG_RM("%s:%d: Module %d: Write RM FE code (reg %d, value %02X)!\n", __FUNCTION__,__LINE__, /*FIXME: hw->devname,*/mod_no, reg, (u8)value); mod_no+=4; /* bit 0-7: data byte */ data = value & 0xFF; if (type == MOD_TYPE_FXO){ /* bit 8-15: register number */ data |= (reg & 0xFF) << 8; /* bit 16-23: chip select byte */ cs = 0x20; cs |= MOD_SPI_CS_FXO_WRITE; if (mod_no % 2 == 1){ /* Select second chip in a chain */ cs |= MOD_SPI_CS_FXO_CHIP_1; } data |= (cs & 0xFF) << 16; /* bit 24-31: ctrl byte */ ctrl_byte = mod_no / 2; ctrl_byte |= MOD_SPI_CTRL_CHAIN; /* always chain */ data |= ctrl_byte << 24; }else if (type == MOD_TYPE_FXS){ /* bit 8-15: register byte */ reg = reg & 0x7F; reg |= MOD_SPI_ADDR_FXS_WRITE; data |= (reg & 0xFF) << 8; /* bit 16-23: chip select byte */ if (mod_no % 2 == 0){ /* Select first chip in a chain */ cs = A700_ANALOG_SPI_CS_FXS_CHIP_0; }else { /* Select second chip in a chain */ cs = A700_ANALOG_SPI_CS_FXS_CHIP_1; } data |= cs << 16; /* bit 24-31: ctrl byte */ ctrl_byte = mod_no / 2; ctrl_byte |= MOD_SPI_CTRL_FXS; if (chain){ ctrl_byte |= MOD_SPI_CTRL_CHAIN; } data |= ctrl_byte << 24; }else{ DEBUG_EVENT("%s: Module %d: Unsupported module type %d!\n", hw->devname, mod_no, type); return -EINVAL; } sdla_bus_write_4(hw, A700_ANALOG_SPI_INTERFACE_REG, data); WP_DELAY(10); data |= A700_ANALOG_SPI_MOD_START_BIT; sdla_bus_write_4(hw, A700_ANALOG_SPI_INTERFACE_REG, data); for (i=0;i<10;i++){ WP_DELAY(10); sdla_bus_read_4(hw, A700_ANALOG_SPI_INTERFACE_REG, &data); if (data & MOD_SPI_BUSY){ continue; } } if (data & MOD_SPI_BUSY) { DEBUG_ERROR("%s: Module %d: Critical Error (%s:%d)!\n", hw->devname, mod_no, __FUNCTION__,__LINE__); return -EINVAL; } return 0; } int sdla_a700_analog_write_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg, value; #if defined(WAN_DEBUG_FE) char *fname; int fline; #endif WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); value = va_arg(args, int); #if defined(WAN_DEBUG_FE) fname = va_arg(args, char*); fline = va_arg(args, int); #endif va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ #if defined(WAN_DEBUG_FE) DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", hw->devname, __FUNCTION__,__LINE__, fname, fline); #else DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); #endif return -EINVAL; } DEBUG_REG("%s: Remora Direct Register %d = %02X\n", hw->devname, reg, value); __sdla_a700_analog_write_fe(hw, (mod_no-4), type, chain, reg, value); sdla_hw_fe_clear_bit(hw,0); return 0; } u_int8_t __sdla_a700_analog_read_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg; u32 data = 0; unsigned char cs = 0x00, ctrl_byte = 0x00; int i; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); va_end(args); if(0)DEBUG_RM("%s:%d: Module %d: Read RM FE code (reg %d)!\n", __FUNCTION__,__LINE__, /*FIXME: hw->devname, */mod_no, reg); mod_no+=4; /* bit 0-7: data byte */ data = 0x00; if (type == MOD_TYPE_FXO){ /* bit 8-15: register byte */ data |= (reg & 0xFF) << 8; /* bit 16-23: chip select byte */ cs = 0x20; cs |= MOD_SPI_CS_FXO_READ; if (mod_no % 2 == 1) { /* Select second chip in a chain */ cs |= MOD_SPI_CS_FXO_CHIP_1; } data |= (cs & 0xFF) << 16; /* bit 24-31: ctrl byte */ ctrl_byte = mod_no / 2; ctrl_byte |= MOD_SPI_CTRL_CHAIN; /* always chain */ data |= ctrl_byte << 24; }else if (type == MOD_TYPE_FXS){ /* bit 8-15: register byte */ reg = reg & 0x7F; reg |= MOD_SPI_ADDR_FXS_READ; data |= (reg & 0xFF) << 8; /* bit 16-23: chip select byte */ if (mod_no % 2 == 0){ /* Select first chip in a chain */ cs = A700_ANALOG_SPI_CS_FXS_CHIP_0; }else{ /* Select second chip in a chain */ cs = A700_ANALOG_SPI_CS_FXS_CHIP_1; } data |= cs << 16; /* bit 24-31: ctrl byte */ ctrl_byte = mod_no / 2; ctrl_byte |= MOD_SPI_CTRL_FXS; if (chain){ ctrl_byte |= MOD_SPI_CTRL_CHAIN; } else { } data |= ctrl_byte << 24; }else{ DEBUG_EVENT("%s: Module %d: Unsupported module type %d!\n", hw->devname, mod_no, type); return -EINVAL; } sdla_bus_write_4(hw, A700_ANALOG_SPI_INTERFACE_REG, data); WP_DELAY(10); data |= A700_ANALOG_SPI_MOD_START_BIT; sdla_bus_write_4(hw, A700_ANALOG_SPI_INTERFACE_REG, data); for (i=0;i<10;i++){ WP_DELAY(10); sdla_bus_read_4(hw, A700_ANALOG_SPI_INTERFACE_REG, &data); if (data & MOD_SPI_BUSY) { continue; } } if (data & MOD_SPI_BUSY){ DEBUG_ERROR("%s: Module %d: Critical Error (%s:%d)!\n", hw->devname, mod_no, __FUNCTION__,__LINE__); return 0xFF; } return (u8)(data & 0xFF); } u_int8_t sdla_a700_analog_read_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg; unsigned char data = 0; #if defined(WAN_DEBUG_FE) char *fname; int fline; #endif WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); #if defined(WAN_DEBUG_FE) fname = va_arg(args, char*); fline = va_arg(args, int); #endif va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ #if defined(WAN_DEBUG_FE) DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", hw->devname, __FUNCTION__,__LINE__,fname,fline); #else DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); #endif return 0x00; } data = __sdla_a700_analog_read_fe (hw, (mod_no-4), type, chain, reg); sdla_hw_fe_clear_bit(hw,0); return data; } /*************************************************************************** Front End FXS/FXO interface for Shark subtype cards ***************************************************************************/ void sdla_a700_reset_fe (void *fe) { sdla_t *card; WAN_ASSERT1(fe == NULL); card = (sdla_t*)((sdla_fe_t*)fe)->card; WAN_ASSERT1(card == NULL); card->hw_iface.bus_write_4(card->hw, A700_ANALOG_SPI_INTERFACE_REG, MOD_SPI_RESET); WP_DELAY(1000); card->hw_iface.bus_write_4(card->hw, A700_ANALOG_SPI_INTERFACE_REG, 0x00000000); WP_DELAY(1000); } void sdla_a600_reset_fe (void *fe) { u32 reg; sdla_t *card; WAN_ASSERT1(fe == NULL); card = (sdla_t*)((sdla_fe_t*)fe)->card; WAN_ASSERT1(card == NULL); DEBUG_RM("%s: Resetting SPI\n", ((sdla_fe_t*)fe)->name); /* Reset FXO */ reg = 0x00; /* set reset */ wan_set_bit(A600_SPI_REG_FX0_RESET_BIT, ®); card->hw_iface.bus_write_4(card->hw, A600_REG_OFF(SPI_INTERFACE_REG), reg); WP_DELAY(1000); /* clear reset */ wan_clear_bit(A600_SPI_REG_FX0_RESET_BIT, ®); card->hw_iface.bus_write_4(card->hw, A600_REG_OFF(SPI_INTERFACE_REG), reg); WP_DELAY(1000); /* Reset FXS */ reg = 0x00; wan_set_bit(A600_SPI_REG_FXS_RESET_BIT, ®); card->hw_iface.bus_write_4(card->hw, A600_REG_OFF(SPI_INTERFACE_REG), reg); WP_DELAY(1000); /* clear reset */ wan_clear_bit(A600_SPI_REG_FXS_RESET_BIT, ®); card->hw_iface.bus_write_4(card->hw, A600_REG_OFF(SPI_INTERFACE_REG), reg); WP_DELAY(1000); } void sdla_b800_reset_module(sdla_t *card, int mod_no) { u32 reg; u8 remora_no, module_no; remora_no = mod_no/4; module_no = mod_no%4; reg = 0x00; reg |= (module_no & 0x3) << 24; reg |= (remora_no & 0x3) << 26; reg |= 1<< B800_SPI_REG_RESET_BIT; card->hw_iface.bus_write_4(card->hw, SPI_INTERFACE_REG, reg); WP_DELAY(1000); card->hw_iface.bus_write_4(card->hw, SPI_INTERFACE_REG, 0x00000000); WP_DELAY(1000); } void sdla_b800_reset_fe (void *fe) { int i; sdla_t *card; WAN_ASSERT1(fe == NULL); card = (sdla_t*)((sdla_fe_t*)fe)->card; WAN_ASSERT1(card == NULL); /* reset all modules together for now until we have the ability/need reset 1 module at a time from driver core */ for (i=0;icard; WAN_ASSERT1(card == NULL); card->hw_iface.bus_write_4(card->hw, SPI_INTERFACE_REG, MOD_SPI_RESET); WP_DELAY(1000); card->hw_iface.bus_write_4(card->hw, SPI_INTERFACE_REG, 0x00000000); WP_DELAY(1000); } /*============================================================================ * Read TE1/56K Front end registers */ static int __sdla_b800_write_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain; u8 module_no, remora_no; int reg, value; u32 data = 0; //unsigned char cs = 0x00, ctrl_byte = 0x00; int i; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); value = va_arg(args, int); va_end(args); if (chain) DEBUG_ERROR ("%s :%d Error: chain mode not supported on A600 (%s:%d)\n", hw->devname, mod_no, __FUNCTION__,__LINE__); remora_no = mod_no/4; module_no = mod_no%4; data |= (module_no & 0x3) << 24; data |= (remora_no & 0x3) << 26; data &= 0xFF000000; if (type == MOD_TYPE_FXO) { /* Clear data bits */ data |= (value & 0xFF); data |= (reg & 0xFF) << 8; } else if (type == MOD_TYPE_FXS) { wan_set_bit(B800_SPI_REG_CHAN_TYPE_FXS_BIT, &data); /* Clear data bits */ data |= (value & 0xFF); data |= (reg & 0x7F) << 8; } else { DEBUG_EVENT("%s: Module %d: Unsupported module type %d!\n", hw->devname, mod_no, type); return -EINVAL; } sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); WP_DELAY(10); wan_set_bit(B800_SPI_REG_START_BIT, &data); sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); for (i=0;i<10;i++) { WP_DELAY(10); sdla_bus_read_4(hw, SPI_INTERFACE_REG,&data); if (!(wan_test_bit(B800_SPI_REG_SPI_BUSY_BIT, &data))) { goto spi_write_done; } } if (wan_test_bit(B800_SPI_REG_SPI_BUSY_BIT, &data)) { DEBUG_ERROR("%s: ERROR:SPI Iface not ready\n", hw->devname); return -EINVAL; } spi_write_done: return 0; } int sdla_b800_write_fe(void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg, value; #if defined(WAN_DEBUG_FE) char *fname; int fline; #endif WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); value = va_arg(args, int); #if defined(WAN_DEBUG_FE) fname = va_arg(args, char*); fline = va_arg(args, int); #endif va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ #if defined(WAN_DEBUG_FE) DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", hw->devname, __FUNCTION__,__LINE__, fname, fline); #else DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); #endif return -EINVAL; } DEBUG_REG("%s: Remora Direct Register %d = %02X\n", hw->devname, reg, value); __sdla_b800_write_fe(hw, mod_no, type, chain, reg, value); sdla_hw_fe_clear_bit(hw,0); return 0; } static int __sdla_shark_rm_write_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain; int reg, value; u32 data = 0; unsigned char cs = 0x00, ctrl_byte = 0x00; int i; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); value = va_arg(args, int); va_end(args); #if 0 if (!wan_test_bit(mod_no, card->fe.fe_param.remora.module_map)){ DEBUG_ERROR("%s: %s:%d: Internal Error: Module %d\n", card->devname, __FUNCTION__,__LINE__,mod_no); return -EINVAL; } #endif if(0)DEBUG_RM("%s:%d: Module %d: Write RM FE code (reg %d, value %02X)!\n", __FUNCTION__,__LINE__, /*FIXME: hw->devname,*/mod_no, reg, (u8)value); /* bit 0-7: data byte */ data = value & 0xFF; if (type == MOD_TYPE_FXO){ /* bit 8-15: register number */ data |= (reg & 0xFF) << 8; /* bit 16-23: chip select byte ** bit 16 ** ** ** */ cs = 0x20; cs |= MOD_SPI_CS_FXO_WRITE; if (mod_no % 2 == 0){ /* Select second chip in a chain */ cs |= MOD_SPI_CS_FXO_CHIP_1; } data |= (cs & 0xFF) << 16; /* bit 24-31: ctrl byte ** bit 24 ** ** ** */ ctrl_byte = mod_no / 2; #if !defined(SPI2STEP) if (hw->hwcpu->hwcard->core_rev > 3){ ctrl_byte |= MOD_SPI_CTRL_START; }else{ ctrl_byte |= MOD_SPI_CTRL_V3_START; } #endif ctrl_byte |= MOD_SPI_CTRL_CHAIN; /* always chain */ data |= ctrl_byte << 24; }else if (type == MOD_TYPE_FXS){ /* bit 8-15: register byte */ reg = reg & 0x7F; reg |= MOD_SPI_ADDR_FXS_WRITE; data |= (reg & 0xFF) << 8; /* bit 16-23: chip select byte ** bit 16 ** ** ** */ if (mod_no % 2){ /* Select first chip in a chain */ cs = MOD_SPI_CS_FXS_CHIP_0; }else{ /* Select second chip in a chain */ cs = MOD_SPI_CS_FXS_CHIP_1; } data |= cs << 16; /* bit 24-31: ctrl byte ** bit 24 ** ** ** */ ctrl_byte = mod_no / 2; #if !defined(SPI2STEP) if (hw->hwcpu->hwcard->core_rev > 3){ ctrl_byte |= MOD_SPI_CTRL_START; }else{ ctrl_byte |= MOD_SPI_CTRL_V3_START; } #endif ctrl_byte |= MOD_SPI_CTRL_FXS; if (chain){ ctrl_byte |= MOD_SPI_CTRL_CHAIN; } data |= ctrl_byte << 24; }else{ DEBUG_EVENT("%s: Module %d: Unsupported module type %d!\n", hw->devname, mod_no, type); return -EINVAL; } sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); #if defined(SPI2STEP) WP_DELAY(1); if (hw->hwcpu->hwcard->core_rev > 3){ data |= MOD_SPI_START; }else{ data |= MOD_SPI_V3_START; } sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); #endif #if 0 DEBUG_EVENT("%s: %s: Module %d - Execute SPI command %08X\n", card->fe.name, __FUNCTION__, mod_no, data); #endif for (i=0;i<10;i++){ WP_DELAY(10); sdla_bus_read_4(hw, SPI_INTERFACE_REG, &data); if (data & MOD_SPI_BUSY){ continue; } } if (data & MOD_SPI_BUSY) { DEBUG_ERROR("%s: Module %d: Critical Error (%s:%d)!\n", hw->devname, mod_no, __FUNCTION__,__LINE__); return -EINVAL; } return 0; } int sdla_shark_rm_write_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg, value; #if defined(WAN_DEBUG_FE) char *fname; int fline; #endif WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); value = va_arg(args, int); #if defined(WAN_DEBUG_FE) fname = va_arg(args, char*); fline = va_arg(args, int); #endif va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ #if defined(WAN_DEBUG_FE) DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", hw->devname, __FUNCTION__,__LINE__, fname, fline); #else DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); #endif return -EINVAL; } DEBUG_REG("%s: Remora Direct Register %d = %02X\n", hw->devname, reg, value); __sdla_shark_rm_write_fe(hw, mod_no, type, chain, reg, value); sdla_hw_fe_clear_bit(hw,0); return 0; } u_int8_t __sdla_b800_read_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg; u8 module_no, remora_no; u32 data = 0; int i; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); va_end(args); remora_no = mod_no/4; module_no = mod_no%4; if (chain) { DEBUG_ERROR ("%s :%d Error: chain mode not supported on B800 (%s:%d)\n", hw->devname, mod_no, __FUNCTION__,__LINE__); WARN_ON(1); } wan_set_bit(B800_SPI_REG_READ_ENABLE_BIT, &data); data |= (module_no & 0x3) << 24; data |= (remora_no & 0x3) << 26; data &= 0xFF000000; if (type == MOD_TYPE_FXO) { data |= (reg & 0xFF) << 8; data &= 0xFFFFFF00; } else if (type == MOD_TYPE_FXS) { wan_set_bit(B800_SPI_REG_CHAN_TYPE_FXS_BIT, &data); data |= (reg & 0x7F) << 8; data &= 0xFFFFFF00; } else { DEBUG_EVENT("%s: Module %d: Unsupported module type %d!\n", hw->devname, mod_no, type); return 0xFF; } sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); WP_DELAY(10); wan_set_bit(B800_SPI_REG_START_BIT, &data); sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); for (i=0;i<10;i++) { WP_DELAY(10); sdla_bus_read_4(hw, SPI_INTERFACE_REG,&data); if (!(wan_test_bit(B800_SPI_REG_SPI_BUSY_BIT, &data))) { goto spi_read_done; } } spi_read_done: if (wan_test_bit(B800_SPI_REG_SPI_BUSY_BIT, &data)) { DEBUG_ERROR("%s: ERROR:SPI Iface not ready\n", hw->devname); data = 0xFF; } return (u8)(data & 0xFF); } u_int8_t sdla_b800_read_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg; unsigned char data = 0; #if defined(WAN_DEBUG_FE) char *fname; int fline; #endif WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); #if defined(WAN_DEBUG_FE) fname = va_arg(args, char*); fline = va_arg(args, int); #endif va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ #if defined(WAN_DEBUG_FE) DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", hw->devname, __FUNCTION__,__LINE__,fname,fline); #else DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); #endif return 0x00; } data = __sdla_b800_read_fe (hw, mod_no, type, chain, reg); //DEBUG_REG("%s: Remora Read Reg %X = %02X\n", // hw->devname, reg, data); sdla_hw_fe_clear_bit(hw,0); return data; } u_int8_t __sdla_shark_rm_read_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg; u32 data = 0; unsigned char cs = 0x00, ctrl_byte = 0x00; int i; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); va_end(args); #if 0 if (!wan_test_bit(mod_no, card->fe.fe_param.remora.module_map)){ DEBUG_ERROR("%s: %s:%d: Internal Error: Module %d\n", card->devname, __FUNCTION__,__LINE__,mod_no); return 0x00; } #endif if(0)DEBUG_RM("%s:%d: Module %d: Read RM FE code (reg %d)!\n", __FUNCTION__,__LINE__, /*FIXME: hw->devname, */mod_no, reg); /* bit 0-7: data byte */ data = 0x00; if (type == MOD_TYPE_FXO){ /* bit 8-15: register byte */ data |= (reg & 0xFF) << 8; /* bit 16-23: chip select byte ** bit 16 ** ** ** */ cs = 0x20; cs |= MOD_SPI_CS_FXO_READ; if (mod_no % 2 == 0){ /* Select second chip in a chain */ cs |= MOD_SPI_CS_FXO_CHIP_1; } data |= (cs & 0xFF) << 16; /* bit 24-31: ctrl byte ** bit 24 ** ** ** */ ctrl_byte = mod_no / 2; #if !defined(SPI2STEP) if (hw->hwcpu->hwcard->core_rev > 3){ ctrl_byte |= MOD_SPI_CTRL_START; }else{ ctrl_byte |= MOD_SPI_CTRL_V3_START; } #endif ctrl_byte |= MOD_SPI_CTRL_CHAIN; /* always chain */ data |= ctrl_byte << 24; }else if (type == MOD_TYPE_FXS){ /* bit 8-15: register byte */ reg = reg & 0x7F; reg |= MOD_SPI_ADDR_FXS_READ; data |= (reg & 0xFF) << 8; /* bit 16-23: chip select byte ** bit 16 ** ** ** */ if (mod_no % 2){ /* Select first chip in a chain */ cs = MOD_SPI_CS_FXS_CHIP_0; }else{ /* Select second chip in a chain */ cs = MOD_SPI_CS_FXS_CHIP_1; } data |= cs << 16; /* bit 24-31: ctrl byte ** bit 24 ** ** ** */ ctrl_byte = mod_no / 2; #if !defined(SPI2STEP) if (hw->hwcpu->hwcard->core_rev > 3){ ctrl_byte |= MOD_SPI_CTRL_START; }else{ ctrl_byte |= MOD_SPI_CTRL_V3_START; } #endif ctrl_byte |= MOD_SPI_CTRL_FXS; if (chain){ ctrl_byte |= MOD_SPI_CTRL_CHAIN; } data |= ctrl_byte << 24; }else{ DEBUG_EVENT("%s: Module %d: Unsupported module type %d!\n", hw->devname, mod_no, type); return -EINVAL; } sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); #if defined(SPI2STEP) WP_DELAY(1); if (hw->hwcpu->hwcard->core_rev > 3){ data |= MOD_SPI_START; }else{ data |= MOD_SPI_V3_START; } sdla_bus_write_4(hw, SPI_INTERFACE_REG, data); #endif #if 0 DEBUG_EVENT("%s: %s: Module %d - Execute SPI command %08X\n", hw->devname, __FUNCTION__, mod_no, data); #endif for (i=0;i<10;i++){ WP_DELAY(10); sdla_bus_read_4(hw, SPI_INTERFACE_REG, &data); if (data & MOD_SPI_BUSY) { continue; } } if (data & MOD_SPI_BUSY){ DEBUG_ERROR("%s: Module %d: Critical Error (%s:%d)!\n", hw->devname, mod_no, __FUNCTION__,__LINE__); return 0xFF; } return (u8)(data & 0xFF); } u_int8_t sdla_shark_rm_read_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg; unsigned char data = 0; #if defined(WAN_DEBUG_FE) char *fname; int fline; #endif WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); #if defined(WAN_DEBUG_FE) fname = va_arg(args, char*); fline = va_arg(args, int); #endif va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ #if defined(WAN_DEBUG_FE) DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", hw->devname, __FUNCTION__,__LINE__,fname,fline); #else DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); #endif return 0x00; } data = __sdla_shark_rm_read_fe (hw, mod_no, type, chain, reg); //DEBUG_REG("%s: Remora Read Reg %X = %02X\n", // hw->devname, reg, data); sdla_hw_fe_clear_bit(hw,0); return data; } /*************************************************************************** ISDN BRI Front End interface ***************************************************************************/ #define SPI_DELAY if(1)WP_DELAY(10) #undef SPI_MAX_RETRY_COUNT #define SPI_MAX_RETRY_COUNT 10000 #define SPI_BREAK if(1)break #define FAST_SPI 0 /*============================================================================ * Write ISDN BRI Front end registers */ static int __write_bri_fe_byte ( void* phw, u_int8_t mod_no, u_int8_t addr, u_int8_t value) { sdlahw_t *hw = (sdlahw_t*)phw; bri_reg_t data, dummy; u_int32_t *data_ptr = (u_int32_t*)&data; u_int32_t *dummy_ptr = (u_int32_t*)&dummy; u_int32_t retry_counter; u_int8_t rm_no=0xFF; WAN_ASSERT(hw == NULL); DEBUG_REG("%s():%s: mod_no:%d addr=0x%X (%d) value=0x%02X\n", __FUNCTION__, hw->devname, mod_no, addr, addr, value); /* Input mod_no is an even number between 0 and 22 (including). Calculate rm_no - should be between 0 and 3 (including). */ rm_no = mod_no / (MAX_BRI_MODULES_PER_REMORA*2); #if 0 DEBUG_BRI("%s(input): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); #endif /* Translate mod_no to be between 0 and 2 (including) */ mod_no = (mod_no / 2) % MAX_BRI_MODULES_PER_REMORA; #if 0 DEBUG_BRI("%s(updated): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); #endif if(rm_no > MAX_BRI_REMORAS - 1){ DEBUG_EVENT("%s:%s(): Line:%d: invalid rm_no: %d!!(mod_no: %d)\n", hw->devname, __FUNCTION__, __LINE__, rm_no, mod_no); return 0; } /* setup address offset for fe */ data.reset = 0; data.start = 1; data.reserv1 = 0; data.remora_addr = rm_no; data.mod_addr = mod_no; data.data = addr; data.contrl = 0; data.contrl |= ADDR_BIT; /* DEBUG_BRI("1. data: 0x%08X\n", *data_ptr); */ /* check spi not busy */ for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ sdla_bus_read_4(hw, SPI_INTERFACE_REG, dummy_ptr); if(dummy.start == 1){ SPI_DELAY; } else { SPI_BREAK; } } SPI_DELAY; if(dummy.start == 1){ DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); return 0; } sdla_bus_write_4(hw, SPI_INTERFACE_REG, *data_ptr); /* start read spi operation */ data.reset=0; data.start=1; data.reserv1=0; data.remora_addr = rm_no; data.mod_addr = mod_no; data.data = value; data.contrl = 0; /* DEBUG_BRI("2. data: 0x%08X\n", *data_ptr); */ #if FAST_SPI SPI_DELAY; #else /* wait for end of spi operation */ for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ sdla_bus_read_4(hw, SPI_INTERFACE_REG, dummy_ptr); if(dummy.start == 1){SPI_DELAY;}else{SPI_BREAK;} } SPI_DELAY; if(dummy.start == 1){ DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); return 0; } #endif /* write the actual data */ sdla_bus_write_4(hw, SPI_INTERFACE_REG, *data_ptr); return 0; } int sdla_shark_bri_write_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, reg, value; #if defined(WAN_DEBUG_FE) char *fname; int fline; #endif va_start(args, phw); mod_no = va_arg(args, int); reg = va_arg(args, int); value = va_arg(args, int); #if defined(WAN_DEBUG_FE) fname = va_arg(args, char*); fline = va_arg(args, int); #endif va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ #if defined(WAN_DEBUG_FE) DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", hw->devname, __FUNCTION__,__LINE__, fname, fline); #else DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); #endif return -EINVAL; } __write_bri_fe_byte(hw, (u8)mod_no, (u8)reg, (u8)value); sdla_hw_fe_clear_bit(hw,0); return 0; } /*============================================================================ * Read ISDN BRI Front end registers */ static u_int8_t __read_bri_fe_byte( void* phw, u_int8_t mod_no, u_int8_t reg, u_int8_t type, u_int8_t optional_arg) { sdlahw_t *hw = (sdlahw_t*)phw; bri_reg_t data, dummy; u_int32_t *data_ptr = (u_int32_t*)&data; u_int32_t *dummy_ptr = (u_int32_t*)&dummy; u_int32_t retry_counter; u_int8_t rm_no=0xFF; u_int8_t value; WAN_ASSERT(hw == NULL); DEBUG_REG("%s():%s\n", __FUNCTION__, hw->devname); if(type != MOD_TYPE_NT && type != MOD_TYPE_TE){ DEBUG_BRI("%s(): Warning: unknown module type! (%d)\n", __FUNCTION__, type); } /* setup address offset for fe */ data.reset = 0; data.start = 1; data.reserv1= 0; if(type == MOD_TYPE_NONE){ /* the only case we get here is if running module detection code. */ rm_no = optional_arg; }else{ /* Input mod_no is an even number between 0 and 22 (including). Calculate rm_no - should be between 0 and 3 (including). */ if(mod_no % 2){ DEBUG_BRI("%s(): Warning: module number (%d) is not even!!\n", __FUNCTION__, mod_no); } rm_no = mod_no / (MAX_BRI_MODULES_PER_REMORA*2); #if 0 DEBUG_BRI("%s(input): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); #endif /* Translate mod_no to be between 0 and 2 (including) */ mod_no = (mod_no / 2) % MAX_BRI_MODULES_PER_REMORA; } #if 0 DEBUG_BRI("%s(updated): rm_no: %d, mod_no: %d\n", __FUNCTION__, rm_no, mod_no); #endif if(rm_no > MAX_BRI_REMORAS - 1){ DEBUG_EVENT("%s:%s(): Line:%d: invalid rm_no: %d!!(mod_no: %d)\n", hw->devname, __FUNCTION__, __LINE__, rm_no, mod_no); return 0; } data.remora_addr = rm_no; data.mod_addr = mod_no; data.data = reg; data.contrl = 0; data.contrl |= ADDR_BIT; if(type == MOD_TYPE_NONE){ /* DavidR (April 10, 2008): for module detection set 512 khz bit */ data.contrl |= CPLD_USE_512KHZ_RECOVERY_CLOCK_BIT; } /* check spi not busy */ for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ sdla_bus_read_4(hw, SPI_INTERFACE_REG, dummy_ptr); if(dummy.start == 1){SPI_DELAY;}else{SPI_BREAK;} } if(dummy.start == 1){ DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); return 0; } /* DEBUG_BRI("1. data: 0x%08X\n", *data_ptr); */ /* setup the address */ sdla_bus_write_4(hw, SPI_INTERFACE_REG, *data_ptr); /* DEBUG_BRI("2. data: 0x%08X\n", *data_ptr); */ /* wait for end of spi operation */ #if !FAST_SPI for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ sdla_bus_read_4(hw, SPI_INTERFACE_REG, dummy_ptr); if(dummy.start == 1){SPI_DELAY;}else{SPI_BREAK;} } SPI_DELAY; if(dummy.start == 1){ DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); return 0; } #endif /* setup data for read spi operation */ data.reset=0; data.start=1; data.reserv1=0; data.remora_addr = rm_no; data.mod_addr = mod_no; data.data = 0; data.contrl = 0; data.contrl |= READ_BIT; if(type == MOD_TYPE_NONE){ /* DavidR (April 10, 2008): for module detection set 512 khz bit */ data.contrl |= CPLD_USE_512KHZ_RECOVERY_CLOCK_BIT; } DEBUG_REG("%s(Line: %i): (data: 0x%08X) reset: 0x%X, start: 0x%X, reserv1: 0x%X, remora_addr: 0x%X, mod_addr: 0x%X, data: 0x%X, contrl: 0x%X\n", __FUNCTION__, __LINE__, *((u32*)&data), data.reset, data.start, data.reserv1, data.remora_addr, data.mod_addr, data.data, data.contrl); #if FAST_SPI SPI_DELAY; #else for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ sdla_bus_read_4(hw, SPI_INTERFACE_REG, dummy_ptr); if(dummy.start == 1){SPI_DELAY;}else{SPI_BREAK;} } SPI_DELAY; if(dummy.start == 1){ DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); return 0; } #endif /* start read spi operation */ sdla_bus_write_4(hw, SPI_INTERFACE_REG, *data_ptr); #if FAST_SPI SPI_DELAY; #else /* wait for end of spi operation */ for (retry_counter = 0; retry_counter < SPI_MAX_RETRY_COUNT; retry_counter++){ sdla_bus_read_4(hw, SPI_INTERFACE_REG, data_ptr); if(data.start == 1){ SPI_DELAY; }else{ SPI_BREAK; } } SPI_DELAY; if(data.start == 1){ DEBUG_EVENT("%s:%s(): Line:%d: SPI TIMEOUT!!\n", hw->devname, __FUNCTION__, __LINE__); return 0; } #endif //DEBUG_BRI("3. data: 0x%08X\n", *data_ptr); value = (u_int8_t)data.data; DEBUG_REG("%s(Line: %i): (data: 0x%08X) reset: 0x%X, start: 0x%X, reserv1: 0x%X, remora_addr: 0x%X, mod_addr: 0x%X, data: 0x%X, contrl: 0x%X\n", __FUNCTION__, __LINE__, *((u32*)&data), data.reset, data.start, data.reserv1, data.remora_addr, data.mod_addr, data.data, data.contrl); DEBUG_REG("%s():%s: mod_no:%d reg=0x%X (%d) value=0x%02X\n", __FUNCTION__, hw->devname, mod_no, reg, reg, value); return value; } u_int8_t sdla_shark_bri_read_fe (void* phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, optional_arg, reg; u_int8_t data = 0; #if defined(WAN_DEBUG_FE) char *fname; int fline; #endif va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); optional_arg = va_arg(args, int); reg = va_arg(args, int); #if defined(WAN_DEBUG_FE) fname = va_arg(args, char*); fline = va_arg(args, int); #endif va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ #if defined(WAN_DEBUG_FE) DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE (%s:%d)!\n", hw->devname, __FUNCTION__,__LINE__,fname,fline); #else DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); #endif return 0x00; } data = __read_bri_fe_byte (hw, (u8)mod_no, (u8)reg, (u8)type, (u8)optional_arg); sdla_hw_fe_clear_bit(hw,0); return data; } /*************************************************************************** Front End AFT Serial interface for Shark subtype cards ***************************************************************************/ #define AFT_SERIAL_FE_INTERFACE_ADDR 0x210 #define AFT_SERIAL_PORT_REG(line,reg) (reg+(0x4000*line)) /*============================================================================ * Read AFT Serial Front end registers */ static int __sdla_shark_serial_write_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; unsigned int addr; int line_no, off, value; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); va_start(args, phw); line_no = (int)va_arg(args, int); off = (int)va_arg(args, int); value = (int)va_arg(args, int); va_end(args); addr = AFT_SERIAL_PORT_REG(line_no,AFT_SERIAL_FE_INTERFACE_ADDR); sdla_bus_write_4(hw, addr, value); return 0; } int sdla_shark_serial_write_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int line_no, off, value; if (sdla_hw_fe_test_and_set_bit(hw,0)){ if (WAN_NET_RATELIMIT()){ DEBUG_EVENT( "%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); } return -EINVAL; } va_start(args, phw); line_no = (int)va_arg(args, int); off = (int)va_arg(args, int); value = (int)va_arg(args, int); va_end(args); __sdla_shark_serial_write_fe(hw, line_no, off, value); sdla_hw_fe_clear_bit(hw,0); return 0; } /*============================================================================ * Read AFT Serial Front end registers */ u_int32_t __sdla_shark_serial_read_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; unsigned int addr; int off, line_no, value; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); va_start(args, phw); line_no = (int)va_arg(args, int); off = (int)va_arg(args, int); va_end(args); addr = AFT_SERIAL_PORT_REG(line_no,AFT_SERIAL_FE_INTERFACE_ADDR); sdla_bus_read_4(hw, addr, (u32*)&value); return value; } u_int32_t sdla_shark_serial_read_fe(void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; va_list args; int line_no, off, value; if (sdla_hw_fe_test_and_set_bit(hw,0)){ if (WAN_NET_RATELIMIT()){ DEBUG_ERROR("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); } return 0x00; } va_start(args, phw); line_no = va_arg(args, int); off = va_arg(args, int); va_end(args); value = __sdla_shark_serial_read_fe(hw, line_no, off); sdla_hw_fe_clear_bit(hw,0); return value; } #if defined(CONFIG_PRODUCT_WANPIPE_AFT_B601) static int __sdla_b601_te1_write_fe(void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_cpu_t *hwcpu; sdlahw_card_t *hwcard; va_list args; int qaccess=0, line_no=0, off=0, value=0; u16 data_hi, data_lo; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); hwcpu = hw->hwcpu; hwcard = hwcpu->hwcard; va_start(args, phw); qaccess = (u_int16_t)va_arg(args, int); line_no = (u_int16_t)va_arg(args, int); off = (u_int16_t)va_arg(args, int); value = (u_int8_t)va_arg(args, int); va_end(args); data_hi = 0x0000; data_lo = 0x0000; if (off & 0x800) { data_hi |= 0x2000; } if (off & 0x1000) { data_hi |= 0x4000; } SDLA_HW_T1E1_FE_ACCESS_BLOCK_A600; data_hi |= (off & 0x7FF); sdla_bus_write_2(hw, A600_MAXIM_INTERFACE_REG_ADD_HI, data_hi); SDLA_HW_T1E1_FE_ACCESS_BLOCK_A600; data_lo = (value & 0xFF); sdla_bus_write_2(hw, A600_MAXIM_INTERFACE_REG_ADD_LO, data_lo); SDLA_HW_T1E1_FE_ACCESS_BLOCK_A600; return 0; } int sdla_b601_te1_write_fe(void *phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg, value; #if defined(WAN_DEBUG_FE) char *fname; int fline; #endif WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); value = va_arg(args, int); va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); return -EINVAL; } __sdla_b601_te1_write_fe(hw, mod_no, type, chain, reg, value); sdla_hw_fe_clear_bit(hw,0); return 0; } u_int8_t __sdla_b601_te1_read_fe (void *phw, ...) { sdlahw_t* hw = (sdlahw_t*)phw; sdlahw_cpu_t *hwcpu; sdlahw_card_t *hwcard; va_list args; int qaccess=0, line_no=0, off=0; u32 data_read; u16 data_hi; WAN_ASSERT(hw == NULL); WAN_ASSERT(hw->hwcpu == NULL); WAN_ASSERT(hw->hwcpu->hwcard == NULL); hwcpu = hw->hwcpu; hwcard = hwcpu->hwcard; va_start(args, phw); qaccess = (u_int16_t)va_arg(args, int); line_no = (u_int16_t)va_arg(args, int); off = (u_int16_t)va_arg(args, int); va_end(args); WAN_ASSERT(qaccess != 0 && qaccess != 1); data_hi = 0x00; if (off & 0x800) { data_hi |= 0x2000; } if (off & 0x1000) { data_hi |= 0x4000; } SDLA_HW_T1E1_FE_ACCESS_BLOCK_A600; data_hi |= (off & 0x7FF); sdla_bus_write_2(hw, A600_MAXIM_INTERFACE_REG_ADD_HI, data_hi); SDLA_HW_T1E1_FE_ACCESS_BLOCK_A600; data_read = 0x00; sdla_bus_read_4(hw, A600_MAXIM_INTERFACE_REG_ADD_LO, &data_read); SDLA_HW_T1E1_FE_ACCESS_BLOCK_A600; return (data_read & 0xFF); } u_int8_t sdla_b601_te1_read_fe (void *phw, ...) { sdlahw_t *hw = (sdlahw_t*)phw; va_list args; int mod_no, type, chain, reg; unsigned char data = 0; WAN_ASSERT(hw->magic != SDLADRV_MAGIC); va_start(args, phw); mod_no = va_arg(args, int); type = va_arg(args, int); chain = va_arg(args, int); reg = va_arg(args, int); va_end(args); if (sdla_hw_fe_test_and_set_bit(hw,0)){ DEBUG_EVENT("%s: %s:%d: Critical Error: Re-entry in FE!\n", hw->devname, __FUNCTION__,__LINE__); return 0x00; } data = __sdla_b601_te1_read_fe (hw, mod_no, type, chain, reg); sdla_hw_fe_clear_bit(hw,0); return data; } #endif