diff options
author | Felix Fietkau <nbd@openwrt.org> | 2007-09-06 16:27:37 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2007-09-06 16:27:37 +0000 |
commit | 92558d67a463bfbb351d30e28648de03b635f024 (patch) | |
tree | a5d41b991a151e72663527a96fbc6c494565d65c /target/linux/amazon/files | |
parent | e1dbce411cd2a3a067f387cee011cd889486a07d (diff) | |
download | upstream-92558d67a463bfbb351d30e28648de03b635f024.tar.gz upstream-92558d67a463bfbb351d30e28648de03b635f024.tar.bz2 upstream-92558d67a463bfbb351d30e28648de03b635f024.zip |
strip the kernel version suffix from target directories, except for brcm-2.4 (the -2.4 will be included in the board name here). CONFIG_LINUX_<ver>_<board> becomes CONFIG_TARGET_<board>, same for profiles.
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@8653 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/amazon/files')
37 files changed, 25486 insertions, 0 deletions
diff --git a/target/linux/amazon/files/arch/mips/amazon/Kconfig b/target/linux/amazon/files/arch/mips/amazon/Kconfig new file mode 100644 index 0000000000..179e35efd2 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/Kconfig @@ -0,0 +1,63 @@ +# copyright 2007 john crispin <blogic@openwrt.org> + +menu "Amazon built-in" + +config AMAZON_ASC_UART + bool "Amazon asc uart" + select SERIAL_CORE + select SERIAL_CORE_CONSOLE + default y + +config AMAZON_PCI + bool "Amazon PCI support" + default y + select HW_HAS_PCI + select PCI + +config AMAZON_NET_SW + bool "Amazon network" + default y + +config AMAZON_WDT + bool "Amazon watchdog timer" + default y + +config AMAZON_MTD + bool "Amazon MTD map" + default y + +choice + prompt "Flash Size" + depends on AMAZON_MTD + +config MTD_AMAZON_FLASH_SIZE_2 + bool "2MB" + +config MTD_AMAZON_FLASH_SIZE_4 + bool "4MB" + +config MTD_AMAZON_FLASH_SIZE_8 + bool "8MB" + +config MTD_AMAZON_FLASH_SIZE_16 + bool "16MB" + +endchoice + +choice + prompt "Bus Width" + depends on AMAZON_MTD + +config MTD_AMAZON_BUS_WIDTH_8 + bool "8-bit" + +config MTD_AMAZON_BUS_WIDTH_16 + bool "16-bit" + +config MTD_AMAZON_BUS_WIDTH_32 + bool "32-bit" + +endchoice + + +endmenu diff --git a/target/linux/amazon/files/arch/mips/amazon/Makefile b/target/linux/amazon/files/arch/mips/amazon/Makefile new file mode 100644 index 0000000000..9cdc100b8c --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2007 openwrt.org +# John Crispin <blogic@openwrt.org> +# +# Makefile for Infineon Amazon +# +obj-y := dma-core.o interrupt.o prom.o setup.o +obj-$(CONFIG_PCI) += pci.o + diff --git a/target/linux/amazon/files/arch/mips/amazon/dma-core.c b/target/linux/amazon/files/arch/mips/amazon/dma-core.c new file mode 100644 index 0000000000..242bc77af2 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/dma-core.c @@ -0,0 +1,1455 @@ +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +//----------------------------------------------------------------------- +/* + * Description: + * Driver for Infineon Amazon DMA + */ +//----------------------------------------------------------------------- +/* Author: Wu Qi Ming[Qi-Ming.Wu@infineon.com] + * Created: 7-April-2004 + */ +//----------------------------------------------------------------------- +/* History + * Last changed on: 4-May-2004 + * Last changed by: <peng.liu@infineon.com> + * Reason: debug + */ +//----------------------------------------------------------------------- +/* Last changed on: 03-Dec-2004 + * Last changed by: peng.liu@infineon.com + * Reason: recover from TPE bug + */ + +//000004:fchang 2005/6/2 Modified by Linpeng as described below +//----------------------------------------------------------------------- +/* Last changed on: 28-Jan-2004 + * Last changed by: peng.liu@infineon.com + * Reason: + * - handle "out of memory" bug + */ +//000003:tc.chen 2005/06/16 fix memory leak when Tx buffer full (heaving traffic). +//507261:tc.chen 2005/07/26 re-organize code address map to improve performance. + +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) +#define MODVERSIONS +#endif + +#if defined(MODVERSIONS) && !defined(__GENKSYMS__) +#include <linux/modversions.h> +#endif + +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB /* need this one 'cause we export symbols */ +#endif + +#undef DMA_NO_POLLING + +/* no TX interrupt handling */ +#define NO_TX_INT +/* need for DMA workaround */ +#undef AMAZON_DMA_TPE_AAL5_RECOVERY + +#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY +#define MAX_SYNC_FAILS 1000000 // 000004:fchang +unsigned int dma_sync_fails = 0; +unsigned int total_dma_tpe_reset = 0; +int (*tpe_reset) (void); +int (*tpe_start) (void); +int (*tpe_inject) (void); +#endif // AMAZON_DMA_TPE_AAL5_RECOVERY + + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/fs.h> +#include <linux/errno.h> +#include <linux/proc_fs.h> +#include <linux/stat.h> +#include <linux/mm.h> +#include <linux/tty.h> +#include <linux/selection.h> +#include <linux/kmod.h> +#include <linux/vmalloc.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <asm/uaccess.h> +#include <linux/errno.h> +#include <asm/io.h> + +#include <asm/amazon/amazon.h> +#include <asm/amazon/irq.h> +#include <asm/amazon/amazon_dma.h> +#include "dma-core.h" + +#define AMAZON_DMA_EMSG(fmt, args...) printk( KERN_ERR "%s: " fmt,__FUNCTION__, ## args) + +static irqreturn_t dma_interrupt(int irq, void *dev_id); +extern void mask_and_ack_amazon_irq(unsigned int irq_nr); + +/***************************************** global data *******************************************/ +u64 *g_desc_list; +dev_list *g_current_dev = NULL; +dev_list *g_head_dev = NULL; +dev_list *g_tail_dev = NULL; +channel_info g_log_chan[CHAN_TOTAL_NUM + 1]; +struct proc_dir_entry *g_amazon_dma_dir; +static u8 rx_chan_list_len = 0; +static u8 tx_chan_list_len = 0; +static int rx_chan_list[RX_CHAN_NUM + 1]; +static int tx_chan_list[TX_CHAN_NUM + 1]; +static u32 comb_isr_mask[CHAN_TOTAL_NUM]; + +static inline int is_rx_chan(int chan_no) +/*judge if this is an rx channel*/ +{ + int result = 0; + if (chan_no < RX_CHAN_NUM) + result = 1; + return result; +} + +/* Ugly, Channel ON register is badly mapped to channel no. */ +static u8 ch_on_mapping[CHAN_TOTAL_NUM] = + { 0, 1, 2, 3, 6, 7, 10, 4, 5, 8, 9, 11 }; + +/* Brief: check wether the chan_no is legal + * Parameter: chan_no: logical channel number + * Return: 0 if is not valid + * 1 if is valid + */ +static inline int is_valid_dma_ch(int chan_no) +{ + return ((chan_no >= 0) && (chan_no < CHAN_TOTAL_NUM)); +} + +/* Brief: check whether a channel is open through Channel ON register + * Parameter: chan_no: logical channel number + * Return: 1 channel is open + * 0 not yet + * EINVAL: invalid parameter + */ +static inline int is_channel_open(int chan_no) +{ + return (AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) & + (1 << ch_on_mapping[chan_no])); +} + +/* Brief: add a list entry + * Description: + * always add to the tail and no redundancy allowed. (i.e. entries are unique) + * 0 : entry deleted + * <0 : not deleted (due to not unique) + */ +static inline int _add_list_entry(int *list, int size_of_list, int entry) +{ + int i; + for (i = 0; i < size_of_list; i++) { + if (list[i] == entry) + break; + if (list[i] < 0) { + list[i] = entry; + return 0; + } + } + return -1; +} + +/* Brief: delete a list entry + * Description: + * find the entry and remove it. shift all entries behind it one step forward if necessary\ + * Return: + * 0 : entry deleted + * <0 : not deleted (due to not found?) + */ +static inline int _delete_list_entry(int *list, int size_of_list, + int entry) +{ + int i, j; + for (i = 0; i < size_of_list; i++) { + if (list[i] == entry) { + for (j = i; j < size_of_list; j++) { + list[j] = list[j + 1]; + if (list[j + 1] < 0) { + break; + } + } + return 0; + } + } + return -1; +} + +/* Brief: enable a channel through Channel ON register + * Parameter: chan_no: logical channel number + * Description: + * Please don't open a channel without a valid descriptor (hardware pitfall) + */ +static inline void open_channel(int chan_no) +{ + AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) |= (1 << ch_on_mapping[chan_no]); + if (is_rx_chan(chan_no)) { + if (_add_list_entry(rx_chan_list, RX_CHAN_NUM, chan_no) == 0) { + rx_chan_list_len++; + } else { + AMAZON_DMA_DMSG("cannot add chan %d to open list\n", chan_no); + } + } else { + if (_add_list_entry(tx_chan_list, TX_CHAN_NUM, chan_no) == 0) { + tx_chan_list_len++; + } else { + AMAZON_DMA_DMSG("cannot add chan %d to open list\n", chan_no); + } + } +} + +/* Brief: disable a channel through Channel ON register + * Parameter: chan_no: logical channel number + */ + +static inline void close_channel(int chan_no) +{ + AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) &= ~(1 << ch_on_mapping[chan_no]); + if (is_rx_chan(chan_no)) { + if (_delete_list_entry(rx_chan_list, RX_CHAN_NUM, chan_no) == 0) { + rx_chan_list_len--; + } else { + AMAZON_DMA_DMSG("cannot remove chan %d from open list \n", + chan_no); + } + } else { + if (_delete_list_entry(tx_chan_list, TX_CHAN_NUM, chan_no) == 0) { + tx_chan_list_len--; + } else { + AMAZON_DMA_DMSG("cannot remove chan %d from open list \n", + chan_no); + } + } +} + +/* Brief: clear RX interrupt + */ +inline void rx_chan_clear_isr(int chan_no) +{ +#ifdef DMA_NO_POLLING + AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR + chan_no * AMAZON_DMA_CH_STEP) = + (AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + chan_no * + AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP | DMA_ISR_CMDCPT + | DMA_ISR_DURR)); +#else + AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR + chan_no * AMAZON_DMA_CH_STEP) = + (AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + chan_no * + AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP | + DMA_ISR_CMDCPT)); +#endif +} + + +/* Brief: hacking function, this will reset all descriptors back to DMA + */ +static void dma_reset_all_descriptors(int chan_no) +{ + volatile struct rx_desc *rx_desc_p = NULL; + int i; + rx_desc_p = + (struct rx_desc *) g_desc_list + + g_log_chan[chan_no].offset_from_base; + for (i = 0; i < g_log_chan[chan_no].desc_len; i++) { + rx_desc_p->status.word &= + (~(DMA_DESC_SOP_SET | DMA_DESC_EOP_SET | DMA_DESC_CPT_SET)); + rx_desc_p->status.word |= + (DMA_DESC_OWN_DMA | g_log_chan[chan_no].packet_size); + rx_desc_p++; + } +} + +#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY +/* Brief: Reset DMA descriptors + */ +static void amazon_dma_reset_tpe_rx(int chan_no) +{ + struct tx_desc *tx_desc_p = NULL; + int j, i = 0; + + // wait until all TX channels stop transmitting + for (j = 9; j <= 10; j++) { + tx_desc_p = + (struct tx_desc *) g_desc_list + + g_log_chan[j].offset_from_base; + for (i = 0; i < g_log_chan[j].desc_len; i++) { + while ((tx_desc_p->status.field.OWN != CPU_OWN)) { + AMAZON_DMA_DMSG("DMA TX in progress\n"); // 000004:fchang + udelay(100); + } + tx_desc_p++; + } + } + + if (tpe_reset) { + total_dma_tpe_reset++; + AMAZON_DMA_DMSG + ("\n===============resetting TPE========================== \n"); + if ((*tpe_reset) ()) { + panic("cannot reset TPE engien\n"); // 000004:fchang + } + } else { + panic("no tpe_reset function\n"); // 000004:fchang + return; + } + dma_reset_all_descriptors(chan_no); + rx_chan_clear_isr(chan_no); + mb(); + + // send EoP + if (tpe_inject) { + if ((*tpe_inject) ()) { + panic("cannot inject a cell\n"); // 000004:fchang + } + } else { + AMAZON_DMA_EMSG("no tpe_inject function\n"); + return; + } + mb(); + while (1) { + if (AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + chan_no * AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT)) { + rx_chan_clear_isr(chan_no); + mb(); + dma_reset_all_descriptors(chan_no); + if (g_log_chan[chan_no].current_desc == + (g_log_chan[chan_no].desc_len - 1)) { + g_log_chan[chan_no].current_desc = 0; + } else { + g_log_chan[chan_no].current_desc++; + } + break; + } + mdelay(1); + } + mb(); +#if 0 + AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) &= ~(1 << ch_on_mapping[chan_no]); + while (AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) & + (1 << ch_on_mapping[chan_no])) { + printk("TPE channel still on\n"); + mdelay(1); + } + + // AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = (1<<chan_no); + mb(); + AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + chan_no * AMAZON_DMA_CH_STEP) = + 0x32; + mb(); + rx_chan_clear_isr(chan_no); + dma_reset_all_descriptors(chan_no); + mb(); + AMAZON_DMA_REG32(AMAZON_DMA_CH_ON) |= (1 << ch_on_mapping[chan_no]); + // g_log_chan[chan_no].current_desc=0; + mb(); + mdelay(1); +#endif + if (tpe_start) { + (*tpe_start) (); + } else { + AMAZON_DMA_EMSG("cannot restart TPE engien\n"); + } +} +#endif // AMAZON_DMA_TPE_AAL5_RECOVERY + + +/* Brief: RX channel interrupt handler + * Parameter: RX channel no + * Description: the interrupt handler for each RX channel + * 1. check descriptor, clear ISR if no incoming packet + * 2. inform upper layer to receive packet (and update descriptors) + */ +inline void rx_chan_intr_handler(int chan_no) +{ + volatile struct rx_desc *rx_desc_p = NULL; + + /* fetch the current descriptor */ + rx_desc_p = + (struct rx_desc *) g_desc_list + + g_log_chan[chan_no].offset_from_base + + g_log_chan[chan_no].current_desc; + + g_log_chan[chan_no].dma_dev->current_rx_chan = + chan_no - g_log_chan[chan_no].dma_dev->logic_rx_chan_base; + + // workaround for DMA pitfall: complete bit set happends before the + // other two bits (own,eop) are ready + if ((rx_desc_p->status.field.EoP != 1) + || (rx_desc_p->status.field.OWN != CPU_OWN) + || (rx_desc_p->status.field.data_length == + g_log_chan[chan_no].packet_size)) { +#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY + if (chan_no == 4 || chan_no == 5) { + dma_sync_fails++; + if (dma_sync_fails > MAX_SYNC_FAILS) { + // detect bug + rx_desc_p0 = + (struct rx_desc *) g_desc_list + + g_log_chan[chan_no].offset_from_base; + rx_desc_p1 = + (struct rx_desc *) g_desc_list + + g_log_chan[chan_no].offset_from_base + 1; + if ((rx_desc_p0->status.field.OWN == CPU_OWN + && rx_desc_p0->status.field.EoP != 1) + && (rx_desc_p1->status.field.OWN == CPU_OWN + && rx_desc_p1->status.field.EoP != 1)) { + amazon_dma_reset_tpe_rx(chan_no); + dma_sync_fails = 0; + return; + } + dma_sync_fails = 0; + AMAZON_DMA_DMSG("too many times ch:%d\n", chan_no); // 000004:fchang + return; + } + udelay(10); // 000004:fchang + } +#endif // //AMAZON_DMA_TPE_AAL5_RECOVERY + return; + } + + /* inform the upper layer to receive the packet */ + g_log_chan[chan_no].intr_handler(g_log_chan[chan_no].dma_dev, RCV_INT); + /* check the next descriptor, if still contains the incoming packet, + then do not clear the interrupt status */ + rx_desc_p = + (struct rx_desc *) g_desc_list + + g_log_chan[chan_no].offset_from_base + + g_log_chan[chan_no].current_desc; + if (! + ((rx_desc_p->status.field.OWN == CPU_OWN) + && (rx_desc_p->status.field.C == 1))) { + rx_chan_clear_isr(chan_no); + } +} + + +/* Brief: TX channel interrupt handler + * Parameter: TX channel no + * Description: the interrupt handler for each TX channel + * 1. check all the descripters,if any of them had transmitted a packet, then free buffer + * because we cannot garantee the which one has already transmitted out, we have to go through all the descriptors here + * 2. clear the interrupt status bit + */ +inline void tx_chan_intr_handler(int chan_no) +{ + struct tx_desc *tx_desc_p = NULL; + int i = 0; + + tx_desc_p = + (struct tx_desc *) g_desc_list + + g_log_chan[chan_no].offset_from_base; + + for (i = 0; i < g_log_chan[chan_no].desc_len; i++) { + if ((tx_desc_p->status.field.OWN == CPU_OWN) + && (tx_desc_p->status.field.C == 1)) { + /* if already transmitted, then free the buffer */ + g_log_chan[chan_no]. + buffer_free((u8 *) __va(tx_desc_p->Data_Pointer), + g_log_chan[chan_no].opt[i]); + tx_desc_p->status.field.C = 0; + /* inform the upper layer about the completion of the + transmitted packet, the upper layer may want to free the + packet */ + g_log_chan[chan_no].intr_handler(g_log_chan[chan_no].dma_dev, + TRANSMIT_CPT_INT); + } + tx_desc_p++; + } + + /* after all these operations, clear the interrupt status bit */ + AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR + chan_no * AMAZON_DMA_CH_STEP) = + (AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + chan_no * + AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP | + DMA_ISR_CMDCPT)); +} + +/* Brief: DMA interrupt handler + */ +static irqreturn_t dma_interrupt(int irq, void *dev_id) +{ + int i = 0; + int chan_no; + u32 isr = 0; +#ifdef NO_TX_INT // 000004:fchang + static int cnt = 0; // 000004:fchang +#endif // 000004:fchang + while ((isr = + AMAZON_DMA_REG32(AMAZON_DMA_COMB_ISR)) & (COMB_ISR_RX_MASK | + COMB_ISR_TX_MASK)) { + if (isr & COMB_ISR_RX_MASK) { + // RX Channels: start WFQ algorithm + chan_no = CHAN_TOTAL_NUM; + for (i = 0; i < RX_CHAN_NUM; i++) { + if ((isr & (comb_isr_mask[i])) + && (g_log_chan[i].weight > 0)) { + if (g_log_chan[chan_no].weight < g_log_chan[i].weight) { + chan_no = i; + } + } + } + if (chan_no < CHAN_TOTAL_NUM) { + rx_chan_intr_handler(chan_no); + } else { + for (i = 0; i < RX_CHAN_NUM; i++) { + g_log_chan[i].weight = g_log_chan[i].default_weight; + } + } + } +#ifdef NO_TX_INT + cnt++; + if (cnt == 10) { + cnt = 0; + for (i = 0; i < tx_chan_list_len; i++) { + if (AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + tx_chan_list[i] * + AMAZON_DMA_CH_STEP) & (DMA_ISR_CPT | DMA_ISR_EOP)) { + tx_chan_intr_handler(tx_chan_list[i]); + } + } + } +#else + if (isr & COMB_ISR_TX_MASK) { + // TX channels: RR + for (i = 0; i < tx_chan_list_len; i++) { + if (isr & (comb_isr_mask[tx_chan_list[i]])) { + tx_chan_intr_handler(tx_chan_list[i]); + } + } + } +#endif + } // while + return IRQ_HANDLED; +} + + +/* Brief: read a packet from DMA RX channel + * Parameter: + * Return: packet length + * Description: + * This is called back in a context of DMA interrupt + * 1. prepare new descriptor + * 2. read data + * 3. update WFQ weight + */ +//507261:tc.chen int dma_device_read(struct dma_device_info* dma_dev, u8** dataptr, void** opt) +int asmlinkage dma_device_read(struct dma_device_info *dma_dev, + u8 ** dataptr, void **opt) +{ + u8 *buf; + int len; + int chan_no = 0; + int byte_offset = 0; + + struct rx_desc *rx_desc_p; + void *p = NULL; + int current_desc; + + chan_no = dma_dev->logic_rx_chan_base + dma_dev->current_rx_chan; + current_desc = g_log_chan[chan_no].current_desc; + rx_desc_p = + (struct rx_desc *) (g_desc_list + + g_log_chan[chan_no].offset_from_base + + current_desc); + buf = (u8 *) __va(rx_desc_p->Data_Pointer); /* extract the virtual + address of the data + pointer */ + len = rx_desc_p->status.field.data_length; /* extract the data length */ +#ifndef CONFIG_MIPS_UNCACHED + dma_cache_inv((unsigned long) buf, len); +#endif // CONFIG_MIPS_UNCACHED + *(u32 *) dataptr = (u32) buf; + if (opt) { + *(int *) opt = (int) g_log_chan[chan_no].opt[current_desc]; /* read + out + the + opt + information */ + } + + buf = + (u8 *) g_log_chan[chan_no].buffer_alloc(g_log_chan[chan_no]. + packet_size, &byte_offset, + &p); + // should check null!!!! + if (buf == NULL || p == NULL) { + *(u32 *) dataptr = 0; + *(int *) opt = 0; + len = 0; + } else { + g_log_chan[chan_no].opt[current_desc] = p; + /* reduce the weight for WFQ algorithm */ + g_log_chan[chan_no].weight -= len; + rx_desc_p->Data_Pointer = (u32) CPHYSADDR((u32) buf); + } + if (current_desc == g_log_chan[chan_no].desc_len - 1) { + current_desc = 0; + } else { + current_desc++; + } + g_log_chan[chan_no].current_desc = current_desc; + + rx_desc_p->status.word = DMA_DESC_OWN_DMA + | (byte_offset << DMA_DESC_BYTEOFF_SHIFT) + | g_log_chan[chan_no].packet_size; + return len; +} + +/* Brief: write a packet through DMA RX channel to peripheral + * Parameter: + * Return: packet length + * Description: + * + */ +u64 dma_tx_drop = 0; +//507261:tc.chen int dma_device_write(struct dma_device_info* dma_dev, u8* dataptr, int len,void* opt) +int asmlinkage dma_device_write(struct dma_device_info *dma_dev, + u8 * dataptr, int len, void *opt) +{ + int chan_no = 0; + struct tx_desc *tx_desc_p; + + int byte_offset = 0; + int current_desc; + static int cnt = 0; // 000004:fchang + + unsigned long flag; + local_irq_save(flag); + + chan_no = dma_dev->logic_tx_chan_base + dma_dev->current_tx_chan; + current_desc = g_log_chan[chan_no].current_desc; + tx_desc_p = + (struct tx_desc *) (g_desc_list + + g_log_chan[chan_no].offset_from_base + + current_desc); + // 000003:tc.chen if(tx_desc_p->status.field.OWN==DMA_OWN){ + if (tx_desc_p->status.field.OWN == DMA_OWN || tx_desc_p->status.field.C == 1) { // 000003:tc.chen + AMAZON_DMA_DMSG("no TX desc for CPU, drop packet\n"); + dma_tx_drop++; + g_log_chan[chan_no].intr_handler(dma_dev, TX_BUF_FULL_INT); + local_irq_restore(flag); + return 0; + } + g_log_chan[chan_no].opt[current_desc] = opt; + + /* byte offset----to adjust the starting address of the data buffer, + should be multiple of the burst length. */ + byte_offset = + ((u32) CPHYSADDR((u32) dataptr)) % (g_log_chan[chan_no].burst_len * + 4); +#ifndef CONFIG_MIPS_UNCACHED + dma_cache_wback((unsigned long) dataptr, len); + wmb(); +#endif // CONFIG_MIPS_UNCACHED + + tx_desc_p->Data_Pointer = (u32) CPHYSADDR((u32) dataptr) - byte_offset; + wmb(); + tx_desc_p->status.word = DMA_DESC_OWN_DMA + | DMA_DESC_SOP_SET + | DMA_DESC_EOP_SET | (byte_offset << DMA_DESC_BYTEOFF_SHIFT) + | len; + wmb(); + if (is_channel_open(chan_no) == 0) { + // turn on if necessary + open_channel(chan_no); + } +#ifdef DMA_NO_POLLING + if ((AMAZON_DMA_REG32 + (AMAZON_DMA_CH0_ISR + + chan_no * AMAZON_DMA_CH_STEP) & (DMA_ISR_DURR | DMA_ISR_CPT)) == + (DMA_ISR_DURR)) { + // clear DURR if (CPT is AND set and DURR is set) + AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR + + chan_no * AMAZON_DMA_CH_STEP) = DMA_ISR_DURR; + } +#endif + + if (current_desc == (g_log_chan[chan_no].desc_len - 1)) { + current_desc = 0; + } else { + current_desc++; + } + + + g_log_chan[chan_no].current_desc = current_desc; + tx_desc_p = + (struct tx_desc *) (g_desc_list + + g_log_chan[chan_no].offset_from_base + + current_desc); + // 000003:tc.chen if(tx_desc_p->status.field.OWN==DMA_OWN){ + if (tx_desc_p->status.field.OWN == DMA_OWN || tx_desc_p->status.field.C == 1) { // 000003:tc.chen + g_log_chan[chan_no].intr_handler(dma_dev, TX_BUF_FULL_INT); + } +#ifdef NO_TX_INT +//000004:fchang Start + cnt++; + if (cnt == 5) { + cnt = 0; + tx_chan_intr_handler(chan_no); + } +//000004:fchang End +#endif + local_irq_restore(flag); // 000004:fchang + return len; +} + + + +int desc_list_proc_read(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + int i; + u32 *p = (u32 *) g_desc_list; + int len = 0; + len += sprintf(buf + len, "descriptor list:\n"); + for (i = 0; i < 120; i++) { + len += sprintf(buf + len, "%d\n", i); + len += sprintf(buf + len, "%08x\n", *(p + i * 2 + 1)); + len += sprintf(buf + len, "%08x\n", *(p + i * 2)); + + } + + return len; + +} + +int channel_weight_proc_read(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + + // int i=0; + int len = 0; + len += sprintf(buf + len, "Qos dma channel weight list\n"); + len += + sprintf(buf + len, + "channel_num default_weight current_weight device Tx/Rx\n"); + len += + sprintf(buf + len, + " 0 %08x %08x Switch Rx0\n", + g_log_chan[0].default_weight, g_log_chan[0].weight); + len += + sprintf(buf + len, + " 1 %08x %08x Switch Rx1\n", + g_log_chan[1].default_weight, g_log_chan[1].weight); + len += + sprintf(buf + len, + " 2 %08x %08x Switch Rx2\n", + g_log_chan[2].default_weight, g_log_chan[2].weight); + len += + sprintf(buf + len, + " 3 %08x %08x Switch Rx3\n", + g_log_chan[3].default_weight, g_log_chan[3].weight); + len += + sprintf(buf + len, + " 4 %08x %08x Switch Tx0\n", + g_log_chan[4].default_weight, g_log_chan[4].weight); + len += + sprintf(buf + len, + " 5 %08x %08x Switch Tx1\n", + g_log_chan[5].default_weight, g_log_chan[5].weight); + /* + len+=sprintf(buf+len," 6 %08x %08x TPE + Rx0\n",g_log_chan[6].default_weight, g_log_chan[6].weight); + len+=sprintf(buf+len," 7 %08x %08x TPE + Rx0\n",g_log_chan[7].default_weight, g_log_chan[7].weight); + len+=sprintf(buf+len," 8 %08x %08x TPE + Tx0\n",g_log_chan[8].default_weight, g_log_chan[8].weight); + len+=sprintf(buf+len," 9 %08x %08x TPE + Rx0\n",g_log_chan[9].default_weight, g_log_chan[9].weight); + len+=sprintf(buf+len," 10 %08x %08x DPLUS + Rx0\n",g_log_chan[10].default_weight, g_log_chan[10].weight); + len+=sprintf(buf+len," 11 %08x %08x DPLUS + Rx0\n",g_log_chan[11].default_weight, g_log_chan[11].weight); */ + return len; +} + +int dma_register_proc_read(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + dev_list *temp_dev; + int len = 0;; + + len += sprintf(buf + len, "amazon dma driver\n"); + len += sprintf(buf + len, "version 1.0\n"); + len += sprintf(buf + len, "devices registered:\n"); + for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) { + len += sprintf(buf + len, "%s ", temp_dev->dev->device_name); + } + len += sprintf(buf + len, "\n"); + len += sprintf(buf + len, "CH_ON=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH_ON)); + len += sprintf(buf + len, "CH_RST=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH_RST)); + len += sprintf(buf + len, "CH0_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH0_ISR)); + len += sprintf(buf + len, "CH1_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH1_ISR)); + len += sprintf(buf + len, "CH2_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH2_ISR)); + len += sprintf(buf + len, "CH3_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH3_ISR)); + len += sprintf(buf + len, "CH4_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH4_ISR)); + len += sprintf(buf + len, "CH5_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH5_ISR)); + len += sprintf(buf + len, "CH6_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH6_ISR)); + len += sprintf(buf + len, "CH7_ISR=%08x\n", AMAZON_DMA_REG32(AMAZON_DMA_CH7_ISR)); + len += sprintf(buf + len, "CH8_ISR=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH8_ISR)); + len += + sprintf(buf + len, "CH9_ISR=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH9_ISR)); + len += + sprintf(buf + len, "CH10_ISR=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH10_ISR)); + len += + sprintf(buf + len, "CH11_ISR=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH11_ISR)); + len += + sprintf(buf + len, "LCH0_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK)); + len += + sprintf(buf + len, "LCH1_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH1_MSK)); + len += + sprintf(buf + len, "LCH2_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH2_MSK)); + len += + sprintf(buf + len, "LCH3_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH3_MSK)); + len += + sprintf(buf + len, "LCH4_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH4_MSK)); + len += + sprintf(buf + len, "LCH5_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH5_MSK)); + len += + sprintf(buf + len, "LCH6_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH6_MSK)); + len += + sprintf(buf + len, "LCH7_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH7_MSK)); + len += + sprintf(buf + len, "LCH8_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH8_MSK)); + len += + sprintf(buf + len, "LCH9_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH9_MSK)); + len += + sprintf(buf + len, "LCH10_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH10_MSK)); + len += + sprintf(buf + len, "LCH11_MSK=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH11_MSK)); + len += + sprintf(buf + len, "Desc_BA=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_Desc_BA)); + len += + sprintf(buf + len, "LCH0_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH0_DES_LEN)); + len += + sprintf(buf + len, "LCH1_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH1_DES_LEN)); + len += + sprintf(buf + len, "LCH2_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH2_DES_LEN)); + len += + sprintf(buf + len, "LCH3_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH3_DES_LEN)); + len += + sprintf(buf + len, "LCH4_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH4_DES_LEN)); + len += + sprintf(buf + len, "LCH5_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH5_DES_LEN)); + len += + sprintf(buf + len, "LCH6_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH6_DES_LEN)); + len += + sprintf(buf + len, "LCH7_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH7_DES_LEN)); + len += + sprintf(buf + len, "LCH8_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH8_DES_LEN)); + len += + sprintf(buf + len, "LCH9_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH9_DES_LEN)); + len += + sprintf(buf + len, "LCH10_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH10_DES_LEN)); + len += + sprintf(buf + len, "LCH11_DES_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH11_DES_LEN)); + len += + sprintf(buf + len, "LCH1_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH1_DES_OFST)); + len += + sprintf(buf + len, "LCH2_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH2_DES_OFST)); + len += + sprintf(buf + len, "LCH3_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH3_DES_OFST)); + len += + sprintf(buf + len, "LCH4_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH4_DES_OFST)); + len += + sprintf(buf + len, "LCH5_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH5_DES_OFST)); + len += + sprintf(buf + len, "LCH6_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH6_DES_OFST)); + len += + sprintf(buf + len, "LCH7_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH7_DES_OFST)); + len += + sprintf(buf + len, "LCH8_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH8_DES_OFST)); + len += + sprintf(buf + len, "LCH9_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH9_DES_OFST)); + len += + sprintf(buf + len, "LCH10_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH10_DES_OFST)); + len += + sprintf(buf + len, "LCH11_DES_OFST=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH11_DES_OFST)); + len += + sprintf(buf + len, "AMAZON_DMA_SW_BL=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_SW_BL)); + len += + sprintf(buf + len, "AMAZON_DMA_TPE_BL=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_TPE_BL)); + len += + sprintf(buf + len, "DPlus2FPI_BL=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_DPlus2FPI_BL)); + len += + sprintf(buf + len, "GRX_BUF_LEN=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_GRX_BUF_LEN)); + len += + sprintf(buf + len, "DMA_ECON_REG=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_DMA_ECON_REG)); + len += + sprintf(buf + len, "POLLING_REG=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_POLLING_REG)); + len += + sprintf(buf + len, "CH_WGT=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_CH_WGT)); + len += + sprintf(buf + len, "TX_WGT=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_TX_WGT)); + len += + sprintf(buf + len, "DPlus2FPI_CLASS=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_DPLus2FPI_CLASS)); + len += + sprintf(buf + len, "COMB_ISR=%08x\n", + AMAZON_DMA_REG32(AMAZON_DMA_COMB_ISR)); +#ifdef AMAZON_DMA_TPE_AAL5_RECOVERY + len += sprintf(buf + len, "TPE fails:%u\n", total_dma_tpe_reset); // 000004:fchang +#endif + return len; +} + +/* Brief: initialize DMA registers + * Description: + */ +static void dma_chip_init(void) +{ + int i; + for (i = 0; i < CHAN_TOTAL_NUM; i++) { + AMAZON_DMA_REG32(AMAZON_DMA_CH1_DES_OFST + + i * AMAZON_DMA_CH_STEP) = DEFAULT_OFFSET; + } +#ifdef DMA_NO_POLLING + AMAZON_DMA_REG32(AMAZON_DMA_POLLING_REG) = 0; +#else + // enable poll mode and set polling counter + AMAZON_DMA_REG32(AMAZON_DMA_POLLING_REG) = DMA_POLLING_CNT | DMA_POLLING_ENABLE; +#endif + // to enable DMA drop + AMAZON_DMA_REG32(AMAZON_DMA_GRX_BUF_LEN) = 0x10000; +} + +int insert_dev_list(dev_list * dev) +{ + dev_list *temp_dev; + if (g_head_dev == NULL) { + g_head_dev = dev; + g_tail_dev = dev; + dev->prev = NULL; + dev->next = NULL; + } else { + for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) { + if (temp_dev->weight < dev->weight) { + if (temp_dev->prev) + temp_dev->prev->next = dev; + + dev->prev = temp_dev->prev; + dev->next = temp_dev; + temp_dev->prev = dev; + if (temp_dev == g_head_dev) + g_head_dev = dev; + break; + } + } + + if (!temp_dev) { + g_tail_dev->next = dev; + dev->prev = g_tail_dev; + dev->next = NULL; + g_tail_dev = dev; + } + + } + + return 1; +} + +u8 *common_buffer_alloc(int len, int *byte_offset, void **opt) +{ + u8 *buffer = (u8 *) kmalloc(len * sizeof(u8), GFP_KERNEL); + *byte_offset = 0; + return buffer; + +} + +int common_buffer_free(u8 * dataptr, void *opt) +{ + if (dataptr) + kfree(dataptr); + return 0; +} + + +int register_dev(struct dma_device_info *dma_dev) +{ + int i, j, temp; + int burst_reg = 0; + u8 *buffer; + void *p = NULL; + int byte_offset = 0; + + struct rx_desc *rx_desc_p; + struct tx_desc *tx_desc_p; + if (strcmp(dma_dev->device_name, "switch1") == 0) { + AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = SWITCH1_RST_MASK; // resest + // channel + // 1st + AMAZON_DMA_REG32(AMAZON_DMA_DMA_ECON_REG) |= 0x3; // endian + // conversion + // for Switch + burst_reg = AMAZON_DMA_SW_BL; + dma_dev->logic_rx_chan_base = switch_rx_chan_base; + dma_dev->logic_tx_chan_base = switch_tx_chan_base; + } + + else if (strcmp(dma_dev->device_name, "switch2") == 0) { + AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = SWITCH2_RST_MASK; // resest + // channel + // 1st + AMAZON_DMA_REG32(AMAZON_DMA_DMA_ECON_REG) |= 0x3; // endian + // conversion + // for Switch + burst_reg = AMAZON_DMA_SW_BL; + dma_dev->logic_rx_chan_base = switch2_rx_chan_base; + dma_dev->logic_tx_chan_base = switch2_tx_chan_base; + + } else if (strcmp(dma_dev->device_name, "TPE") == 0) { + AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = TPE_RST_MASK; // resest + // channel 1st + // + burst_reg = AMAZON_DMA_TPE_BL; + dma_dev->logic_rx_chan_base = TPE_rx_chan_base; + dma_dev->logic_tx_chan_base = TPE_tx_chan_base; + } + + else if (strcmp(dma_dev->device_name, "DPlus") == 0) { + AMAZON_DMA_REG32(AMAZON_DMA_CH_RST) = DPlus2FPI_RST_MASK; // resest + // channel + // 1st + dma_dev->logic_rx_chan_base = DPLus2FPI_rx_chan_base; + dma_dev->logic_tx_chan_base = DPLus2FPI_tx_chan_base; + + } + + i = 0; + for (temp = dma_dev->tx_burst_len; temp > 2; temp /= 2) { + i += 1; + } + + + AMAZON_DMA_REG32(burst_reg) = i << 1; + i = 0; + for (temp = dma_dev->rx_burst_len; temp > 2; temp /= 2) { + i += 1; + } + AMAZON_DMA_REG32(burst_reg) += i; + + for (i = 0; i < dma_dev->num_rx_chan; i++) { + + temp = dma_dev->logic_rx_chan_base + i; + g_log_chan[temp].dma_dev = dma_dev; + g_log_chan[temp].weight = dma_dev->rx_chan[i].weight; + g_log_chan[temp].default_weight = dma_dev->rx_chan[i].weight; + g_log_chan[temp].current_desc = 0; + g_log_chan[temp].desc_ofst = DEFAULT_OFFSET; + g_log_chan[temp].desc_len = dma_dev->rx_chan[i].desc_num; + g_log_chan[temp].offset_from_base = temp * DEFAULT_OFFSET; + g_log_chan[temp].packet_size = dma_dev->rx_chan[i].packet_size; + + AMAZON_DMA_REG32(AMAZON_DMA_CH0_DES_LEN + temp * AMAZON_DMA_CH_STEP) = dma_dev->rx_chan[i].desc_num; + // enable interrupt mask + if (temp == 4 || temp == 5) { + AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x32; + } else { + AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x36; + } + strcpy(g_log_chan[temp].device_name, dma_dev->device_name); + g_log_chan[temp].burst_len = dma_dev->rx_burst_len; + g_log_chan[temp].control = dma_dev->rx_chan[i].control; + + + /* specify the buffer allocation and free method */ + if (dma_dev->buffer_alloc) + g_log_chan[temp].buffer_alloc = dma_dev->buffer_alloc; + else + g_log_chan[temp].buffer_alloc = common_buffer_alloc; + + if (dma_dev->buffer_free) + g_log_chan[temp].buffer_free = dma_dev->buffer_free; + else + g_log_chan[temp].buffer_free = common_buffer_free; + + if (dma_dev->intr_handler) + g_log_chan[temp].intr_handler = dma_dev->intr_handler; + else + g_log_chan[temp].intr_handler = NULL; + + for (j = 0; j < g_log_chan[temp].desc_len; j++) { + rx_desc_p = (struct rx_desc *) (g_desc_list + g_log_chan[temp].offset_from_base + j); + rx_desc_p->status.word = 0; + rx_desc_p->status.field.data_length = g_log_chan[temp].packet_size; + buffer = (u8 *) g_log_chan[temp].buffer_alloc(g_log_chan[temp].packet_size, &byte_offset, &p); + rx_desc_p->Data_Pointer = (u32) CPHYSADDR((u32) buffer); + rx_desc_p->status.field.byte_offset = byte_offset; + /* fix me, should check if the addresss comply with the burst + lenght requirment */ + g_log_chan[temp].opt[j] = p; + rx_desc_p->status.field.OWN = DMA_OWN; + + } + /* open or close the channel */ + if (g_log_chan[temp].control) + open_channel(temp); + else + close_channel(temp); + } + + for (i = 0; i < dma_dev->num_tx_chan; i++) { + temp = dma_dev->logic_tx_chan_base + i; + g_log_chan[temp].dma_dev = dma_dev; + g_log_chan[temp].weight = dma_dev->tx_chan[i].weight; + g_log_chan[temp].default_weight = dma_dev->tx_chan[i].weight; + g_log_chan[temp].current_desc = 0; + g_log_chan[temp].desc_ofst = DEFAULT_OFFSET; + g_log_chan[temp].desc_len = dma_dev->tx_chan[i].desc_num; + g_log_chan[temp].offset_from_base = temp * DEFAULT_OFFSET; + g_log_chan[temp].packet_size = dma_dev->tx_chan[i].packet_size; + + AMAZON_DMA_REG32(AMAZON_DMA_CH0_DES_LEN + temp * AMAZON_DMA_CH_STEP) = dma_dev->tx_chan[i].desc_num; + // enable interrupt mask +#ifdef NO_TX_INT + AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x3e; +#else + AMAZON_DMA_REG32(AMAZON_DMA_CH0_MSK + temp * AMAZON_DMA_CH_STEP) = 0x36; +#endif + + strcpy(g_log_chan[temp].device_name, dma_dev->device_name); + g_log_chan[temp].burst_len = dma_dev->tx_burst_len; + g_log_chan[temp].control = dma_dev->tx_chan[i].control; + + if (dma_dev->buffer_alloc) + g_log_chan[temp].buffer_alloc = dma_dev->buffer_alloc; + else + g_log_chan[temp].buffer_alloc = common_buffer_alloc; + + if (dma_dev->buffer_free) + g_log_chan[temp].buffer_free = dma_dev->buffer_free; + else + g_log_chan[temp].buffer_free = common_buffer_free; + + if (dma_dev->intr_handler) + g_log_chan[temp].intr_handler = dma_dev->intr_handler; + else + g_log_chan[temp].intr_handler = NULL; + + for (j = 0; j < g_log_chan[temp].desc_len; j++) { + + tx_desc_p = + (struct tx_desc *) (g_desc_list + + g_log_chan[temp].offset_from_base + j); + tx_desc_p->status.word = 0; + tx_desc_p->status.field.data_length = + g_log_chan[temp].packet_size; + tx_desc_p->status.field.OWN = CPU_OWN; + + } + /* workaround DMA pitfall, we never turn on channel if we don't + have proper descriptors */ + if (!g_log_chan[temp].control) { + close_channel(temp); + } + + } + + return 0; +} + +int dma_device_register(struct dma_device_info *dma_dev) +{ + dev_list *temp_dev; + temp_dev = (dev_list *) kmalloc(sizeof(dev_list), GFP_KERNEL); + temp_dev->dev = dma_dev; + temp_dev->weight = dma_dev->weight; + insert_dev_list(temp_dev); + /* check whether this is a known device */ + if ((strcmp(dma_dev->device_name, "switch1") == 0) + || (strcmp(dma_dev->device_name, "TPE") == 0) + || (strcmp(dma_dev->device_name, "switch2") == 0) + || (strcmp(dma_dev->device_name, "DPlus") == 0)) { + register_dev(dma_dev); + } + + return 0; +} + + +int unregister_dev(struct dma_device_info *dma_dev) +{ + int i, j, temp; + u8 *buffer; + struct rx_desc *rx_desc_p; + + for (i = 0; i < dma_dev->num_rx_chan; i++) { + temp = dma_dev->logic_rx_chan_base + i; + close_channel(temp); + for (j = 0; j < g_log_chan[temp].desc_len; j++) { + rx_desc_p = + (struct rx_desc *) (g_desc_list + + g_log_chan[temp].offset_from_base + j); + buffer = (u8 *) __va(rx_desc_p->Data_Pointer); + g_log_chan[temp].buffer_free(buffer, g_log_chan[temp].opt[j]); + } + } + for (i = 0; i < dma_dev->num_tx_chan; i++) { + temp = dma_dev->logic_tx_chan_base + i; + close_channel(temp); + } + return 0; +} + +int dma_device_unregister(struct dma_device_info *dev) +{ + dev_list *temp_dev; + for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) { + if (strcmp(dev->device_name, temp_dev->dev->device_name) == 0) { + if ((strcmp(dev->device_name, "switch1") == 0) + || (strcmp(dev->device_name, "TPE") == 0) + || (strcmp(dev->device_name, "switch2") == 0) + || (strcmp(dev->device_name, "DPlus") == 0)) + unregister_dev(dev); + if (temp_dev == g_head_dev) { + g_head_dev = temp_dev->next; + kfree(temp_dev); + } else { + if (temp_dev == g_tail_dev) + g_tail_dev = temp_dev->prev; + if (temp_dev->prev) + temp_dev->prev->next = temp_dev->next; + if (temp_dev->next) + temp_dev->next->prev = temp_dev->prev; + kfree(temp_dev); + } + break; + } + + } + return 0; +} + +void dma_device_update_rx(struct dma_device_info *dma_dev) +{ + int i, temp; + for (i = 0; i < dma_dev->num_rx_chan; i++) { + temp = dma_dev->logic_rx_chan_base + i; + g_log_chan[temp].control = dma_dev->rx_chan[i].control; + + if (g_log_chan[temp].control) + open_channel(temp); + else + close_channel(temp); + } + +} + +void dma_device_update_tx(struct dma_device_info *dma_dev) +{ + int i, temp; + for (i = 0; i < dma_dev->num_tx_chan; i++) { + temp = dma_dev->logic_tx_chan_base + i; + g_log_chan[temp].control = dma_dev->tx_chan[i].control; + if (g_log_chan[temp].control) { + /* we turn on channel when send out the very first packet */ + // open_channel(temp); + } else + close_channel(temp); + } +} + +int dma_device_update(struct dma_device_info *dma_dev) +{ + dma_device_update_rx(dma_dev); + dma_device_update_tx(dma_dev); + return 0; +} + +static int dma_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int dma_release(struct inode *inode, struct file *file) +{ + /* release the resources */ + return 0; +} + +static int dma_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + int value = 0; + int result = 0; + int chan_no = 0; + + switch (cmd) { + case 0: /* get register value */ + break; + case 1: /* return channel weight */ + chan_no = *((int *) arg); + *((int *) arg + 1) = g_log_chan[chan_no].default_weight; + break; + case 2: /* set channel weight */ + chan_no = *((int *) arg); + value = *((int *) arg + 1); + printk("new weight=%08x\n", value); + g_log_chan[chan_no].default_weight = value; + break; + default: + break; + } + return result; +} + + +static struct file_operations dma_fops = { + owner:THIS_MODULE, + open:dma_open, + release:dma_release, + ioctl:dma_ioctl, +}; + +static int dma_init(void) +{ + int result = 0; + int i; + printk("initialising dma core\n"); + result = register_chrdev(DMA_MAJOR, "dma-core", &dma_fops); + if (result) { + AMAZON_DMA_EMSG("cannot register device dma-core!\n"); + return result; + } + result = request_irq(AMAZON_DMA_INT, dma_interrupt, SA_INTERRUPT, "dma-core", (void *) &dma_interrupt); + if (result) { + AMAZON_DMA_EMSG("error, cannot get dma_irq!\n"); + free_irq(AMAZON_DMA_INT, (void *) &dma_interrupt); + return -EFAULT; + } + + g_desc_list = (u64 *) KSEG1ADDR(__get_free_page(GFP_DMA)); + + if (g_desc_list == NULL) { + AMAZON_DMA_EMSG("no memory for desriptor\n"); + return -ENOMEM; + } + memset(g_desc_list, 0, PAGE_SIZE); + AMAZON_DMA_REG32(AMAZON_DMA_Desc_BA) = (u32) CPHYSADDR((u32) g_desc_list); + g_amazon_dma_dir = proc_mkdir("amazon_dma", NULL); + create_proc_read_entry("dma_register", 0, g_amazon_dma_dir, dma_register_proc_read, NULL); + create_proc_read_entry("g_desc_list", 0, g_amazon_dma_dir, desc_list_proc_read, NULL); + create_proc_read_entry("channel_weight", 0, g_amazon_dma_dir, channel_weight_proc_read, NULL); + + dma_chip_init(); + for (i = 0; i < (RX_CHAN_NUM + 1); i++) { + rx_chan_list[i] = -1; + } + for (i = 0; i < (TX_CHAN_NUM + 1); i++) { + tx_chan_list[i] = -1; + } + + for (i = 0; i < CHAN_TOTAL_NUM; i++) { + comb_isr_mask[i] = 0x80000000 >> (i); + } + + g_log_chan[CHAN_TOTAL_NUM].weight = 0; + printk("initialising dma core ... done\n"); + + return 0; +} + +arch_initcall(dma_init); + + +void dma_cleanup(void) +{ + dev_list *temp_dev; + + unregister_chrdev(DMA_MAJOR, "dma-core"); + for (temp_dev = g_head_dev; temp_dev; temp_dev = temp_dev->next) { + kfree(temp_dev); + } + free_page(KSEG0ADDR((unsigned long) g_desc_list)); + remove_proc_entry("channel_weight", g_amazon_dma_dir); + remove_proc_entry("dma_list", g_amazon_dma_dir); + remove_proc_entry("dma_register", g_amazon_dma_dir); + remove_proc_entry("amazon_dma", NULL); + /* release the resources */ + free_irq(AMAZON_DMA_INT, (void *) &dma_interrupt); +} + +EXPORT_SYMBOL(dma_device_register); +EXPORT_SYMBOL(dma_device_unregister); +EXPORT_SYMBOL(dma_device_read); +EXPORT_SYMBOL(dma_device_write); +EXPORT_SYMBOL(dma_device_update); +EXPORT_SYMBOL(dma_device_update_rx); + +MODULE_LICENSE("GPL"); diff --git a/target/linux/amazon/files/arch/mips/amazon/dma-core.h b/target/linux/amazon/files/arch/mips/amazon/dma-core.h new file mode 100644 index 0000000000..cb3d456c95 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/dma-core.h @@ -0,0 +1,69 @@ +#ifndef DMA_CORE_H +#define DMA_CORE_H + +#define AMAZON_DMA_REG32(reg_num) *((volatile u32*)(reg_num)) +#define AMAZON_DMA_CH_STEP 4 + +#define COMB_ISR_RX_MASK 0xfe000000 +#define COMB_ISR_TX_MASK 0x01f00000 + + +#define DMA_OWN 1 +#define CPU_OWN 0 +#define DMA_MAJOR 250 + +//Descriptors +#define DMA_DESC_OWN_CPU 0x0 +#define DMA_DESC_OWN_DMA 0x80000000 +#define DMA_DESC_CPT_SET 0x40000000 +#define DMA_DESC_SOP_SET 0x20000000 +#define DMA_DESC_EOP_SET 0x10000000 + +#define switch_rx_chan_base 0 +#define switch_tx_chan_base 7 +#define switch2_rx_chan_base 2 +#define switch2_tx_chan_base 8 +#define TPE_rx_chan_base 4 +#define TPE_tx_chan_base 9 +#define DPLus2FPI_rx_chan_base 6 +#define DPLus2FPI_tx_chan_base 11 + +#define RX_CHAN_NUM 7 +#define TX_CHAN_NUM 5 +#define CHAN_TOTAL_NUM (RX_CHAN_NUM+TX_CHAN_NUM) +#define DEFAULT_OFFSET 20 +#define DESCRIPTOR_SIZE 8 + +typedef struct dev_list{ + struct dma_device_info* dev; + int weight; + struct dev_list* prev; + struct dev_list* next; +}dev_list; + +typedef struct channel_info{ + char device_name[16]; + int occupied; + enum attr_t attr; + int current_desc; + int weight; + int default_weight; + int desc_num; + int burst_len; + int desc_len; + int desc_ofst; + int packet_size; + int offset_from_base; + int control; + void* opt[DEFAULT_OFFSET]; + u8* (*buffer_alloc)(int len,int* offset, void** opt); + int (*buffer_free)(u8* dataptr,void* opt); + int (*intr_handler)(struct dma_device_info* info,int status); + + struct dma_device_info* dma_dev; +}channel_info; + + + +#endif + diff --git a/target/linux/amazon/files/arch/mips/amazon/interrupt.c b/target/linux/amazon/files/arch/mips/amazon/interrupt.c new file mode 100644 index 0000000000..5e34e0577b --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/interrupt.c @@ -0,0 +1,186 @@ +/* + * Gary Jennejohn (C) 2003 <gj@denx.de> + * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org> + * Copyright (C) 2007 John Crispin <blogic@openwrt.org> + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Routines for generic manipulation of the interrupts found on the + * AMAZON boards. + */ + +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> +#include <linux/module.h> + +#include <asm/amazon/amazon.h> +#include <asm/amazon/irq.h> +#include <asm/bootinfo.h> +#include <asm/irq_cpu.h> +#include <asm/irq.h> +#include <asm/time.h> + +static void amazon_disable_irq(unsigned int irq_nr) +{ + int i; + u32 amazon_ier = AMAZON_ICU_IM0_IER; + + if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0) + amazon_writel(amazon_readl(amazon_ier) & (~(AMAZON_DMA_H_MASK)), amazon_ier); + else { + irq_nr -= INT_NUM_IRQ0; + for (i = 0; i <= 4; i++) + { + if (irq_nr <= 31) + amazon_writel(amazon_readl(amazon_ier) & ~(1 << irq_nr ), amazon_ier); + amazon_ier += 0x10; + irq_nr -= 32; + } + } +} + +static void amazon_mask_and_ack_irq(unsigned int irq_nr) +{ + int i; + u32 amazon_ier = AMAZON_ICU_IM0_IER; + u32 amazon_isr = AMAZON_ICU_IM0_ISR; + + if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0){ + amazon_writel(amazon_readl(amazon_ier) & (~(AMAZON_DMA_H_MASK)), amazon_ier); + amazon_writel(AMAZON_DMA_H_MASK, amazon_isr); + } else { + irq_nr -= INT_NUM_IRQ0; + for (i = 0; i <= 4; i++) + { + if (irq_nr <= 31){ + amazon_writel(amazon_readl(amazon_ier) & ~(1 << irq_nr ), amazon_ier); + amazon_writel((1 << irq_nr ), amazon_isr); + } + amazon_ier += 0x10; + amazon_isr += 0x10; + irq_nr -= 32; + } + } +} + +static void amazon_enable_irq(unsigned int irq_nr) +{ + int i; + u32 amazon_ier = AMAZON_ICU_IM0_IER; + + if (irq_nr <= INT_NUM_IM0_IRL11 && irq_nr >= INT_NUM_IM0_IRL0) + amazon_writel(amazon_readl(amazon_ier) | AMAZON_DMA_H_MASK, amazon_ier); + else { + irq_nr -= INT_NUM_IRQ0; + for (i = 0; i <= 4; i++) + { + if (irq_nr <= 31) + amazon_writel(amazon_readl(amazon_ier) | (1 << irq_nr ), amazon_ier); + amazon_ier += 0x10; + irq_nr -= 32; + } + } +} + +static unsigned int amazon_startup_irq(unsigned int irq) +{ + amazon_enable_irq(irq); + return 0; +} + +static void amazon_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + amazon_enable_irq(irq); + } +} + +static struct hw_interrupt_type amazon_irq_type = { + "AMAZON", + .startup = amazon_startup_irq, + .enable = amazon_enable_irq, + .disable = amazon_disable_irq, + .unmask = amazon_enable_irq, + .ack = amazon_mask_and_ack_irq, + .mask = amazon_disable_irq, + .mask_ack = amazon_mask_and_ack_irq, + .end = amazon_end_irq +}; + +/* Cascaded interrupts from IM0-4 */ +static inline void amazon_hw_irqdispatch(u8 line) +{ + u32 irq; + + irq = (amazon_readl(AMAZON_ICU_IM_VEC) >> (line * 5)) & AMAZON_ICU_IM0_VEC_MASK; + if (line == 0 && irq <= 11 && irq >= 0) { + //DMA fixed to IM0_IRL0 + irq = 0; + } + do_IRQ(irq + INT_NUM_IRQ0 + (line * 32)); +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; + if (pending & CAUSEF_IP7){ + do_IRQ(MIPS_CPU_TIMER_IRQ); + goto out; + } else { + unsigned int i; + for (i = 0; i <= 4; i++) + { + if(pending & (CAUSEF_IP2 << i)){ + amazon_hw_irqdispatch(i); + goto out; + } + } + } + printk("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status()); +out: + return; +} + +static struct irqaction cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "cascade", +}; + +void __init arch_init_irq(void) +{ + int i; + + /* mask all interrupt sources */ + for(i = 0; i <= 4; i++){ + amazon_writel(0, AMAZON_ICU_IM0_IER + (i * 0x10)); + } + + mips_cpu_irq_init(); + + /* set up irq cascade */ + for (i = 2; i <= 6; i++) { + setup_irq(i, &cascade); + } + + for (i = INT_NUM_IRQ0; i <= INT_NUM_IM4_IRL31; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + set_irq_chip(i, &amazon_irq_type); + } +} diff --git a/target/linux/amazon/files/arch/mips/amazon/pci.c b/target/linux/amazon/files/arch/mips/amazon/pci.c new file mode 100644 index 0000000000..ab305a983c --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/pci.c @@ -0,0 +1,293 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org> + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ + +/* FIXME: convert nasty volatile register derefs to readl/writel calls */ + +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <asm/io.h> +#include <asm/paccess.h> +#include <asm/amazon/irq.h> +#include <asm/amazon/amazon.h> + +#define AMAZON_PCI_REG32( addr ) (*(volatile u32 *)(addr)) +#ifndef AMAZON_PCI_MEM_BASE +#define AMAZON_PCI_MEM_BASE 0xb2000000 +#endif +#define AMAZON_PCI_MEM_SIZE 0x00400000 +#define AMAZON_PCI_IO_BASE 0xb2400000 +#define AMAZON_PCI_IO_SIZE 0x00002000 + +#define AMAZON_PCI_CFG_BUSNUM_SHF 16 +#define AMAZON_PCI_CFG_DEVNUM_SHF 11 +#define AMAZON_PCI_CFG_FUNNUM_SHF 8 + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +static inline u32 amazon_r32(u32 addr) +{ + u32 *ptr = (u32 *) addr; + return __raw_readl(ptr); +} + +static inline void amazon_w32(u32 addr, u32 val) +{ + u32 *ptr = (u32 *) addr; + __raw_writel(val, ptr); +} + + +static struct resource pci_io_resource = { + .name = "io pci IO space", +#if 0 + .start = AMAZON_PCI_IO_BASE, + .end = AMAZON_PCI_IO_BASE + AMAZON_PCI_IO_SIZE - 1, +#endif + .start = 0, + .end = AMAZON_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + .name = "ext pci memory space", + .start = AMAZON_PCI_MEM_BASE, + .end = AMAZON_PCI_MEM_BASE + AMAZON_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +static inline u32 amazon_pci_swap(u32 val) +{ +#ifdef CONFIG_AMAZON_PCI_HW_SWAP + return swab32(val); +#else + return val; +#endif +} + +static int amazon_pci_config_access(unsigned char access_type, + struct pci_bus *bus, unsigned int devfn, unsigned int where, u32 *data) +{ + unsigned long flags; + u32 pci_addr; + u32 val; + int ret; + + /* Amazon support slot from 0 to 15 */ + /* devfn 0 & 0x20 is itself */ + if ((bus != 0) || (devfn == 0) || (devfn == 0x20)) + return 1; + + pci_addr=AMAZON_PCI_CFG_BASE | + bus->number << AMAZON_PCI_CFG_BUSNUM_SHF | + devfn << AMAZON_PCI_CFG_FUNNUM_SHF | + (where & ~0x3); + + local_irq_save(flags); + if (access_type == PCI_ACCESS_WRITE) { + val = amazon_pci_swap(*data); + ret = put_dbe(val, (u32 *)pci_addr); + } else { + ret = get_dbe(val, (u32 *)pci_addr); + *data = amazon_pci_swap(val); + } + + amazon_w32(PCI_MODE, amazon_r32(PCI_MODE) & (~(1<<PCI_MODE_cfgok_bit))); + amazon_w32(STATUS_COMMAND_ADDR, amazon_r32(STATUS_COMMAND_ADDR)); + amazon_w32(PCI_MODE, amazon_r32(PCI_MODE) | (~(1<<PCI_MODE_cfgok_bit))); + local_irq_restore(flags); + + return ret; +} + + +static int amazon_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) +{ + u32 data = 0; + int ret = PCIBIOS_SUCCESSFUL; + + if (amazon_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) { + data = ~0; + ret = -1; + } + + switch (size) { + case 1: + *((u8 *) val) = (data >> ((where & 3) << 3)) & 0xff; + break; + case 2: + *((u16 *) val) = (data >> ((where & 3) << 3)) & 0xffff; + break; + case 4: + *val = data; + break; + default: + return -1; + } + + return ret; +} + + +static int amazon_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) +{ + if (size != 4) { + u32 data; + + if (amazon_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return -1; + + if (size == 1) + val = (data & ~(0xff << ((where & 3) << 3))) | (val << ((where & 3) << 3)); + else if (size == 2) + val = (data & ~(0xffff << ((where & 3) << 3))) | (val << ((where & 3) << 3)); + else + return -1; + } + + if (amazon_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops amazon_pci_ops = { + amazon_pci_read, + amazon_pci_write +}; + +static struct pci_controller amazon_pci_controller = { + .pci_ops = &amazon_pci_ops, + .mem_resource = &pci_mem_resource, + .io_resource = &pci_io_resource +}; + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + switch (slot) { + case 13: + /* IDSEL = AD29 --> USB Host Controller */ + return INT_NUM_IM2_IRL15; + case 14: + /* IDSEL = AD30 --> mini PCI connector */ + return INT_NUM_IM2_IRL14; + default: + printk("Warning: no IRQ found for PCI device in slot %d, pin %d\n", slot, pin); + return 0; + } +} + +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + switch(dev->irq) { + case INT_NUM_IM2_IRL15: + /* + * IDSEL = AD29 --> USB Host Controller + * PCI_INTA/B/C--GPIO Port0.2--EXIN3 + * IN/ALT0:1 ALT1:0 + * PULL UP + */ + (*AMAZON_GPIO_P0_DIR) = (*AMAZON_GPIO_P0_DIR) & 0xfffffffb; + (*AMAZON_GPIO_P0_ALTSEL0) = (*AMAZON_GPIO_P0_ALTSEL0)| 4; + (*AMAZON_GPIO_P0_ALTSEL1) = (*AMAZON_GPIO_P0_ALTSEL1)& 0xfffffffb; + (*AMAZON_GPIO_P0_PUDSEL) = (*AMAZON_GPIO_P0_PUDSEL) | 4; + (*AMAZON_GPIO_P0_PUDEN) = (*AMAZON_GPIO_P0_PUDEN) | 4; + //External Interrupt Node + (*AMAZON_ICU_EXTINTCR) = (*AMAZON_ICU_EXTINTCR)|0x6000; /* Low Level triggered */ + (*AMAZON_ICU_IRNEN) = (*AMAZON_ICU_IRNEN)|0x8; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + break; + case INT_NUM_IM2_IRL14: + /* + * IDSEL = AD30 --> mini PCI connector + * PCI_INTA--GPIO Port0.1--EXIN2 + * IN/ALT0:1 ALT1:0 + * PULL UP + */ + (*AMAZON_GPIO_P0_DIR) = (*AMAZON_GPIO_P0_DIR) & 0xfffffffd; + (*AMAZON_GPIO_P0_ALTSEL0) = (*AMAZON_GPIO_P0_ALTSEL0)| 2; + (*AMAZON_GPIO_P0_ALTSEL1) = (*AMAZON_GPIO_P0_ALTSEL1)& 0xfffffffd; + (*AMAZON_GPIO_P0_PUDSEL) = (*AMAZON_GPIO_P0_PUDSEL) | 2; + (*AMAZON_GPIO_P0_PUDEN) = (*AMAZON_GPIO_P0_PUDEN) | 2; + //External Interrupt Node + (*AMAZON_ICU_EXTINTCR) = (*AMAZON_ICU_EXTINTCR)|0x600; + (*AMAZON_ICU_IRNEN) = (*AMAZON_ICU_IRNEN)|0x4; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + break; + default: + return 1; + } + return 0; +} + +int amazon_pci_init(void) +{ + u32 temp_buffer; + +#ifdef CONFIG_AMAZON_PCI_HW_SWAP + AMAZON_PCI_REG32(IRM) = AMAZON_PCI_REG32(IRM) | (1<<27) | (1<<28); + wmb(); +#endif + + AMAZON_PCI_REG32(CLOCK_CONTROL) = AMAZON_PCI_REG32(CLOCK_CONTROL) | (1<<ARB_CTRL_bit); + amazon_w32(PCI_MODE, amazon_r32(PCI_MODE) & (~(1<<PCI_MODE_cfgok_bit))); + + AMAZON_PCI_REG32(STATUS_COMMAND_ADDR) = AMAZON_PCI_REG32(STATUS_COMMAND_ADDR) | (1<<BUS_MASTER_ENABLE_BIT) |(1<<MEM_SPACE_ENABLE_BIT); + + temp_buffer = AMAZON_PCI_REG32(PCI_ARB_CTRL_STATUS_ADDR); + temp_buffer = temp_buffer | (1<< INTERNAL_ARB_ENABLE_BIT); + temp_buffer = temp_buffer & ~(3<< PCI_MASTER0_REQ_MASK_2BITS); + temp_buffer = temp_buffer & ~(3<< PCI_MASTER0_GNT_MASK_2BITS); + + /* flash */ + temp_buffer = temp_buffer & ~(3<< PCI_MASTER1_REQ_MASK_2BITS); + temp_buffer = temp_buffer & ~(3<< PCI_MASTER1_GNT_MASK_2BITS); + + /* external master */ + temp_buffer = temp_buffer & ~(3<< PCI_MASTER2_REQ_MASK_2BITS); + temp_buffer = temp_buffer & ~(3<< PCI_MASTER2_GNT_MASK_2BITS); + + AMAZON_PCI_REG32(PCI_ARB_CTRL_STATUS_ADDR) = temp_buffer; + wmb(); + + AMAZON_PCI_REG32(FPI_ADDRESS_MAP_0) = 0xb2000000; + AMAZON_PCI_REG32(FPI_ADDRESS_MAP_1) = 0xb2100000; + AMAZON_PCI_REG32(FPI_ADDRESS_MAP_2) = 0xb2200000; + AMAZON_PCI_REG32(FPI_ADDRESS_MAP_3) = 0xb2300000; + AMAZON_PCI_REG32(FPI_ADDRESS_MAP_4) = 0xb2400000; + AMAZON_PCI_REG32(FPI_ADDRESS_MAP_5) = 0xb2500000; + AMAZON_PCI_REG32(FPI_ADDRESS_MAP_6) = 0xb2600000; + AMAZON_PCI_REG32(FPI_ADDRESS_MAP_7) = 0xb2700000; + + AMAZON_PCI_REG32(BAR11_MASK) = 0x0f000008; + AMAZON_PCI_REG32(PCI_ADDRESS_MAP_11) = 0x0; + AMAZON_PCI_REG32(BAR1_ADDR) = 0x0; + amazon_w32(PCI_MODE, amazon_r32(PCI_MODE) | (~(1<<PCI_MODE_cfgok_bit))); + //use 8 dw burse length + AMAZON_PCI_REG32(FPI_BURST_LENGTH) = 0x303; + + set_io_port_base(ioremap(AMAZON_PCI_IO_BASE, AMAZON_PCI_IO_SIZE)); + register_pci_controller(&amazon_pci_controller); + return 0; +} +arch_initcall(amazon_pci_init); diff --git a/target/linux/amazon/files/arch/mips/amazon/prom.c b/target/linux/amazon/files/arch/mips/amazon/prom.c new file mode 100644 index 0000000000..2947473ad0 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/prom.c @@ -0,0 +1,77 @@ +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright 2007 John Crispin <blogic@openwrt.org> + */ + +#include <linux/init.h> +#include <linux/string.h> +#include <linux/ctype.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/bootmem.h> +#include <linux/ioport.h> +#include <asm/bootinfo.h> +#include <asm/amazon/amazon.h> +#include <asm/amazon/irq.h> +#include <asm/amazon/model.h> +#include <asm/cpu.h> + +void prom_putchar(char c) +{ + /* Wait for FIFO to empty */ + while ((amazon_readl(AMAZON_ASC_FSTAT) >> 8) != 0x00) ; + /* Crude cr/nl handling is better than none */ + if(c == '\n') + amazon_writel('\r', AMAZON_ASC_TBUF); + amazon_writel(c, AMAZON_ASC_TBUF); +} + +void prom_printf(const char * fmt, ...) +{ + va_list args; + int l; + char *p, *buf_end; + char buf[1024]; + + va_start(args, fmt); + /* FIXME - hopefully i < sizeof(buf) */ + l = vsprintf(buf, fmt, args); + va_end(args); + buf_end = buf + l; + + for (p = buf; p < buf_end; p++) + prom_putchar(*p); +} + + +void __init prom_init(void) +{ + mips_machgroup = MACH_GROUP_INFINEON; + mips_machtype = MACH_INFINEON_AMAZON; + + strcpy(&(arcs_cmdline[0]), "console=ttyS0,115200 rootfstype=squashfs,jffs2 init=/etc/preinit"); + + add_memory_region(0x00000000, 0x1000000, BOOT_MEM_RAM); +} + +void prom_free_prom_memory(void) +{ +} + +const char *get_system_type(void) +{ + return BOARD_SYSTEM_TYPE; +} diff --git a/target/linux/amazon/files/arch/mips/amazon/setup.c b/target/linux/amazon/files/arch/mips/amazon/setup.c new file mode 100644 index 0000000000..a96b565c69 --- /dev/null +++ b/target/linux/amazon/files/arch/mips/amazon/setup.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2004 Peng Liu <peng.liu@infineon.com> + * Copyright (C) 2007 John Crispin <blogic@openwrt.org> + * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org> + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/delay.h> + +#include <asm/reboot.h> +#include <asm/system.h> +#include <asm/time.h> +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/amazon/amazon.h> +#include <asm/amazon/irq.h> +#include <asm/amazon/model.h> + +extern void prom_printf(const char * fmt, ...); +static void amazon_reboot_setup(void); + +/* the CPU clock rate - lifted from u-boot */ +unsigned int amazon_get_cpu_hz(void) +{ + /*-----------------------------------*/ + /**CGU CPU Clock Reduction Register***/ + /*-----------------------------------*/ + switch(amazon_readl(AMAZON_CGU_CPUCRD) & 0x3){ + case 0: + /*divider ration 1/1, 235 MHz clock */ + return 235000000; + case 1: + /*divider ration 2/3, 235 MHz clock, clock not accurate, here */ + return 150000000; + case 2: + /*divider ration 1/2, 235 MHz clock */ + return 117500000; + default: + /*divider ration 1/4, 235 MHz clock */ + return 58750000; + } +} + +/* the FPI clock rate - lifted from u-boot */ +unsigned int amazon_get_fpi_hz(void) +{ + unsigned int clkCPU; + clkCPU = amazon_get_cpu_hz(); + + /*-------------------------------------*/ + /***CGU Clock Divider Select Register***/ + /*-------------------------------------*/ + switch (amazon_readl(AMAZON_CGU_DIV) & 0x3) + { + case 1: + return clkCPU >> 1; + case 2: + return clkCPU >> 2; + default: + return clkCPU; + /* '11' is reserved */ + } +} + +/* this doesn't really belong here, but it's a convenient location */ +unsigned int amazon_get_cpu_ver(void) +{ + static unsigned int cpu_ver = 0; + if (cpu_ver == 0) + cpu_ver = amazon_readl(AMAZON_MCD_CHIPID) & 0xFFFFF000; + return cpu_ver; +} + +void amazon_time_init(void) +{ + mips_hpt_frequency = amazon_get_cpu_hz()/2; + printk("mips_hpt_frequency:%d\n", mips_hpt_frequency); +} + +extern int hr_time_resolution; + +/* ISR GPTU Timer 6 for high resolution timer */ +static void amazon_timer6_interrupt(int irq, void *dev_id) +{ + timer_interrupt(AMAZON_TIMER6_INT, NULL); +} + +static struct irqaction hrt_irqaction = { + .handler = amazon_timer6_interrupt, + .flags = SA_INTERRUPT, + .name = "hrt", +}; + +/* + * THe CPU counter for System timer, set to HZ + * GPTU Timer 6 for high resolution timer, set to hr_time_resolution + * Also misuse this routine to print out the CPU type and clock. + */ +void __init plat_timer_setup(struct irqaction *irq) +{ + /* cpu counter for timer interrupts */ + setup_irq(MIPS_CPU_TIMER_IRQ, irq); + + /* enable the timer in the PMU */ + amazon_writel(amazon_readl(AMAZON_PMU_PWDCR)| AMAZON_PMU_PWDCR_GPT|AMAZON_PMU_PWDCR_FPI, AMAZON_PMU_PWDCR); + + /* setup the GPTU for timer tick f_fpi == f_gptu*/ + amazon_writel(0x0100, AMAZON_GPTU_CLC); + amazon_writel(0xffff, AMAZON_GPTU_CAPREL); + amazon_writel(0x80C0, AMAZON_GPTU_T6CON); +} + +void __init plat_mem_setup(void) +{ + u32 chipid = 0; + u32 part_no = 0; + + chipid = amazon_readl(AMAZON_MCD_CHIPID); + part_no = AMAZON_MCD_CHIPID_PART_NUMBER_GET(chipid); + + if(part_no == AMAZON_CHIPID_YANGTSE){ + prom_printf("Yangtse Version\n"); + } else if (part_no == AMAZON_CHIPID_STANDARD) { + prom_printf(SYSTEM_MODEL_NAME "\n"); + } else { + prom_printf("unknown version %8x\n",part_no); + } + + amazon_reboot_setup(); + board_time_init = amazon_time_init; + + //stop reset TPE and DFE + amazon_writel(0, AMAZON_RST_REQ); + //clock + amazon_writel(0x3fff, AMAZON_PMU_PWDCR); + //reenable trace capability + part_no = readl(AMAZON_BCU_ECON); +} + +static void amazon_machine_restart(char *command) +{ + local_irq_disable(); + amazon_writel(AMAZON_RST_ALL, AMAZON_RST_REQ); + for (;;) ; +} + +static void amazon_machine_halt(void) +{ + printk(KERN_NOTICE "System halted.\n"); + local_irq_disable(); + for (;;) ; +} + +static void amazon_machine_power_off(void) +{ + printk(KERN_NOTICE "Please turn off the power now.\n"); + local_irq_disable(); + for (;;) ; +} + +static void amazon_reboot_setup(void) +{ + _machine_restart = amazon_machine_restart; + _machine_halt = amazon_machine_halt; + pm_power_off = amazon_machine_power_off; +} diff --git a/target/linux/amazon/files/drivers/atm/amazon_tpe.c b/target/linux/amazon/files/drivers/atm/amazon_tpe.c new file mode 100644 index 0000000000..cf3e407329 --- /dev/null +++ b/target/linux/amazon/files/drivers/atm/amazon_tpe.c @@ -0,0 +1,3074 @@ +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +//----------------------------------------------------------------------- +/* + * Description: + * Driver for Infineon Amazon TPE + */ +//----------------------------------------------------------------------- +/* Author: peng.liu@infineon.com + * Created: 12-April-2004 + */ +//----------------------------------------------------------------------- +/* History + * Last changed on: 13 Oct. 2004 + * Last changed by: peng.liu@infineon.com + * Last changed on: 28 Jan. 2004 + * Last changed by: peng.liu@infineon.com + * Last changed Reason: + * - AAL5R may send more bytes than expected in MFL (so far, confirmed as 64 bytes) + */ +// 507261:tc.chen 2005/07/26 re-organize code address map to improve performance. +// 507281:tc.chen 2005/07/28 fix f4 segment isssue +/* 511045:linmars 2005/11/04 from Liu.Peng: change NRT_VBR bandwidth calculation based on scr instead of pcr */ + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif + +/*TPE level loopback, bypass AWARE DFE */ +#undef TPE_LOOPBACK + +/* enable debug options */ +#undef AMAZON_ATM_DEBUG + +/* enable rx error packet analysis */ +#undef AMAZON_ATM_DEBUG_RX + +/* test AAL5 Interrupt */ +#undef AMAZON_TPE_TEST_AAL5_INT + +/* dump packet */ +#undef AMAZON_TPE_DUMP + +/* read ARC register*/ +/* this register is located in side DFE module*/ +#undef AMAZON_TPE_READ_ARC + +/* software controlled reassembly */ +#undef AMAZON_TPE_SCR + +/* recovery from AAL5 bug */ +#undef AMAZON_TPE_AAL5_RECOVERY + +#if defined(AMAZON_TPE_READ_ARC) || defined(AMAZON_TPE_AAL5_RECOVERY) +#define ALPHAEUS_BASE_ADDR 0x31c00 +#define A_CFG_ADDR (ALPHAEUS_BASE_ADDR+0x04) +#define AR_CB0_STATUS_ADDR (ALPHAEUS_BASE_ADDR+0x2c) +#define AR_CB1_STATUS_ADDR (ALPHAEUS_BASE_ADDR+0x30) +#define AT_CELL0_ADDR (ALPHAEUS_BASE_ADDR+0x90) +#define AR_CELL0_ADDR (ALPHAEUS_BASE_ADDR+0x1a0) +#define AR_CD_CNT0_ADDR (ALPHAEUS_BASE_ADDR+0x1c8) +#endif + +#include <linux/module.h> +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/fs.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/time.h> +#include <linux/atm.h> +#include <linux/atmdev.h> +#include <linux/netdevice.h> +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/system.h> +#include <asm/atomic.h> +#include <asm/bitops.h> +#include <asm/system.h> + +#include <asm/amazon/amazon.h> +#include <asm/amazon/irq.h> + +#include <linux/in.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/ip.h> +#include <linux/tcp.h> +#include <linux/skbuff.h> +#include <linux/in6.h> +#include <linux/delay.h> +#include <asm/amazon/atm_defines.h> +#include <asm/amazon/amazon_dma.h> +#include <asm/amazon/amazon_tpe.h> + +#if defined(AMAZON_TPE_READ_ARC) || defined(AMAZON_TPE_AAL5_RECOVERY) +#include <asm/amazon/amazon_mei.h> +#include <asm/amazon/amazon_mei_app.h> +#endif + +#define AMAZON_TPE_EMSG(fmt, args...) printk( KERN_ERR "%s: " fmt,__FUNCTION__, ## args) + +/***************************************** External Functions *******************************************/ +extern unsigned int amazon_get_fpi_hz(void); +extern void mask_and_ack_amazon_irq(unsigned int irq_nr); +extern void amz_push_oam(unsigned char *); + +//amazon_mei.c +#if defined(AMAZON_TPE_READ_ARC) || defined(AMAZON_TPE_AAL5_RECOVERY) +extern MEI_ERROR meiDebugRead(u32 srcaddr, u32 *databuff, u32 databuffsize); +extern MEI_ERROR meiDebugWrite(u32 destaddr, u32 *databuff, u32 databuffsize); +#endif + +/***************************************** Internal Functions *******************************************/ +int amazon_atm_read_procmem(char *buf, char **start, off_t offset,int count, int *eof, void *data); +/***************************************** Global Data *******************************************/ +amazon_atm_dev_t g_atm_dev; //device data +static struct tq_struct swex_start_task; //BH task +static struct tq_struct swex_complete_task; //BH task +#ifdef AMAZON_TPE_SCR +static struct tq_struct a5r_task; //BH task +#endif +static struct dma_device_info g_dma_dev; //for DMA +static struct atm_dev * amazon_atm_devs[AMAZON_ATM_PORT_NUM]; +static struct oam_last_activity g_oam_time_stamp[AMAZON_ATM_MAX_VCC_NUM]; +static u8 g_oam_cell[AMAZON_AAL0_SDU+4]; //for OAM cells +#ifdef AMAZON_CHECK_LINK +static int adsl_link_status; //ADSL link status, 0:down, 1:up +#endif //AMAZON_CHECK_LINK +/***************************************** Module Parameters *************************************/ +// Parameter Definition for module +static int port_enable0 = 1; // Variable for parameter port_enable0 +static int port_enable1 = 0; // Variable for parameter port_enable1 +static int port_max_conn0 = 15; // Variable for parameter port_max_conn0 +static int port_max_conn1 = 0; // Variable for parameter port_max_conn1 +static int port_cell_rate_up0 = 7500; // Variable for parameter port_cell_rate_up0 +static int port_cell_rate_up1 = 7500; // Variable for parameter port_cell_rate_up1 + + +static int qsb_tau = 1; // Variable for parameter qsb_tau +static int qsb_srvm = 0xf; // Variable for parameter qsb_srvm +static int qsb_tstep = 4 ; // Variable for parameter qsb_tstep + +static int cbm_nrt = 3900; // Variable for parameter cbm_nrt +static int cbm_clp0 =3500; // Variable for parameter cbm_clp0 +static int cbm_clp1 =3200; // Variable for parameter cbm_clp1 +static int cbm_free_cell_no = AMAZON_ATM_FREE_CELLS; // Variable for parameter cbm_free_cell_no + +static int a5_fill_pattern = 0x7e; // Variable for parameter a5_fill_pattern '~' +static int a5s_mtu = 0x700; // mtu for tx +static int a5r_mtu = 0x700; // mtu for rx + +static int oam_q_threshold = 64; // oam queue threshold, minium value 64 +static int rx_q_threshold = 1000; // rx queue threshold, minium value 64 +static int tx_q_threshold = 800; // tx queue threshold, minium value 64 + +MODULE_PARM(port_max_conn0, "i"); +MODULE_PARM_DESC(port_max_conn0, "Maximum atm connection for port #0"); +MODULE_PARM(port_max_conn1, "i"); +MODULE_PARM_DESC(port_max_conn1, "Maximum atm connection for port #1"); +MODULE_PARM(port_enable0, "i"); +MODULE_PARM_DESC(port_enable0, "0 -> port disabled, 1->port enabled"); +MODULE_PARM(port_enable1, "i"); +MODULE_PARM_DESC(port_enable1, "0 -> port disabled, 1->port enabled"); +MODULE_PARM(port_cell_rate_up0, "i"); +MODULE_PARM_DESC(port_cell_rate_up0, "ATM port upstream rate in cells/s"); +MODULE_PARM(port_cell_rate_up1, "i"); +MODULE_PARM_DESC(port_cell_rate_up1, "ATM port upstream rate in cells/s"); + +MODULE_PARM(qsb_tau,"i"); +MODULE_PARM_DESC(qsb_tau, "Cell delay variation. value must be > 0"); +MODULE_PARM(qsb_srvm, "i"); +MODULE_PARM_DESC(qsb_srvm, "Maximum burst size"); +MODULE_PARM(qsb_tstep, "i"); +MODULE_PARM_DESC(qsb_tstep, "n*32 cycles per sbs cycles n=1,2,4"); + +MODULE_PARM(cbm_nrt, "i"); +MODULE_PARM_DESC(cbm_nrt, "Non real time threshold for cell buffer"); +MODULE_PARM(cbm_clp0, "i"); +MODULE_PARM_DESC(cbm_clp0, "Threshold for cells with cell loss priority 0"); +MODULE_PARM(cbm_clp1, "i"); +MODULE_PARM_DESC(cbm_clp1, "Threshold for cells with cell loss priority 1"); +MODULE_PARM(cbm_free_cell_no, "i"); +MODULE_PARM_DESC(cbm_free_cell_no, "Number of cells in the cell buffer manager"); + +MODULE_PARM(a5_fill_pattern, "i"); +MODULE_PARM_DESC(a5_fill_pattern, "filling pattern (PAD) for aal5 frames"); +MODULE_PARM(a5s_mtu, "i"); +MODULE_PARM_DESC(a5s_mtu, "max. SDU for upstream"); +MODULE_PARM(a5r_mtu, "i"); +MODULE_PARM_DESC(a5r_mtu, "max. SDU for downstream"); + +MODULE_PARM(oam_q_threshold, "i"); +MODULE_PARM_DESC(oam_q_threshold, "oam queue threshold"); + +MODULE_PARM(rx_q_threshold, "i"); +MODULE_PARM_DESC(rx_q_threshold, "downstream/rx queue threshold"); + +MODULE_PARM(tx_q_threshold, "i"); +MODULE_PARM_DESC(tx_q_threshold, "upstream/tx queue threshold"); + +/***************************************** local functions *************************************/ +/* Brief: valid QID + * Return: 1 if valid + * 0 if not + */ +static inline int valid_qid(int qid) +{ + return ( (qid>0) && (qid<AMAZON_ATM_MAX_QUEUE_NUM)); +} + +/* + * Brief: align to 16 bytes boundary + * Parameter: + * skb + * Description: + * use skb_reserve to adjust the data pointer + * don't change head pointer + * pls allocate extrac 16 bytes before call this function + */ +static void inline alloc_align_16(struct sk_buff * skb) +{ + if ( ( ((u32) (skb->data)) & 15) != 0){ + AMAZON_TPE_DMSG("need to adjust the alignment manually\n"); + skb_reserve(skb, 16 - (((u32) (skb->data)) & 15) ); + } + +} + +/* + * Brief: initialize the device according to the module paramters + * Return: not NULL - ok + * NULL - fails + * Description: arrange load parameters and call the hardware initialization routines + */ +static void atm_init_parameters(amazon_atm_dev_t *dev) +{ + //port setting + dev->ports[0].enable = port_enable0; + dev->ports[0].max_conn = port_max_conn0; + dev->ports[0].tx_max_cr = port_cell_rate_up0; + if (port_enable1){ + dev->ports[1].enable = port_enable1; + dev->ports[1].max_conn = port_max_conn1; + dev->ports[1].tx_max_cr = port_cell_rate_up1; + } + + //aal5 + dev->aal5.padding_byte = a5_fill_pattern; + dev->aal5.tx_max_sdu = a5s_mtu; + dev->aal5.rx_max_sdu = a5r_mtu; + + //cbm + dev->cbm.nrt_thr = cbm_nrt; + dev->cbm.clp0_thr = cbm_clp0; + dev->cbm.clp1_thr = cbm_clp1; + dev->cbm.free_cell_cnt = cbm_free_cell_no; + + //qsb + dev->qsb.tau = qsb_tau; + dev->qsb.tstepc =qsb_tstep; + dev->qsb.sbl = qsb_srvm; + + //allocate on the fly + dev->cbm.mem_addr = NULL; + dev->cbm.qd_addr = NULL; +} + + +/* Brief: Find QID for VCC + * Parameters: vcc - VCC data structure + * Return Value: -EINVAL - VCC not found + * qid - QID for this VCC + * Description: + * This function returns the QID of a given VCC + */ +static int amazon_atm_get_queue(struct atm_vcc* vcc) +{ + int i; + for (i=0;i<AMAZON_ATM_MAX_QUEUE_NUM;i++) { + if (g_atm_dev.queues[i].vcc == vcc) return i; + } + return -EINVAL; +} + + +/* + * Brief: Find QID for VPI/VCI + * Parameters: vpi - VPI to found + * vci - VCI to found + * + * Return Value: -EINVAL - VPI/VCI not found + * qid - QID for this VPI/VCI + * + * Description: + * This function returns the QID for a given VPI/VCI. itf doesn't matter + */ +static int amazon_atm_find_vpivci(u8 vpi, u16 vci) +{ + int i; + struct atm_vcc * vcc; + for (i=0;i<AMAZON_ATM_MAX_QUEUE_NUM;i++) { + if ( (vcc = g_atm_dev.queues[i].vcc)!= NULL) { + if ((vcc->vpi == vpi) && (vcc->vci == vci)) return i; + } + } + return -EINVAL; +} + +/* Brief: Find QID for VPI + * Parameters: vpi - VPI to found + * Return Value: -EINVAL - VPI not found + * qid - QID for this VPI + * + * Description: + * This function returns the QID for a given VPI. itf and VCI don't matter + */ +static int amazon_atm_find_vpi(u8 vpi) +{ + int i; + for (i=0;i<AMAZON_ATM_MAX_QUEUE_NUM;i++) { + if ( g_atm_dev.queues[i].vcc!= NULL) { + if (g_atm_dev.queues[i].vcc->vpi == vpi) return i; + } + } + return -EINVAL; +} + +/* + * Brief: Clears QID entries for VCC + * + * Parameters: vcc - VCC to found + * + * Description: + * This function searches for the given VCC and sets it to NULL if found. + */ +static inline void amazon_atm_clear_vcc(int i) +{ + g_atm_dev.queues[i].vcc = NULL; + g_atm_dev.queues[i].free = 1; +} + + +/* + * Brief: dump skb data + */ +static inline void dump_skb(u32 len, char * data) +{ +#ifdef AMAZON_TPE_DUMP + int i; + for(i=0;i<len;i++){ + printk("%2.2x ",(u8)(data[i])); + if (i % 16 == 15) + printk("\n"); + } + printk("\n"); +#endif +} + +/* + * Brief: dump queue descriptor + */ +static inline void dump_qd(int qid) +{ +#ifdef AMAZON_TPE_DUMP + u8 * qd_addr; + if (valid_qid(qid) != 1) return; + qd_addr = (u8 *) KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr); + AMAZON_TPE_EMSG("qid: %u [%8x][%8x][%8x][%8x]\n", qid + ,readl(qd_addr+qid*CBM_QD_SIZE+0x0) + ,readl(qd_addr+qid*CBM_QD_SIZE+0x4) + ,readl(qd_addr+qid*CBM_QD_SIZE+0x8) + ,readl(qd_addr+qid*CBM_QD_SIZE+0xc)); +#endif +} + +/* + * Brief: release TX skbuff + */ +static inline void amazon_atm_free_tx_skb_vcc(struct atm_vcc *vcc, struct sk_buff *skb) +{ + if ( vcc->pop != NULL) { + vcc->pop(vcc, skb); + } else { + dev_kfree_skb_any(skb); + } +} +/* + * Brief: release TX skbuff + */ +static inline void amazon_atm_free_tx_skb(struct sk_buff *skb) +{ + struct atm_vcc* vcc = ATM_SKB(skb)->vcc; + if (vcc!=NULL){ + amazon_atm_free_tx_skb_vcc(vcc,skb); + } else { + dev_kfree_skb_any(skb);//fchang:Added + } +} + +/* Brief: divide by 64 and round up + */ +static inline u32 divide_by_64_round_up(int input) +{ + u32 tmp1; + tmp1 = (u32) input; + tmp1 = (tmp1%64)?(tmp1/64 + 1): (tmp1/64); + if (tmp1 == 0) tmp1 = 1; + return tmp1; +} + +/* + * Brief: statistics + */ +#ifdef AMAZON_ATM_DEBUG +static inline void queue_statics(int qid, qs_t idx) +{ + if (valid_qid(qid)){ + g_atm_dev.queues[qid].qs[idx]++; + } +} +#else //not AMAZON_ATM_DEBUG +static inline void queue_statics(int qid, qs_t idx){} +#endif //AMAZON_ATM_DEBUG + + +/* Brief: set dma tx full, i.e. there is no available descriptors + */ +static void inline atm_dma_full(void) +{ + AMAZON_TPE_DMSG("ch0 is full\n"); + atomic_set(&g_atm_dev.dma_tx_free_0,0); +} + +/* + * Brief set dma tx free (at least one descript is available) + */ +inline static void atm_dma_free(void) +{ + AMAZON_TPE_DMSG("ch0 is free\n"); + atomic_set(&g_atm_dev.dma_tx_free_0,1); +} + + +/* Brief: return the status of DMA TX descriptors + * Parameters: TX channel (DMA_TX_CH0, TX_CH1) + * Return: + * 1: there are availabel TX descriptors + * 0: no available + * Description: + * + */ +inline int dma_may_send(int ch) +{ + if (atomic_read(&g_atm_dev.dma_tx_free_0)){ + return 1; + } + return 0; +} + +/******************************* global functions *********************************/ +/* + * Brief: SWIE Cell Extraction Start Routine + * and task routine for swex_complete_task + * Parameters: irq_stat - interrupt status + * + * Description: + * This is the routine for extracting cell. It will schedule itself if the hardware is busy. + * This routine runs in interrupt context + */ +void amazon_atm_swex(void * irq_stat) +{ + u32 ex_stat=0; + u32 addr; + // Read extraction status register + ex_stat = readl(CBM_HWEXSTAT0_ADDR); + + // Check if extraction/insertion is in progress + if ( (ex_stat & CBM_EXSTAT_SCB) || (ex_stat & CBM_EXSTAT_FB) || (test_and_set_bit(SWIE_LOCK, &(g_atm_dev.swie.lock))!=0)) { + AMAZON_TPE_DMSG(" extraction in progress. Will wait\n"); + swex_start_task.data = irq_stat; + queue_task(&swex_start_task, &tq_immediate); + mark_bh(IMMEDIATE_BH); + }else { + // Extract QID + g_atm_dev.swie.qid = (((u32)irq_stat) >> 24); + AMAZON_TPE_DMSG("extracting from qid=%u\n",g_atm_dev.swie.qid); + //read status word + addr = KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr); + addr = readl((addr + g_atm_dev.swie.qid * 0x10 + 4) & 0xFFFFFFC0); + addr = KSEG1ADDR(addr); + g_atm_dev.swie.sw = readl(addr+52)&SWIE_ADDITION_DATA_MASK; + AMAZON_TPE_DMSG("cell addition word: %8x \n", g_atm_dev.swie.sw); + + // Start extraction + AMAZON_WRITE_REGISTER_L(g_atm_dev.swie.qid | SWIE_CBM_PID_SUBADDR, CBM_HWEXPAR0_ADDR); + AMAZON_WRITE_REGISTER_L(SWIE_CBM_SCE0, CBM_HWEXCMD_ADDR); + } +} +#ifdef AMAZON_TPE_SCR +u32 g_a5r_wait=0; +/* + * Brief: AAL5 Packet Extraction Routine and task routine for a5r_task + * Parameters: irq_stat - interrupt status + * + * Description: + * This is the routine for extracting frame. It will schedule itself if the hardware is busy. + * This routine runs in interrupt context + */ +void amazon_atm_a5r(void* qid) +{ + volatile u32 ex_stat=0; + u32 addr; + u32 a5r_wait=0; + + ex_stat = readl(CBM_HWEXSTAT0_ADDR); +#if 0 + // Check if extraction/insertion is in progress + if ( (ex_stat & CBM_EXSTAT_SCB) || (ex_stat & CBM_EXSTAT_FB) ) { + AMAZON_TPE_DMSG(" extraction in progress. Will wait\n"); + a5r_task.data = qid; + queue_task(&a5r_task, &tq_immediate); + mark_bh(IMMEDIATE_BH); + }else { + AMAZON_TPE_DMSG("extracting from qid=%u\n",(u8)qid); + // Start extraction + AMAZON_WRITE_REGISTER_L(((u8)qid) | CBM_HWEXPAR_PN_A5, CBM_HWEXPAR0_ADDR); + AMAZON_WRITE_REGISTER_L(CBM_HWEXCMD_FE0, CBM_HWEXCMD_ADDR); + } +#else + //while ( (ex_stat & CBM_EXSTAT_SCB) || (ex_stat & CBM_EXSTAT_FB) ) { + while ( ex_stat != 0x80){ + a5r_wait++; + ex_stat = readl(CBM_HWEXSTAT0_ADDR); +#if 0 + if (a5r_wait >= 0xffffff){ + a5r_wait=0; + printk("."); + } +#endif + } + if (a5r_wait > g_a5r_wait){ + g_a5r_wait = a5r_wait; + } + AMAZON_WRITE_REGISTER_L(((u8)qid) | CBM_HWEXPAR_PN_A5, CBM_HWEXPAR0_ADDR); + AMAZON_WRITE_REGISTER_L(CBM_HWEXCMD_FE0, CBM_HWEXCMD_ADDR); +#endif +} + +#endif //AMAZON_TPE_SCR + +/* Brief: Handle F4/F5 OAM cell + * Return: + * 0 ok + * <0 fails + */ +static int inline amazon_handle_oam_cell(void *data, u8 vpi, u16 vci,u32 status) +{ + struct atm_vcc* vcc=NULL; + int qid; + if (!status&SWIE_EOAM_MASK){ + AMAZON_TPE_EMSG("unknown cell received, discarded\n"); + goto amazon_handle_oam_cell_err_exit; + }else if (status&SWIE_ECRC10ERROR_MASK){ + AMAZON_TPE_EMSG("CRC-10 Error Status:%8x, discarded\n", status); + goto amazon_handle_oam_cell_err_exit; + }else{ + if(status & (SWIE_EVCI3_MASK |SWIE_EVCI4_MASK)){ + //F4 level (VPI) OAM, Assume duplex + qid = amazon_atm_find_vpi(vpi)+CBM_RX_OFFSET; + }else if (status & (SWIE_EPTI4_MASK|SWIE_EPTI5_MASK)){ + //F5 level (VCI) OAM, Assume duplex + qid = amazon_atm_find_vpivci(vpi,vci)+CBM_RX_OFFSET; + }else{ + qid = -1; + AMAZON_TPE_EMSG("non-F4/F5 OAM cells?, discarded\n"); + goto amazon_handle_oam_cell_err_exit; + } + } + if (valid_qid(qid) && ((vcc = g_atm_dev.queues[qid].vcc)!=NULL)){ + //TODO, should we do this for ALL OAM types? (Actually only User and CC) + g_atm_dev.queues[qid].access_time=xtime; + if (vcc->push_oam){ + (*vcc->push_oam)(vcc,data); + }else{ + amz_push_oam(data); + } + }else{ + AMAZON_TPE_EMSG("no VCC yet\n"); + goto amazon_handle_oam_cell_err_exit; + } + return 0; +amazon_handle_oam_cell_err_exit: + dump_skb(AMAZON_AAL0_SDU,(char *)data); + return -1; +} + +/* Brief: SWIE Cell Extraction Finish Routine + * and task routine for swex_complete_task + * Description: + * 1.Allocate a buffer of type struct sk_buff + * 2.Copy the data from the temporary memory to this buffer + * 3.Push the data to upper layer + * 4.Update the statistical data if necessary + * 5.Release the temporary data + + */ +void amazon_atm_swex_push(void * data) +{ + struct atm_vcc* vcc=NULL; + struct sk_buff* skb=NULL; + struct amazon_atm_cell_header * cell_header; + u32 status; + int qid; + if (!data){ + AMAZON_TPE_EMSG("data is NULL\n"); + return; + } + qid = ((u8*)data)[AMAZON_AAL0_SDU]; + status = ((u32*)data)[ATM_AAL0_SDU/4]; + cell_header = (struct amazon_atm_cell_header *) data; + if (valid_qid(qid) != 1){ + AMAZON_TPE_EMSG("error qid: %u\n",qid); + AMAZON_TPE_EMSG("unknown cells recieved\n"); + }else if (qid == AMAZON_ATM_OAM_Q_ID){ + //OAM or RM or OTHER cell + //Find real connection + +#ifdef IKOS_MINI_BOOT + //for OAM loop back test + dump_skb(56,(char *)data); + //kfree(data); using g_oam_cell + return; +#endif //IKOS_MINI_BOOT +#ifdef TPE_LOOPBACK + amz_push_oam(data); + return; +#endif//TPE_LOOPBACK + int ret = 0; + ret = amazon_handle_oam_cell(data,cell_header->bit.vpi,cell_header->bit.vci,status); + if (ret == 0) + return; + }else{ + //should be normal AAL0 cells + // Get VCC + vcc = g_atm_dev.queues[qid].vcc; + if (vcc != NULL) { + AMAZON_TPE_DMSG("push to upper layer\n"); + skb = dev_alloc_skb(AMAZON_AAL0_SDU); + if (skb != NULL) { + //skb->dev=vcc->dev; + memcpy(skb_put(skb, AMAZON_AAL0_SDU), data, AMAZON_AAL0_SDU); + skb->stamp = xtime; + ATM_SKB(skb)->vcc = vcc; + (*g_atm_dev.queues[qid].push)(vcc,skb,0); + }else{ + AMAZON_TPE_EMSG(" No memory left for incoming AAL0 cell! Cell discarded!\n"); + //inform the upper layer + (*g_atm_dev.queues[qid].push)(vcc,skb,-ENOMEM); + atomic_inc(&vcc->stats->rx_drop); + } + }else{ + AMAZON_TPE_EMSG("invalid qid %u\n",qid); + } + } + //kfree(data); using g_oam_cell +} + +/* + * Brief: Interrupt handler for software cell extraction (done) + * Parameters: irq - CPPN for this interrupt + * data - Device ID for this interrupt + * regs - Register file + * + * Description: + * When a software extraction is finished this interrupt is issued. + * It reads the cell data and sends it to the ATM stack. + */ +void amazon_atm_swex_isr(int irq, void *data, struct pt_regs *regs) +{ + u32 * cell = NULL; + int i; + //ATM_AAL0 SDU + QID + AMAZON_TPE_DMSG("SWIE extraction done\n"); + cell = (u32 *) g_oam_cell; + if (cell != NULL){ + //convert to host byte order from big endian + for(i=0;i<ATM_AAL0_SDU;i+=4){ + cell[i/4]=readl(SWIE_ECELL_ADDR+i); + } + cell[ATM_AAL0_SDU/4]= g_atm_dev.swie.sw; + ((u8*)cell)[AMAZON_AAL0_SDU] = g_atm_dev.swie.qid; +#ifdef IKOS_MINI_BOOT + for(i=0;i<ATM_AAL0_SDU;i+=4){ + AMAZON_TPE_DMSG("[%2x][%2x][%2x][%2x]\n", + ((char*)cell)[i], + ((char*)cell)[i+1], + ((char*)cell)[i+2], + ((char*)cell)[i+3] + ); + } + AMAZON_TPE_DMSG("qid: %u\n", ((u8*)cell)[AMAZON_AAL0_SDU]); + amazon_atm_swex_push((void *) cell); +#else //not IKOS_MINI_BOOT + swex_complete_task.data = cell; + queue_task(&swex_complete_task,&tq_immediate); + mark_bh(IMMEDIATE_BH); +#endif //not IKOS_MINI_BOOT + }else{ + AMAZON_TPE_EMSG("no memory for receiving AAL0 cell\n"); + } + + /* release the lock and check */ + if (test_and_clear_bit(SWIE_LOCK,&(g_atm_dev.swie.lock)) == 0){ + AMAZON_TPE_EMSG("swie lock is already released\n"); + } + wake_up(&g_atm_dev.swie.sleep); +} +/* Brief: Interrupt handler for software cell insertion + * + * Parameters: irq - CPPN for this interrupt + * data - Device ID for this interrupt + * regs - Register file + * + * Description: + * When a software insertion is finished this interrupt is issued. + * The only purpose is to release the semaphore and read the status register. + */ +void amazon_atm_swin_isr(int irq, void *data, struct pt_regs *regs) +{ + AMAZON_TPE_DMSG("SWIE insertion done\n"); + /* release the lock and check */ + if (test_and_clear_bit(SWIE_LOCK,&(g_atm_dev.swie.lock)) == 0){ + AMAZON_TPE_EMSG("swie lock is already released"); + } + // Release semaphore + up(&g_atm_dev.swie.in_sem); + +} +/* Brief: Interrupt handler for software cell insertion & extraction + * Parameters: irq - CPPN for this interrupt + * data - Device ID for this interrupt + * regs - Register file + * Description: + * When a software insertion or extractionis finished this interrupt is issued. + */ +void amazon_atm_swie_isr(int irq, void *data, struct pt_regs *regs) +{ + u32 status=0; + // Read status register + status = readl(SWIE_ISTAT_ADDR); + AMAZON_TPE_DMSG("insertion status: %8x\n", status); + if (status & SWIE_ISTAT_DONE){ + //clear interrupt in peripheral and ICU + AMAZON_WRITE_REGISTER_L(SRC_TOS_MIPS | SRC_CLRR|SRC_SRE_ENABLE | AMAZON_SWIE_INT, SWIE_ISRC_ADDR); + mask_and_ack_amazon_irq(AMAZON_SWIE_INT); + + amazon_atm_swin_isr(irq,data,regs); + } + status = readl(SWIE_ESTAT_ADDR); + AMAZON_TPE_DMSG("extraction status: %8x\n", status); + if (status & SWIE_ESTAT_DONE){ + //clear interrupt + AMAZON_WRITE_REGISTER_L(SRC_TOS_MIPS | SRC_CLRR|SRC_SRE_ENABLE | AMAZON_SWIE_INT, SWIE_ESRC_ADDR); + mask_and_ack_amazon_irq(AMAZON_SWIE_INT); + + amazon_atm_swex_isr(irq,data,regs); + } + //clear interrupt in ICU +} + +/* + * Brief: Insert ATM cell into CBM + * Parameters: queue - Target queue + * cell - Pointer to cell data + * Return Value: EBUSY - CBM is busy + * 0 - OK, cell inserted + * Description: + * This function inserts a cell into the CBM using the software insertion + * method. The format of the cell should be + * Little Endian (address starting from 0) + * H3, H2, H1, H0, P3, P2, P1, P0, P7, P6, P5, P4, ..., P47, P46, P45, P44 + * Big Endian (address starting from 0) + * H0, H1, H2, H3, P0, P1, P2, P3, P4, P5, P6, P7, ..., P44, P45, P46, P47 + * This function does not free memory!!! + */ +int amazon_atm_swin(u8 queue, void* cell) +{ + u32 status=0; + int i; + // Read status register + status = readl(SWIE_ISTAT_ADDR); + AMAZON_TPE_DMSG(" SWIE status=0x%08x\n",status); + + AMAZON_TPE_DMSG(" Inserting cell qid=%u\n",queue); + +#ifdef AMAZON_CHECK_LINK + if (adsl_link_status == 0){ + return -EFAULT; + } +#endif //AMAZON_CHECK_LINK + + // Get semaphore (if possible) + if (down_interruptible(&g_atm_dev.swie.in_sem)) { + return -ERESTARTSYS; + } + /* try to set lock */ + wait_event_interruptible(g_atm_dev.swie.sleep,(test_and_set_bit(SWIE_LOCK,&(g_atm_dev.swie.lock)) == 0)); + if (signal_pending(current)){ + return -ERESTARTSYS; + } + + // Store cell in CBM memory + for(i=0;i<ATM_AAL0_SDU;i+=4){ + AMAZON_WRITE_REGISTER_L(((u32*)cell)[i/4],SWIE_ICELL_ADDR+i); + } + //Store queue id + AMAZON_WRITE_REGISTER_L((u32) queue,SWIE_IQID_ADDR); + + //Start SWIE + AMAZON_WRITE_REGISTER_L(SWIE_ICMD_START,SWIE_ICMD_ADDR); + + return 0; +} + +#ifdef AMAZON_ATM_DEBUG +/* + * Brief: Interrupt handler for HTU + * + * Parameters: irq - CPPN for this interrupt + * data - Device ID for this interrupt + * regs - Register file + * + */ +void amazon_atm_htu_isr(int irq, void *data, struct pt_regs *regs) +{ + u32 irq_stat=0; + + // Read interrupt status register + irq_stat = readl(HTU_ISR0_ADDR); + AMAZON_TPE_DMSG("HTU status: %8x\n",irq_stat); + //Clear interrupt in CBM and ICU + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_HTU_INT, HTU_SRC0_ADDR); + mask_and_ack_amazon_irq(AMAZON_HTU_INT); + // Check if Any Cell Arrived + if (irq_stat & (HTU_ISR_NE | HTU_ISR_PNE) ) { + AMAZON_TPE_EMSG("INFNOENTRY %8x\n", readl(HTU_INFNOENTRY_ADDR)); + }else if (irq_stat & (HTU_ISR_TORD|HTU_ISR_PT)){ + AMAZON_TPE_EMSG("Time Out %8x\n", readl(HTU_INFTIMEOUT_ADDR)); + }else if (irq_stat & HTU_ISR_IT){ + AMAZON_TPE_EMSG("Interrupt Test\n"); + }else if (irq_stat & HTU_ISR_OTOC){ + AMAZON_TPE_EMSG("Overflow of Time Out Counter\n"); + }else if (irq_stat & HTU_ISR_ONEC){ + AMAZON_TPE_EMSG("Overflow of No Entry Counter\n"); + }else{ + AMAZON_TPE_EMSG("unknown HTU interrupt occurs %8x\n", irq_stat); + } + +} +#endif //AMAZON_ATM_DEBUG + +#ifdef AMAZON_TPE_TEST_AAL5_INT +/* + * Brief: Interrupt handler for AAL5 + * + * Parameters: irq - CPPN for this interrupt + * data - Device ID for this interrupt + * regs - Register file + * + */ +void amazon_atm_aal5_isr(int irq, void *data, struct pt_regs *regs) +{ + volatile u32 irq_stat=0; + + // Read interrupt status register + irq_stat = readl(AAL5_SISR0_ADDR); + if (irq_stat){ + AMAZON_TPE_EMSG("A5S status: %8x\n",irq_stat); + //Clear interrupt in CBM and ICU + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_AAL5_INT, AAL5_SSRC0_ADDR); + mask_and_ack_amazon_irq(AMAZON_AAL5_INT); + } + irq_stat = readl(AAL5_RISR0_ADDR); + if (irq_stat){ + AMAZON_TPE_EMSG("A5R status: %8x\n",irq_stat); + //Clear interrupt in CBM and ICU + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_AAL5_INT, AAL5_RSRC0_ADDR); + mask_and_ack_amazon_irq(AMAZON_AAL5_INT); + } +} +#endif //AMAZON_TPE_TEST_AAL5_INT + +/* + * Brief: Interrupt handler for CBM + * + * Parameters: irq - CPPN for this interrupt + * data - Device ID for this interrupt + * regs - Register file + * + * Description: + * This is the MIPS interrupt handler for the CBM. It processes incoming cells + * for SWIE queues. + */ +void amazon_atm_cbm_isr(int irq, void *data, struct pt_regs *regs) +{ + u32 irq_stat=0; + u8 qid=0; + + // Read interrupt status register + while ( (irq_stat = readl(CBM_INTINF0_ADDR))){ + AMAZON_TPE_DMSG("CBM INT status: %8x\n",irq_stat); + //Clear interrupt in CBM and ICU + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_CBM_INT, CBM_SRC0_ADDR); + qid = (u8) ((irq_stat & CBM_INTINF0_QID_MASK)>>CBM_INTINF0_QID_SHIFT); +#ifdef AMAZON_TPE_SCR + if (irq_stat & CBM_INTINF0_EF){ + amazon_atm_a5r((void*)qid); + } +#endif + // Check if Any Cell Arrived + if (irq_stat & CBM_INTINF0_ACA) { + amazon_atm_swex((void *)irq_stat); + } + //TX AAL5 PDU discard + if (irq_stat & CBM_INTINF0_OPF){ + if ( (qid) < CBM_RX_OFFSET ){ + g_atm_dev.mib_counter.tx_drop++; + } + queue_statics(qid, QS_HW_DROP); + } + if (irq_stat & (CBM_INTINF0_ERR|CBM_INTINF0_Q0E|CBM_INTINF0_Q0I|CBM_INTINF0_RDE)){ + AMAZON_TPE_EMSG("CBM INT status: %8x\n",irq_stat); + if (irq_stat & CBM_INTINF0_ERR){ + AMAZON_TPE_EMSG("CBM Error: FPI Bus Error\n"); + } + if (irq_stat & CBM_INTINF0_Q0E){ + AMAZON_TPE_EMSG("CBM Error: Queue 0 Extract\n"); + } + if (irq_stat & CBM_INTINF0_Q0I){ + AMAZON_TPE_EMSG("CBM Error: Queue 0 Extract\n"); + } + if (irq_stat & CBM_INTINF0_RDE){ + AMAZON_TPE_EMSG("CBM Error: Read Empty Queue %u\n",qid); + dump_qd(qid); + } + } + } + mask_and_ack_amazon_irq(AMAZON_CBM_INT); +} + +/* Brief: check the status word after AAL SDU after reassembly + */ +static inline void check_aal5_error(u8 stw0, u8 stw1, int qid) +{ + if (stw0 & AAL5_STW0_MFL){ + AMAZON_TPE_DMSG("Maximum Frame Length\n"); + g_atm_dev.queues[qid].aal5VccOverSizedSDUs++; + } + if (stw0 & AAL5_STW0_CRC){ + AMAZON_TPE_DMSG("CRC\n"); + g_atm_dev.queues[qid].aal5VccCrcErrors++; + } +#ifdef AMAZON_ATM_DEBUG_RX + AMAZON_TPE_EMSG("qid:%u stw0:%8x stw1:%8x\n",qid,stw0,stw1); +#endif +} + +/* Brief: Process DMA rx data + * Parameters: + dma_dev: pointer to the dma_device_info, provided by us when register the dma device + * Return: no + * Description: DMA interrupt handerl with OoS support. It is called when there is some data in rx direction. + * + */ +//507261:tc.chen void atm_process_dma_rx(struct dma_device_info* dma_dev) +void __system atm_process_dma_rx(struct dma_device_info* dma_dev) +{ + u8 * head=NULL; + u32 length=0; + u8 stw0=0; + u8 stw1=0; + + struct sk_buff * skb=NULL; + struct atm_vcc * vcc=NULL; + int qid=0; +#ifdef AMAZON_ATM_DEBUG_RX + static int dma_rx_dump=0; + static u32 seq=0; + + seq++; + if (dma_rx_dump>0){ + printk("\n=========================[%u]=========================\n",seq); + } +#endif + length=dma_device_read(dma_dev,&head,(void**)&skb); + AMAZON_TPE_DMSG("receive %8p[%u] from DMA\n", head,length); + if (head == NULL||length<=0) { + AMAZON_TPE_DMSG("dma_read null \n"); + goto error_exit; + } + + if (length > (g_atm_dev.aal5.rx_max_sdu+64)){ + AMAZON_TPE_EMSG("received packet too large (%u)\n",length); + goto error_exit; + } + //check AAL5R trail for error and qid + //last byte is qid + length--; + qid = (int) head[length]; + AMAZON_TPE_DMSG("head[%u] qid %u\n",length, qid); + //STW0 is always 4 bytes before qid + length -= 4; + stw0 = head[length]&0xff; + AMAZON_TPE_DMSG("head[%u] stw0 %8x\n",length, stw0); + //position of STW1 depends on the BE bits + length = length-4 + (stw0&AAL5_STW0_BE); + stw1 = head[length]&0xff; + AMAZON_TPE_DMSG("head[%u] stw1 %8x\n",length, stw1); + if ( (stw0 & AAL5_STW0_MASK) || (stw1 & AAL5_STW1_MASK) ){ + //AAL5 Error + check_aal5_error(stw0, stw1,qid); + goto error_exit; + } + //make data pointers consistent + //UU + CPI + length -= 2; + AMAZON_TPE_DMSG("packet length %u\n", length); + + //error: cannot restore the qid + if (valid_qid(qid) != 1){ + AMAZON_TPE_EMSG("received frame in invalid qid %u!\n", qid); + goto error_exit; + } + vcc = g_atm_dev.queues[qid].vcc; + if (vcc == NULL){ + AMAZON_TPE_EMSG("received frame in invalid vcc, qid=%u!\n",qid); + goto error_exit; + } + if (skb == NULL){ + AMAZON_TPE_EMSG("cannot restore skb pointer!\n"); + goto error_exit; + } + skb_put(skb,length); + skb->stamp = xtime; + g_atm_dev.queues[qid].access_time=xtime; + if ((*g_atm_dev.queues[qid].push)(vcc,skb,0)){ + g_atm_dev.mib_counter.rx_drop++; + queue_statics(qid, QS_SW_DROP); + }else{ + g_atm_dev.mib_counter.rx++; + adsl_led_flash();//joelin adsl led + queue_statics(qid, QS_PKT); + AMAZON_TPE_DMSG("push successful!\n"); + } +#ifdef AMAZON_ATM_DEBUG_RX + if (dma_rx_dump>0){ + printk("\nOK packet [dump=%u] length=%u\n",dma_rx_dump,length); + dump_skb(length+7, head); + } + if (dma_rx_dump >0) dma_rx_dump--; +#endif + return ; +error_exit: +#ifdef AMAZON_ATM_DEBUG_RX + if ( (head!=NULL) && (length >0)){ + AMAZON_TPE_EMSG("length=%u\n",length); + dump_skb(length+5, head); + } + dma_rx_dump++; +#endif + g_atm_dev.mib_counter.rx_err++; + queue_statics(qid, QS_ERR); + /* + if (vcc){ + (*g_atm_dev.queues[qid].push)(vcc,skb,1); + } + */ + if (skb != NULL) { + dev_kfree_skb_any(skb); + } + return; +} + +/*Brief: ISR for DMA pseudo interrupt + *Parameter: + dma_dev: pointer to the dma_device_info, provided by us when register the dma device + intr_status: + RCV_INT: rx data available + TX_BUF_FULL_INT: tx descriptor run out of + TRANSMIT_CPT_INT: tx descriptor available again + *Return: + 0 for success??? + */ +//507261:tc.chen int amazon_atm_dma_handler(struct dma_device_info* dma_dev, int intr_status) +int __system amazon_atm_dma_handler(struct dma_device_info* dma_dev, int intr_status) +{ + AMAZON_TPE_DMSG("status:%u\n",intr_status); + switch (intr_status) { + case RCV_INT: + atm_process_dma_rx(dma_dev); + break; + case TX_BUF_FULL_INT: + //TX full: no descriptors + atm_dma_full(); + break; + case TRANSMIT_CPT_INT: + //TX free: at least one descriptor + atm_dma_free(); + break; + default: + AMAZON_TPE_EMSG("unknown status!\n"); + } + return 0; +} + +/*Brief: free buffer for DMA tx + *Parameter: + dataptr: pointers to data buffer + opt: optional parameter, used to convey struct skb pointer, passwd in dma_device_write + *Return: + 0 for success??? + *Description: + called by DMA module to release data buffer after DMA tx transaction + *Error: + cannot restore skb pointer + */ +int amazon_atm_free_tx(u8*dataptr, void* opt) +{ + struct sk_buff *skb; + if (opt){ + AMAZON_TPE_DMSG("free skb%8p\n",opt); + skb = (struct sk_buff *)opt; + amazon_atm_free_tx_skb(skb); + }else{ + AMAZON_TPE_EMSG("BUG: cannot restore skb pointer!\n"); + } + return 0; +} + +/*Brief: allocate buffer & do alignment + */ +inline struct sk_buff * amazon_atm_alloc_buffer(int len) +{ + struct sk_buff *skb; + skb = dev_alloc_skb(len+16); + if (skb){ + //alignment requriements (4x32 bits (16 bytes) boundary) + alloc_align_16(skb); + } + return skb; +} + +/*Brief: allocate buffer for DMA rx + *Parameter: + len: length + opt: optional data to convey the skb pointer, which will be returned to me in interrupt handler, + *Return: + pointer to buffer, NULL means error? + *Description: + must make sure byte alignment + */ + +u8* amazon_atm_alloc_rx(int len, int* offset, void **opt) +{ + struct sk_buff *skb; + *offset = 0; + skb = amazon_atm_alloc_buffer(len); + if (skb){ + AMAZON_TPE_DMSG("alloc skb->data:%8p len:%u\n",skb->data,len); + *(struct sk_buff**)opt = skb; + }else{ + AMAZON_TPE_DMSG("no memory for receiving atm frame!\n"); + return NULL; + } + return skb->data; +} + + + + +/* Brief: Allocate kernel memory for sending a datagram. + * Parameters + * vcc virtual connection + * size data buffer size + * Return: + * NULL fail + * sk_buff a pointer to a sk_buff + * Description: + * This function can allocate our own additional memory for AAL5S inbound + * header (8bytes). We have to replace the protocol default one (alloc_tx in /net/atm/common.c) + * when we open the device. + * byte alignment is done is DMA driver. + */ +struct sk_buff *amazon_atm_alloc_tx(struct atm_vcc *vcc,unsigned int size) +{ + struct sk_buff *skb; + + if (!dma_may_send(DMA_TX_CH0)){ + AMAZON_TPE_EMSG("no DMA descriptor available!\n"); + return NULL; + } + //AAL5 inbound header space + alignment extra buffer + size+=8+AAL5S_INBOUND_HEADER; + + if (atomic_read(&vcc->tx_inuse) && !atm_may_send(vcc,size)) { + AMAZON_TPE_EMSG("Sorry tx_inuse = %u, size = %u, sndbuf = %u\n", + atomic_read(&vcc->tx_inuse),size,vcc->sk->sndbuf); + return NULL; + } + + skb = amazon_atm_alloc_buffer(size); + if (skb == NULL){ + AMAZON_TPE_EMSG("no memory\n"); + return NULL; + } + AMAZON_TPE_DMSG("dev_alloc_skb(%u) = %x\n", skb->len, (u32)skb); + AMAZON_TPE_DMSG("tx_inuse %u += %u\n",atomic_read(&vcc->tx_inuse),skb->truesize); + atomic_add(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse); + + //reserve for AAL5 inbound header + skb_reserve(skb,AAL5S_INBOUND_HEADER); + return skb; +} + + +/* Brief: change per queue QSB setting according to vcc qos parameters + * Paramters: + * vcc: atm_vcc pointer + * qid: CBM queue id (1~15) + * Return: + */ +static inline void set_qsb(struct atm_vcc *vcc, struct atm_qos *qos, int qid) +{ + qsb_qptl_t qptl; + qsb_qvpt_t qvpt; + u32 tmp=0; + unsigned int qsb_clk; + + qsb_clk = amazon_get_fpi_hz()>>1; + + AMAZON_TPE_EMSG("Class=%u MAX_PCR=%u PCR=%u MIN_PCR=%u SCR=%u MBS=%u CDV=%u\n" + ,qos->txtp.traffic_class + ,qos->txtp.max_pcr + ,qos->txtp.pcr + ,qos->txtp.min_pcr + ,qos->txtp.scr + ,qos->txtp.mbs + ,qos->txtp.cdv + ); + + // PCR limiter + if (qos->txtp.max_pcr == 0){ + qptl.bit.tprs = 0; /* 0 disables the PCR limiter */ + }else { + // peak cell rate will be slightly lower than requested (maximum rate / pcr)= (qsbclock/2^3 * timestep/4)/pcr + tmp = (( (qsb_clk * g_atm_dev.qsb.tstepc)>>5)/ qos->txtp.max_pcr ) + 1; + // check if an overfow occured + if (tmp > QSB_TP_TS_MAX) { + AMAZON_TPE_EMSG("max_pcr is too small, max_pcr:%u tprs:%u\n",qos->txtp.max_pcr, tmp); + qptl.bit.tprs = QSB_TP_TS_MAX; + }else{ + qptl.bit.tprs = tmp; + } + } + //WFQ + if (qos->txtp.traffic_class == ATM_CBR || qos->txtp.traffic_class ==ATM_VBR_RT){ + // real time queue gets weighted fair queueing bypass + qptl.bit.twfq = 0; + }else if (qos->txtp.traffic_class ==ATM_VBR_NRT ||qos->txtp.traffic_class ==ATM_UBR_PLUS ){ + // wfq calculation here are based on virtual cell rates, to reduce granularity for large rates + // wfq factor is maximum cell rate / garenteed cell rate. + //qptl.bit.twfq = g_atm_dev.qsb.min_cr * QSB_WFQ_NONUBR_MAX / qos->txtp.min_pcr; + if (qos->txtp.min_pcr == 0) { + AMAZON_TPE_EMSG("<warning> MIN_PCR should not be zero\n"); + qptl.bit.twfq = QSB_WFQ_NONUBR_MAX; + }else{ + tmp = QSB_GCR_MIN * QSB_WFQ_NONUBR_MAX / qos->txtp.min_pcr; + if (tmp == 0 ){ + qptl.bit.twfq = 1; + }else if (tmp > QSB_WFQ_NONUBR_MAX){ + AMAZON_TPE_EMSG("min_pcr is too small, min_pcr:%u twfq:%u\n",qos->txtp.min_pcr, tmp); + qptl.bit.twfq = QSB_WFQ_NONUBR_MAX; + }else{ + qptl.bit.twfq = tmp; + } + } + }else if (qos->txtp.traffic_class == ATM_UBR){ + // ubr bypass, twfq set to maximum value + qptl.bit.twfq = QSB_WFQ_UBR_BYPASS; + }else{ + //tx is diabled, treated as UBR + AMAZON_TPE_EMSG("<warning> unsupported traffic class %u \n", qos->txtp.traffic_class); + qos->txtp.traffic_class = ATM_UBR; + qptl.bit.twfq = QSB_WFQ_UBR_BYPASS; + } + + //SCR Leaky Bucket Shaper VBR.0/VBR.1 + if (qos->txtp.traffic_class ==ATM_VBR_RT || qos->txtp.traffic_class ==ATM_VBR_NRT){ + if (qos->txtp.scr == 0){ + //SCR == 0 disable the shaper + qvpt.bit.ts = 0; + qvpt.bit.taus = 0; + }else{ + //CLP + if (vcc->atm_options&ATM_ATMOPT_CLP){ + //CLP1 + qptl.bit.vbr = 1; + }else{ + //CLP0 + qptl.bit.vbr = 0; + } + //TS and TauS + tmp = (( (qsb_clk * g_atm_dev.qsb.tstepc)>>5)/ qos->txtp.scr ) + 1; + if (tmp > QSB_TP_TS_MAX) { + AMAZON_TPE_EMSG("scr is too small, scr:%u ts:%u\n",qos->txtp.scr, tmp); + qvpt.bit.ts = QSB_TP_TS_MAX; + }else{ + qvpt.bit.ts = tmp; + } + tmp = (qos->txtp.mbs - 1)*(qvpt.bit.ts - qptl.bit.tprs)/64; + if (tmp > QSB_TAUS_MAX){ + AMAZON_TPE_EMSG("mbs is too large, mbr:%u taus:%u\n",qos->txtp.mbs, tmp); + qvpt.bit.taus = QSB_TAUS_MAX; + }else if (tmp == 0){ + qvpt.bit.taus = 1; + }else{ + qvpt.bit.taus = tmp; + } + } + }else{ + qvpt.w0 = 0; + } + //write the QSB Queue Parameter Table (QPT) + AMAZON_WRITE_REGISTER_L(QSB_QPT_SET_MASK,QSB_RTM_ADDR); + AMAZON_WRITE_REGISTER_L(qptl.w0, QSB_RTD_ADDR); + AMAZON_WRITE_REGISTER_L((QSB_TABLESEL_QPT<<QSB_TABLESEL_SHIFT) + | QSB_RAMAC_REG_LOW + | QSB_WRITE + | qid + ,QSB_RAMAC_ADDR); + //write the QSB Queue VBR Parameter Table (QVPT) + AMAZON_WRITE_REGISTER_L(QSB_QVPT_SET_MASK,QSB_RTM_ADDR); + AMAZON_WRITE_REGISTER_L(qvpt.w0, QSB_RTD_ADDR); + AMAZON_WRITE_REGISTER_L((QSB_TABLESEL_QVPT<<QSB_TABLESEL_SHIFT) + | QSB_RAMAC_REG_LOW + | QSB_WRITE + | qid + ,QSB_RAMAC_ADDR); + AMAZON_TPE_EMSG("tprs:%u twfq:%u ts:%u taus:%u\n",qptl.bit.tprs,qptl.bit.twfq,qvpt.bit.ts,qvpt.bit.taus); +} + +/* + * Brief: create/change CBM queue descriptor + * Parameter: + * vcc: atm_vcc pointer + * qid: CBM queue id (1~15) + */ +static inline void set_qd(struct atm_vcc *vcc, u32 qid) +{ + u32 tx_config=0,rx_config=0; + u32 itf = (u32) vcc->itf; + u32 dma_qos=0; + u8 * qd_addr=NULL; + + tx_config|=CBM_QD_W3_WM_EN|CBM_QD_W3_CLPt; + //RT: check if the connection is a real time connection + if (vcc->qos.txtp.traffic_class == ATM_CBR || vcc->qos.txtp.traffic_class == ATM_VBR_RT){ + tx_config|= CBM_QD_W3_RT; + }else{ + tx_config|= CBM_QD_W3_AAL5; //don't set the AAL5 flag if it is a RT service + } + rx_config = tx_config; + + if(vcc->qos.aal == ATM_AAL5){ + //QoS: DMA QoS according to the traffic class + switch (vcc->qos.txtp.traffic_class){ + case ATM_CBR: dma_qos = CBR_DMA_QOS;break; + case ATM_VBR_RT: dma_qos = VBR_RT_DMA_QOS;break; + case ATM_VBR_NRT: dma_qos = VBR_NRT_DMA_QOS;break; + case ATM_UBR_PLUS: dma_qos = UBR_PLUS_DMA_QOS;break; + case ATM_UBR: dma_qos = UBR_DMA_QOS;break; + } + + //TX: upstream, AAL5(EPD or PPD), NOINT, SBid + tx_config |= CBM_QD_W3_DIR_UP|CBM_QD_W3_INT_NOINT|(itf&CBM_QD_W3_SBID_MASK); + //RX: DMA QoS, downstream, no interrupt, AAL5(EPD, PPD), NO INT, HCR +#ifdef AMAZON_TPE_SCR + rx_config |= dma_qos|CBM_QD_W3_DIR_DOWN|CBM_QD_W3_INT_EOF; +#else + rx_config |= dma_qos|CBM_QD_W3_DIR_DOWN|CBM_QD_W3_INT_NOINT|CBM_QD_W3_HCR; +#endif + }else { + //should be AAL0 + //upstream, NOINT, SBid + tx_config |= CBM_QD_W3_DIR_UP|CBM_QD_W3_INT_NOINT|(itf&CBM_QD_W3_SBID_MASK); + //RX: downstream, ACA interrupt, + rx_config |= CBM_QD_W3_DIR_DOWN|CBM_QD_W3_INT_ACA; + } + + //Threshold: maximum threshold for tx/rx queue, which is adjustable in steps of 64 cells + tx_config |= ( (divide_by_64_round_up(tx_q_threshold)&0xffff)<<CBM_QD_W3_THRESHOLD_SHIFT) & CBM_QD_W3_THRESHOLD_MASK; + rx_config |= ( (divide_by_64_round_up(rx_q_threshold)&0xffff)<<CBM_QD_W3_THRESHOLD_SHIFT) & CBM_QD_W3_THRESHOLD_MASK; + + qd_addr = (u8*) KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr); + //TX + AMAZON_WRITE_REGISTER_L(tx_config, (qd_addr+qid*CBM_QD_SIZE + 0xc)); + AMAZON_WRITE_REGISTER_L(0, (qd_addr+qid*CBM_QD_SIZE + 0x8)); + //RX + AMAZON_WRITE_REGISTER_L(rx_config, (qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE + 0xc)); + AMAZON_WRITE_REGISTER_L(0, (qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE + 0x8)); +} +/* + * Brief: add HTU table entry + * Parameter: + * vpi.vci: + * qid: CBM queue id (DEST is qid + CBM_RX_OFFSET) + * idx: entry id (starting from zero to 14) + * Return: + * 0: sucessful + * EIO: HTU table entry cannot be written + */ + +inline int set_htu_entry(u8 vpi, u16 vci, u8 qid, u8 idx) +{ + int i = 0; + u32 tmp1=0; + while ((tmp1 = readl(HTU_RAMSTAT_ADDR))!=0 && i < 1024) i++; + if (i > 1024) + { + AMAZON_TPE_EMSG("timeout\n"); + return -EIO; + } + // write address register, + AMAZON_WRITE_REGISTER_L(idx, HTU_RAMADDR_ADDR); + // configure transmit queue + tmp1 = vpi<<24|vci<<8; + tmp1|= HTU_RAMDAT1_VCON // valid connection the entry is not validated here !!!!!!!!!!!!!!!! + |HTU_RAMDAT1_VCI3 // vci3 -> oam queue + |HTU_RAMDAT1_VCI4 // vci4 -> oam queue + |HTU_RAMDAT1_VCI6 // vci6 -> rm queue + |HTU_RAMDAT1_PTI4 // pti4 -> oam queue + |HTU_RAMDAT1_PTI5; // pti5 -> oam queue + + // ramdat 1 (in params & oam handling) + AMAZON_WRITE_REGISTER_L( tmp1, HTU_RAMDAT1_ADDR); + // ramdat 2 (out params & oam handling) + tmp1 = ((qid+CBM_RX_OFFSET)&HTU_RAMDAT2_QID_MASK) + |HTU_RAMDAT2_PTI6 + |HTU_RAMDAT2_PTI7 + |HTU_RAMDAT2_F4U + |HTU_RAMDAT2_F5U + ; + AMAZON_WRITE_REGISTER_L( tmp1, HTU_RAMDAT2_ADDR); + wmb(); + // write HTU entry + AMAZON_WRITE_REGISTER_L(HTU_RAMCMD_WR, HTU_RAMCMD_ADDR); + return 0; +} +/* + * Brief: add HTU table entry + * Parameter: + * vcc: atm_vcc pointer + * qid: CBM queue id + * Return: + * 0: sucessful + * EIO: HTU table entry cannot be written + */ +inline static int set_htu(struct atm_vcc *vcc, u32 qid) +{ + return set_htu_entry(vcc->vpi, vcc->vci, qid, (qid - CBM_DEFAULT_Q_OFFSET)); +} + +/* + * Brief: allocate a queue + * Return: + * <=0 no available queues + * >0 qid + */ +static int atm_allocate_q(short itf) +{ + int i; + u32 tmp1=0; + int qid=0; + amazon_atm_port_t * dev; + dev = &g_atm_dev.ports[itf]; + //find start queue id for this interface + for (i=0; i< itf; i++) + { + qid+= g_atm_dev.ports[i].max_conn; + } + // apply default queue offset ( oam, free cell queue, others, rm ) + qid += CBM_DEFAULT_Q_OFFSET; + tmp1 = qid; + // search for a free queue + while ( (qid<tmp1+dev->max_conn) + && ( g_atm_dev.queues[qid].free != 1)) { + qid++;; + } + // if none was found, send failure message and return + if ( tmp1+dev->max_conn == qid) + { + return -EFAULT; + } + return qid; + +} +/* Brief: open a aal5 or aal0 connection + */ +static int atm_open(struct atm_vcc *vcc, push_back_t push) +{ + int err=0; + int qid=0; + amazon_atm_port_t * port = & g_atm_dev.ports[vcc->itf]; + unsigned long flags; + /***************** check bandwidth ******************/ + /* 511045:linmars change ATM_VBR_NRT to use scr instead of pcr */ + if ((vcc->qos.txtp.traffic_class==ATM_CBR&&vcc->qos.txtp.max_pcr>port->tx_rem_cr) + ||(vcc->qos.txtp.traffic_class==ATM_VBR_RT&&vcc->qos.txtp.max_pcr>port->tx_rem_cr) + ||(vcc->qos.txtp.traffic_class==ATM_VBR_NRT&&vcc->qos.txtp.scr>port->tx_rem_cr) + ||(vcc->qos.txtp.traffic_class==ATM_UBR_PLUS&&vcc->qos.txtp.min_pcr>port->tx_rem_cr) + ) { + AMAZON_TPE_EMSG("not enough bandwidth left (%u) cells per seconds \n",port->tx_rem_cr); + return -EINVAL; + } + if ( (qid = amazon_atm_find_vpivci(vcc->vpi, vcc->vci)) >0 ){ + AMAZON_TPE_EMSG("vpi:%u vci:%u is alreay open on queue:%u\n", vcc->vpi, vcc->vci, qid); + return -EADDRINUSE; + } + + /***************** allocate entry queueID for this port *****************/ + if ( (qid=atm_allocate_q(vcc->itf)) <= 0){ + AMAZON_TPE_EMSG("port: %u max:%u qid: %u\n", vcc->itf, port->max_conn, qid); + AMAZON_TPE_EMSG("no availabel connections for this port:%u\n",vcc->itf); + return -EINVAL; + } + /**************QSB parameters and CBM descriptors*************/ + set_qsb(vcc, &vcc->qos, qid); + set_qd(vcc, qid); + mb(); + err=set_htu(vcc,qid); + if (err){ + AMAZON_TPE_EMSG("set htu entry fails %u\n",err); + return err; + } + /************set internal mapping*************/ + local_irq_save(flags); + g_atm_dev.queues[qid].free = 0; + g_atm_dev.queues[qid].vcc = vcc; + g_atm_dev.queues[qid].push = push; + g_atm_dev.queues[qid+CBM_RX_OFFSET].free = 0; + g_atm_dev.queues[qid+CBM_RX_OFFSET].vcc = vcc; + g_atm_dev.queues[qid+CBM_RX_OFFSET].push = push; + /******************reserve bandwidth**********************/ + if (vcc->qos.txtp.traffic_class == ATM_CBR){ + //CBR, real time connection, reserve PCR + port->tx_cur_cr += vcc->qos.txtp.max_pcr; + port->tx_rem_cr -= vcc->qos.txtp.max_pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_VBR_RT){ + //VBR_RT, real time connection, reserve PCR + port->tx_cur_cr += vcc->qos.txtp.max_pcr; + port->tx_rem_cr -= vcc->qos.txtp.max_pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_VBR_NRT){ + //VBR_NRT, reserve SCR + port->tx_cur_cr += vcc->qos.txtp.pcr; + port->tx_rem_cr -= vcc->qos.txtp.pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_UBR_PLUS){ + //UBR_PLUS, reserve MCR + port->tx_cur_cr += vcc->qos.txtp.min_pcr; + port->tx_rem_cr -= vcc->qos.txtp.min_pcr; + } + local_irq_restore(flags); + return err; +} +/* Brief: Open ATM connection + * Parameters: atm_vcc - Pointer to VCC data structure + * vpi - VPI value for new connection + * vci - VCI value for new connection + * + * Return: 0 - sucessful + * -ENOMEM - No memory available + * -EINVAL - No bandwidth/queue/ or unsupported AAL type + * Description: + * This function opens an ATM connection on a specific device/interface + * + */ +int amazon_atm_open(struct atm_vcc *vcc,push_back_t push) +{ + int err=0; + + AMAZON_TPE_DMSG("vpi %u vci %u itf %u aal %u\n" + ,vcc->vpi + ,vcc->vci + ,vcc->itf + ,vcc->qos.aal + ); + + AMAZON_TPE_DMSG("tx cl %u bw %u mtu %u\n" + ,vcc->qos.txtp.traffic_class + ,vcc->qos.txtp.max_pcr + ,vcc->qos.txtp.max_sdu + ); + AMAZON_TPE_DMSG("rx cl %u bw %u mtu %u\n" + ,vcc->qos.rxtp.traffic_class + ,vcc->qos.rxtp.max_pcr + ,vcc->qos.rxtp.max_sdu + ); + if (vcc->qos.aal == ATM_AAL5 || vcc->qos.aal == ATM_AAL0){ + err = atm_open(vcc,push); + }else{ + AMAZON_TPE_EMSG("unsupported aal type %u\n", vcc->qos.aal); + err = -EPROTONOSUPPORT; + }; + if (err == 0 ){ + //replace the default memory allocation function with our own + vcc->alloc_tx = amazon_atm_alloc_tx; + set_bit(ATM_VF_READY,&vcc->flags); + } + return err; +} + +/* Brief: Send ATM OAM cell + * Parameters: atm_vcc - Pointer to VCC data structure + * skb - Pointer to sk_buff structure, that contains the data + * Return: 0 - sucessful + * -ENOMEM - No memory available + * -EINVAL - Not supported + * Description: + * This function sends a cell over and ATM connection + * We always release the skb + * TODO: flags handling (ATM_OF_IMMED, ATM_OF_INRATE) + */ +int amazon_atm_send_oam(struct atm_vcc *vcc, void * cell, int flags) +{ + int err=0; + int qid=0; + struct amazon_atm_cell_header * cell_header; + // Get cell header + cell_header = (struct amazon_atm_cell_header*) cell; + if ((cell_header->bit.pti == ATM_PTI_SEGF5) || (cell_header->bit.pti == ATM_PTI_E2EF5)) { + qid = amazon_atm_find_vpivci( cell_header->bit.vpi, cell_header->bit.vci); + }else if (cell_header->bit.vci == 0x3 || cell_header->bit.vci == 0x4) { + //507281:tc.chen qid = amazon_atm_find_vpi((int) cell_header->bit.vpi); + // 507281:tc.chen start + u8 f4_vpi; + f4_vpi = cell_header->bit.vpi; + qid = amazon_atm_find_vpi(f4_vpi ); + // 507281:tc.chen end + }else{ + //non-OAM cells, always invalid + qid = -EINVAL; + } + if (qid == -EINVAL) { + err = -EINVAL; + AMAZON_TPE_EMSG("not valid AAL0 packet\n"); + }else{ + //send the cell using swie +#ifdef TPE_LOOPBACK + err = amazon_atm_swin(AMAZON_ATM_OAM_Q_ID, cell); +#else + err = amazon_atm_swin(qid, cell); +#endif + } + //kfree(cell); + return err; +} + +/* Brief: Send AAL5 frame through DMA + * Parameters: vpi - virtual path id + * vci - virtual circuit id + * clp - cell loss priority + * qid - CBM queue to be sent to + * skb - packet to be sent + * Return: 0 - sucessful + * -ENOMEM - No memory available + * -EINVAL - Not supported + * Description: + * This function sends a AAL5 frame over and ATM connection + * 1. make sure that the data is aligned to 4x32-bit boundary + * 2. provide the inbound data (CPCS-UU and CPI, not used here) + * 3. set CLPn + * 4. send the frame by DMA + * 5. release the buffer ??? + ** use our own allocation alloc_tx + ** we make sure the alignment and additional memory + *** we always release the skb + + */ +int amazon_atm_dma_tx(u8 vpi, u16 vci, u8 clp, u8 qid, struct sk_buff *skb) +{ + int err=0,need_pop=1; + u32 * data=NULL; + int nwrite=0; + struct sk_buff *skb_tmp; + u32 len=skb->len; + + //AAL5S inbound header 8 bytes + if (skb->len > g_atm_dev.aal5.tx_max_sdu - AAL5S_INBOUND_HEADER) { + AMAZON_TPE_DMSG("tx_max_sdu:%u\n",g_atm_dev.aal5.tx_max_sdu); + AMAZON_TPE_DMSG("skb too large [%u]!\n",skb->len); + err = -EMSGSIZE; + goto atm_dma_tx_error_exit; + } + + //Check the byte alignment requirement and header space + if ( ( ((u32)(skb->data)%16) !=AAL5S_INBOUND_HEADER)|| (skb_headroom(skb)<AAL5S_INBOUND_HEADER)){ + //not aligned or no space for header, fall back to memcpy + skb_tmp = dev_alloc_skb(skb->len+16); + if (skb_tmp==NULL){ + err = - ENOMEM; + goto atm_dma_tx_error_exit; + } + alloc_align_16(skb_tmp); + g_atm_dev.aal5.cnt_cpy++; + skb_reserve(skb_tmp,AAL5S_INBOUND_HEADER); + memcpy(skb_put(skb_tmp,skb->len), skb->data, skb->len); + amazon_atm_free_tx_skb(skb); + need_pop=0; + skb = skb_tmp; + } + //Provide AAL5S inbound header + data = (u32 *)skb_push(skb,8); + data[0] = __be32_to_cpu(vpi<<20|vci<<4|clp); + data[1] = __be32_to_cpu(g_atm_dev.aal5.padding_byte<<8|qid); + + len = skb->len; + + //send through DMA + AMAZON_TPE_DMSG("AAL5S header 0 %8x\n", data[0]); + AMAZON_TPE_DMSG("AAL5S header 0 %8x\n", data[1]); + AMAZON_TPE_DMSG("about to call dma_write len: %u\n", len); + nwrite=dma_device_write( &g_dma_dev,skb->data,len,skb); + if (nwrite != len) { + //DMA descriptors full +// AMAZON_TPE_EMSG("AAL5 packet drop due to DMA nwrite:%u skb->len:%u\n", nwrite,len); + AMAZON_TPE_DMSG("AAL5 packet drop due to DMA nwrite:%u skb->len:%u\n", nwrite,len); + err = -EAGAIN; + goto atm_dma_tx_drop_exit; + } + AMAZON_TPE_DMSG("just finish call dma_write\n"); + //release in the "dma done" call-back + return 0; +atm_dma_tx_error_exit: + g_atm_dev.mib_counter.tx_err++; + queue_statics(qid, QS_ERR); + goto atm_dma_tx_exit; + +atm_dma_tx_drop_exit: + g_atm_dev.mib_counter.tx_drop++; + queue_statics(qid, QS_SW_DROP); +atm_dma_tx_exit: + if (need_pop){ + amazon_atm_free_tx_skb(skb); + }else{ + dev_kfree_skb_any(skb); + } + return err; +} + +/* Brief: Send AAL0/AAL5 packet + * Parameters: atm_vcc - Pointer to VCC data structure + * skb - Pointer to sk_buff structure, that contains the data + * Return: 0 - sucessful + * -ENOMEM - No memory available + * -EINVAL - Not supported + * Description: + * See amazon_atm_dma_tx + */ +int amazon_atm_send(struct atm_vcc *vcc,struct sk_buff *skb) +{ + int qid=0; + u8 clp=0; + int err=0; + u32 wm=0; + + if (vcc == NULL || skb == NULL){ + AMAZON_TPE_EMSG("invalid parameter\n"); + return -EINVAL; + } + ATM_SKB(skb)->vcc = vcc; + qid = amazon_atm_get_queue(vcc); + if (valid_qid(qid) != 1) { + AMAZON_TPE_EMSG("invalid vcc!\n"); + err = -EINVAL; + goto atm_send_err_exit; + } + + //Send AAL0 using SWIN + if (vcc->qos.aal == ATM_AAL0){ +#ifdef TPE_LOOPBACK + err=amazon_atm_swin((qid+CBM_RX_OFFSET), skb->data); +#else + err=amazon_atm_swin(qid, skb->data); +#endif + if (err){ + goto atm_send_err_exit; + } + goto atm_send_exit; + } + + //Should be AAl5 + //MIB counter + g_atm_dev.mib_counter.tx++; + adsl_led_flash();//joelin adsl led + queue_statics(qid, QS_PKT); + +#ifdef AMAZON_CHECK_LINK + //check adsl link + if (adsl_link_status == 0){ + //link down + AMAZON_TPE_DMSG("ADSL link down, discarded!\n"); + err=-EFAULT; + goto atm_send_drop_exit; + } +#endif + clp = (vcc->atm_options&ATM_ATMOPT_CLP)?1:0; + //check watermark first + wm = readl(CBM_WMSTAT0_ADDR); + if ( (wm & (1<<qid)) + ||( (vcc->qos.txtp.traffic_class != ATM_CBR + &&vcc->qos.txtp.traffic_class != ATM_VBR_RT) + &(wm & (CBM_WM_NRT_MASK | (clp&CBM_WM_CLP1_MASK)) ))){ + //wm hit: discard + AMAZON_TPE_DMSG("watermark hit, discarded!\n"); + err=-EFAULT; + goto atm_send_drop_exit; + } +#ifdef TPE_LOOPBACK + return amazon_atm_dma_tx(vcc->vpi, vcc->vci,clp, (qid+CBM_RX_OFFSET),skb); +#else + return amazon_atm_dma_tx(vcc->vpi, vcc->vci,clp, qid,skb); +#endif + +atm_send_exit: + amazon_atm_free_tx_skb_vcc(vcc,skb); + return 0; + +atm_send_drop_exit: + g_atm_dev.mib_counter.tx_drop++; + queue_statics(qid,QS_SW_DROP); +atm_send_err_exit: + amazon_atm_free_tx_skb_vcc(vcc,skb); + return err; +} + +/* Brief: Return ATM port related MIB + * Parameter: interface number + atm_cell_ifEntry_t + */ +int amazon_atm_cell_mib(atm_cell_ifEntry_t* to,u32 itf) +{ + g_atm_dev.mib_counter.htu_unp += readl(HTU_MIBCIUP); + to->ifInUnknownProtos = g_atm_dev.mib_counter.htu_unp; +#ifdef AMAZON_TPE_READ_ARC + u32 reg_val=0; + meiDebugRead((AR_CELL0_ADDR+itf*4),®_val,1); + g_atm_dev.mib_counter.rx_cells += reg_val; + reg_val=0; + meiDebugWrite((AR_CELL0_ADDR+itf*4),®_val,1); + to->ifHCInOctets_h = (g_atm_dev.mib_counter.rx_cells * 53)>>32; + to->ifHCInOctets_l = (g_atm_dev.mib_counter.rx_cells * 53) & 0xffff; + + meiDebugRead((AT_CELL0_ADDR+itf*4),®_val,1); + g_atm_dev.mib_counter.tx_cells += reg_val; + reg_val=0; + meiDebugWrite((AT_CELL0_ADDR+itf*4),®_val,1); + to->ifHCOutOctets_h = (g_atm_dev.mib_counter.tx_cells * 53)>>32; + to->ifHCOutOctets_l = (g_atm_dev.mib_counter.rx_cells * 53) & 0xffff; + + meiDebugRead((AR_CD_CNT0_ADDR+itf*4),®_val,1); + g_atm_dev.mib_counter.rx_err_cells += reg_val; + reg_val=0; + meiDebugWrite((AR_CD_CNT0_ADDR+itf*4),®_val,1); + to->ifInErrors = g_atm_dev.mib_counter.rx_err_cells; + + to->ifOutErrors = 0; +#else + to->ifHCInOctets_h = 0; + to->ifHCInOctets_l = 0; + to->ifHCOutOctets_h = 0; + to->ifHCOutOctets_l = 0; + to->ifInErrors = 0; + to->ifOutErrors = 0; +#endif + return 0; +} + +/* Brief: Return ATM AAL5 related MIB + * Parameter: + atm_aal5_ifEntry_t + */ +int amazon_atm_aal5_mib(atm_aal5_ifEntry_t* to) +{ + u32 reg_l,reg_h; + //AAL5R received Octets from ATM + reg_l = readl(AAL5_RIOL_ADDR); + reg_h = readl(AAL5_RIOM_ADDR); + g_atm_dev.mib_counter.rx_cnt_h +=reg_h; + if (reg_l + g_atm_dev.mib_counter.rx_cnt_l < reg_l){ + g_atm_dev.mib_counter.rx_cnt_h++; + } + + g_atm_dev.mib_counter.rx_cnt_l+= reg_l; + //AAL5S sent Octets to ATM + reg_l = readl(AAL5_SOOL_ADDR); + reg_h = readl(AAL5_SOOM_ADDR); + g_atm_dev.mib_counter.tx_cnt_h +=reg_h; + if (reg_l + g_atm_dev.mib_counter.tx_cnt_l < reg_l){ + g_atm_dev.mib_counter.tx_cnt_h++; + } + g_atm_dev.mib_counter.tx_cnt_l+= reg_l; + + + g_atm_dev.mib_counter.tx_ppd += readl(CBM_AAL5ODIS_ADDR); + g_atm_dev.mib_counter.rx_drop += readl(CBM_AAL5IDIS_ADDR); + + //store + to->ifHCInOctets_h = g_atm_dev.mib_counter.rx_cnt_h; + to->ifHCInOctets_l = g_atm_dev.mib_counter.rx_cnt_l; + to->ifHCOutOctets_h = g_atm_dev.mib_counter.tx_cnt_h; + to->ifHCOutOctets_l = g_atm_dev.mib_counter.tx_cnt_l; + to->ifOutDiscards = g_atm_dev.mib_counter.tx_drop; + to->ifInDiscards = g_atm_dev.mib_counter.rx_drop; + + //Software provided counters + //packets passed to higher layer + to->ifInUcastPkts = g_atm_dev.mib_counter.rx; + //packets passed from higher layer + to->ifOutUcastPkts = g_atm_dev.mib_counter.tx; + //number of wrong downstream packets + to->ifInErrors = g_atm_dev.mib_counter.rx_err; + //number of wrong upstream packets + to->ifOutErros = g_atm_dev.mib_counter.tx_err; + + return 0; +} +/* Brief: Return ATM AAL5 VCC related MIB from internale use + * Parameter: + * qid + * atm_aal5_vcc_t + */ +static int __amazon_atm_vcc_mib(int qid, atm_aal5_vcc_t* to) +{ + //aal5VccCrcErrors + to->aal5VccCrcErrors = g_atm_dev.queues[qid].aal5VccCrcErrors; + to->aal5VccOverSizedSDUs =g_atm_dev.queues[qid].aal5VccOverSizedSDUs; + to->aal5VccSarTimeOuts = 0; //not supported yet + return 0; +} +/* Brief: Return ATM AAL5 VCC related MIB from vpi/vci + * Parameter: atm_vcc + * atm_aal5_vcc_t + */ +int amazon_atm_vcc_mib_x(int vpi, int vci,atm_aal5_vcc_t* to) +{ + int qid=0; + int err=0; + qid = amazon_atm_find_vpivci(vpi, vci); + if (qid >0 ){ + err = __amazon_atm_vcc_mib(qid,to); + }else{ + return -EINVAL; + } + return err; +} + + +/* Brief: Return ATM AAL5 VCC related MIB + * Parameter: atm_vcc + * atm_aal5_vcc_t + */ +int amazon_atm_vcc_mib(struct atm_vcc *vcc,atm_aal5_vcc_t* to) +{ + int qid=0; + int err=0; + qid = amazon_atm_get_queue(vcc); + if (qid >0 ){ + err = __amazon_atm_vcc_mib(qid,to); + }else{ + return -EINVAL; + } + return err; +} + +/* Brief: Close ATM connection + * Parameters: atm_vcc - Pointer to VCC data structure + * Return: no + * Description: + * This function closes the given ATM connection + */ +void amazon_atm_close(struct atm_vcc *vcc){ + int i; + int qid=0; + u32 tmp1; + u8 * qd_addr; + unsigned long flags; + if (vcc == NULL){ + AMAZON_TPE_EMSG("invalid parameter. vcc is null\n"); + return; + } + u32 itf = (u32) vcc->itf; + //release bandwidth + if (vcc->qos.txtp.traffic_class == ATM_CBR){ + g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.max_pcr; + g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.max_pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_VBR_RT){ + g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.max_pcr; + g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.max_pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_VBR_NRT){ + g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.pcr; + g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.pcr; + }else if (vcc->qos.txtp.traffic_class == ATM_UBR_PLUS){ + g_atm_dev.ports[itf].tx_rem_cr += vcc->qos.txtp.min_pcr; + g_atm_dev.ports[itf].tx_cur_cr -= vcc->qos.txtp.min_pcr; + } + + qid = amazon_atm_get_queue(vcc); + if (qid == -EINVAL){ + AMAZON_TPE_EMSG("unknown vcc %u.%u.%u\n", vcc->itf, vcc->vpi, vcc->vci); + return; + } + local_irq_save(flags); + //Disable HTU entry + i=0; + while ((tmp1 = readl(HTU_RAMSTAT_ADDR))!=0 && i < HTU_RAM_ACCESS_MAX) i++; + if (i == HTU_RAM_ACCESS_MAX){ + AMAZON_TPE_EMSG("HTU RAM ACCESS out of time\n"); + } + + // write address register + AMAZON_WRITE_REGISTER_L(qid - CBM_DEFAULT_Q_OFFSET, HTU_RAMADDR_ADDR); + // invalidate the connection + AMAZON_WRITE_REGISTER_L(0, HTU_RAMDAT1_ADDR); + // write command + AMAZON_WRITE_REGISTER_L(HTU_RAMCMD_WR,HTU_RAMCMD_ADDR); + + qd_addr = (u8 *) KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr); +#ifdef AMAZON_ATM_DEBUG + tmp1 = readl(qd_addr+qid*CBM_QD_SIZE+0x8) & 0xffff; + AMAZON_TPE_DMSG("TX queue has %u cells \n", tmp1); + tmp1 = readl( qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE+0x08)&0xffff; + AMAZON_TPE_DMSG("RX queue has %u cells \n", tmp1); +#endif + // set threshold of txqueue to 0 + tmp1 = readl(qd_addr+qid*CBM_QD_SIZE+0x0c); + tmp1&= (~ CBM_QD_W3_THRESHOLD_MASK); + AMAZON_WRITE_REGISTER_L(tmp1, (qd_addr+qid*CBM_QD_SIZE+0x0c)); + // set threshold of rxqueue to 0 + tmp1 = readl( qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE+0x0c); + tmp1&= (~ CBM_QD_W3_THRESHOLD_MASK); + AMAZON_WRITE_REGISTER_L(tmp1,(qd_addr+(qid+CBM_RX_OFFSET)*CBM_QD_SIZE+0x0c)); + + //clear internal mapping + amazon_atm_clear_vcc(qid); + amazon_atm_clear_vcc(qid+CBM_RX_OFFSET); + + local_irq_restore(flags); +} + + +/* Brief: initialize internal data structure + */ +static void atm_constructor(amazon_atm_dev_t * dev) +{ + int i; + memset(dev,0,sizeof(amazon_atm_dev_t)); + atm_init_parameters(dev); + //internal: queue "free" flag + for(i=1;i<AMAZON_ATM_MAX_QUEUE_NUM;i++) { + //dev->queues[i].vcc=NULL; + dev->queues[i].free = 1; + } + for(i=0;i<AMAZON_ATM_PORT_NUM;i++){ + dev->ports[i].tx_rem_cr = dev->ports[i].tx_max_cr; + } + //MIB + atomic_set(&dev->dma_tx_free_0,1); //initially there should be free descriptors +} + +/* Brief: return round up base-2 logarithm + */ +static inline int get_log_2(u32 value) +{ + int i=0,j=1; + while (i<11){ + if (j>=value) break; + j=j<<1; + i++; + } + AMAZON_TPE_DMSG("round up base-2 logarithm of %u is %u\n", value, i); + return i; +} + +/* Brief: TPE hardware initialization + * Parameter: specifiy the configurations of the hardware + */ +static inline int atm_init_hard(amazon_atm_dev_t * dev) +{ + int i; + u32 tmp1, tmp2, tmp3; + u8 * mem_addr=NULL; + u8 * qd_addr=NULL; + //PMU power on the module 1st + *(AMAZON_PMU_PWDCR) = (*AMAZON_PMU_PWDCR) | (AMAZON_PMU_PWDCR_TPE); + //Reset the module + *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) | (AMAZON_RST_REQ_TPE); + mb(); + mdelay(100); + *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) & (~(AMAZON_RST_REQ_TPE)); + mb(); + + unsigned long qsb_clk = amazon_get_fpi_hz()>>1; + /*********allocate & arrange memory for CBM *********/ + if (dev->cbm.mem_addr == NULL){ + dev->cbm.allocated = 1; + mem_addr = (u8 *)__get_free_pages(GFP_KERNEL, get_log_2(((CBM_CELL_SIZE * dev->cbm.free_cell_cnt) >>PAGE_SHIFT) + 1)); + if (mem_addr != NULL){ + dev->cbm.mem_addr = mem_addr; + } else { + goto init_no_mem; + } + } + if (dev->cbm.qd_addr == NULL){ +#ifdef CONFIG_USE_VENUS + //to work around a bug, bit15 of QDOFF address should be 1,Aug4, 2004 + //thus, we allocate 64k memory + qd_addr = (u8 *)__get_free_pages(GFP_KERNEL, 4); + if (qd_addr != NULL) { + dev->cbm.qd_addr_free = (u8*) (((unsigned long) qd_addr)); + dev->cbm.qd_addr = (u8*) (((unsigned long) qd_addr) | 0x8000); + }else{ + goto init_no_mem; + } +#else //CONFIG_USE_VENUS + qd_addr = (u8 *)kmalloc( CBM_QD_SIZE * AMAZON_ATM_MAX_QUEUE_NUM, GFP_KERNEL); + if (qd_addr != NULL) { + dev->cbm.qd_addr = qd_addr; + }else { + goto init_no_mem; + } +#endif //CONFIG_USE_VENUS + } +//#ifndef CONFIG_MIPS_UNCACHED + mem_addr = (u8 *)KSEG1ADDR((unsigned long)dev->cbm.mem_addr); + qd_addr = (u8 *)KSEG1ADDR((unsigned long)dev->cbm.qd_addr); +//#endif + //CBM reset cell queue memory, 64 bytes / cell + memset_io(mem_addr, 0, CBM_CELL_SIZE * dev->cbm.free_cell_cnt); + //make a link list, last 4 bytes is pointer + for(i=1;i<dev->cbm.free_cell_cnt;i++){ + AMAZON_WRITE_REGISTER_L(CPHYSADDR((mem_addr + CBM_CELL_SIZE * i)),(mem_addr + CBM_CELL_SIZE * (i-1) + 0x3c)); + } + //reset queue descriptor + memset_io(qd_addr, 0, CBM_QD_SIZE * AMAZON_ATM_MAX_QUEUE_NUM); + //init word 0-2 of q0 (free cell list) + //address of last cell + AMAZON_WRITE_REGISTER_L(CPHYSADDR((mem_addr + CBM_CELL_SIZE * (dev->cbm.free_cell_cnt-1))), qd_addr); + //address of first cell + AMAZON_WRITE_REGISTER_L(CPHYSADDR((mem_addr)), (qd_addr + 4)); + //no. of free cells + AMAZON_WRITE_REGISTER_L(dev->cbm.free_cell_cnt,(qd_addr + 8)); + //init q descriptor for OAM receiving + AMAZON_WRITE_REGISTER_L((CBM_QD_W3_INT_ACA | (divide_by_64_round_up(oam_q_threshold)&0xff)<< CBM_QD_W3_THRESHOLD_SHIFT), (qd_addr + AMAZON_ATM_OAM_Q_ID * CBM_QD_SIZE + 0x0c)); +// AMAZON_WRITE_REGISTER_L((CBM_QD_W3_INT_ACA | (u32)oam_q_threshold<< CBM_QD_W3_THRESHOLD_SHIFT), (qd_addr + AMAZON_ATM_OAM_Q_ID * CBM_QD_SIZE + 0x0c)); + //config CBM + //set offset address and threshold + AMAZON_WRITE_REGISTER_L(CPHYSADDR(qd_addr), CBM_QDOFF_ADDR); + AMAZON_WRITE_REGISTER_L(((dev->cbm.nrt_thr&CBM_THR_MASK)|CBM_WM_3_1), CBM_NRTTHR_ADDR); + AMAZON_WRITE_REGISTER_L(((dev->cbm.clp0_thr&CBM_THR_MASK)|CBM_WM_3_1), CBM_CLP0THR_ADDR); + AMAZON_WRITE_REGISTER_L(((dev->cbm.clp1_thr&CBM_THR_MASK)|CBM_WM_3_1), CBM_CLP1THR_ADDR); + //config interrupts + AMAZON_WRITE_REGISTER_L( CBM_IMR_MASK & (~(CBM_IMR_ACA|CBM_IMR_Q0E|CBM_IMR_Q0I|CBM_IMR_RDE|CBM_IMR_OPF|CBM_IMR_ERR +#ifdef AMAZON_ATM_DEBUG + |CBM_IMR_DISC|CBM_IMR_QFD|CBM_IMR_NFCA|CBM_IMR_CLP1TR|CBM_IMR_CLP0TR|CBM_IMR_NRTTR|CBM_IMR_QTR +#endif +#ifdef AMAZON_TPE_SCR + |CBM_IMR_EF +#endif + )), CBM_IMR0_ADDR); + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_CBM_INT, CBM_SRC0_ADDR); + + //HTU + //RAM entry for number of possible connections per interface + tmp1 = dev->ports[0].max_conn?dev->ports[0].max_conn-1:0; + AMAZON_WRITE_REGISTER_L(tmp1, HTU_RX0_ADDR); + for(i=1;i<AMAZON_ATM_PORT_NUM;i++){ + tmp1+=dev->ports[i].max_conn; + AMAZON_WRITE_REGISTER_L(tmp1, HTU_RX0_ADDR + 4 * i); + } + dev->cbm.max_q_off = tmp1+1; + //Queue ID for OAM/RM/Other cells + AMAZON_WRITE_REGISTER_L (AMAZON_ATM_OAM_Q_ID, HTU_DESTOAM_ADDR); + AMAZON_WRITE_REGISTER_L( AMAZON_ATM_RM_Q_ID, HTU_DESTRM_ADDR); + AMAZON_WRITE_REGISTER_L( AMAZON_ATM_OTHER_Q_ID, HTU_DESTOTHER_ADDR); + //Timeout + AMAZON_WRITE_REGISTER_L((u32) HTUTIMEOUT, HTU_TIMEOUT_ADDR); +#ifdef AMAZON_ATM_DEBUG + AMAZON_WRITE_REGISTER_L((u32) HTU_ISR_MASK + &(~(HTU_ISR_NE|HTU_ISR_TORD|HTU_ISR_OTOC|HTU_ISR_ONEC|HTU_ISR_PNE|HTU_ISR_PT)), HTU_IMR0_ADDR); + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS|SRC_SRE_ENABLE|AMAZON_HTU_INT,HTU_SRC0_ADDR); +#endif + //QSB + //global setting, TstepC, SBL, Tau + //Tau + AMAZON_WRITE_REGISTER_L(dev->qsb.tau, QSB_TAU_ADDR); + //SBL + AMAZON_WRITE_REGISTER_L(dev->qsb.sbl, QSB_SBL_ADDR); + //tstep + AMAZON_WRITE_REGISTER_L(dev->qsb.tstepc>>1, QSB_CONFIG_ADDR); + + //port settting + for(i=0;i<AMAZON_ATM_PORT_NUM;i++){ + if ( (dev->ports[i].enable) && (dev->ports[i].tx_max_cr!=0) ){ + tmp1 = ((qsb_clk * dev->qsb.tstepc) >>1) / dev->ports[i].tx_max_cr; + tmp2 = tmp1 / 64; //integer value of Tsb + tmp3 = tmp1%64 + 1; //fractional part of Tsb + //carry over to integer part (?) + if (tmp3 == 64) { + tmp3 = 0; + tmp2++; + } + if (tmp2 == 0){ + tmp2 = 1; + tmp3 = 1; + } + //1. set mask 2. write value to data transfer register 3. start the transfer + //SCT(FracRate) + AMAZON_WRITE_REGISTER_L(QSB_SET_SCT_MASK, QSB_RTM_ADDR); + AMAZON_WRITE_REGISTER_L(tmp3,QSB_RTD_ADDR); + AMAZON_WRITE_REGISTER_L(((QSB_TABLESEL_SCT<<QSB_TABLESEL_SHIFT)|QSB_RAMAC_REG_LOW|QSB_WRITE|i),QSB_RAMAC_ADDR); + //SPT(SBV + PN + IntRage) + AMAZON_WRITE_REGISTER_L(QSB_SET_SPT_MASK, QSB_RTM_ADDR); + AMAZON_WRITE_REGISTER_L(QSB_SPT_SBVALID|tmp2|(i<<16),QSB_RTD_ADDR); + AMAZON_WRITE_REGISTER_L(((QSB_TABLESEL_SPT<<QSB_TABLESEL_SHIFT)|QSB_RAMAC_REG_LOW|QSB_WRITE|i),QSB_RAMAC_ADDR); + + + } + } + + //SWIE: Setup Service Request Control Registers to enable interrupts + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_SWIE_INT, SWIE_ISRC_ADDR); + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_SWIE_INT, SWIE_ESRC_ADDR); + + wmb(); +#ifdef AMAZON_TPE_TEST_AAL5_INT + AMAZON_WRITE_REGISTER_L(AAL5R_ISR_FE,AAL5_RIMR0_ADDR); + AMAZON_WRITE_REGISTER_L(0, AAL5_SIMR0_ADDR); + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_AAL5_INT,AAL5_SSRC0_ADDR); + AMAZON_WRITE_REGISTER_L(SRC_CLRR|SRC_TOS_MIPS | SRC_SRE_ENABLE | AMAZON_AAL5_INT,AAL5_RSRC0_ADDR); +#endif //AMAZON_TPE_TEST_AAL5_INT + + AMAZON_WRITE_REGISTER_L(dev->aal5.tx_max_sdu,AAL5_SMFL_ADDR); + AMAZON_WRITE_REGISTER_L(dev->aal5.rx_max_sdu,AAL5_RMFL_ADDR); + AMAZON_WRITE_REGISTER_L(AAL5_SCMD_MODE_POLL // enable polling mode + |AAL5_SCMD_SS + |AAL5_SCMD_AR + ,AAL5_SCMD_ADDR); + //start CBM + AMAZON_WRITE_REGISTER_L(CBM_CFG_START,CBM_CFG_ADDR); + wmb(); + return 0; +init_no_mem: + if (mem_addr != NULL) free_pages((unsigned long)mem_addr,get_log_2(((CBM_CELL_SIZE * dev->cbm.free_cell_cnt) >>PAGE_SHIFT) + 1)); + +#ifdef CONFIG_USE_VENUS + //to work around a bug, bit15 of QDOFF address should be 1 + if (qd_addr != NULL) free_pages((unsigned long)qd_addr,4); +#else //CONFIG_USE_VENUS + if (qd_addr != NULL) kfree(qd_addr); +#endif //CONFIG_USE_VENUS + return -ENOMEM; +} + +/* + * Brief: Create entry in /proc for status information + */ +void atm_create_proc(void) +{ + create_proc_read_entry("amazon_atm", 0,NULL, amazon_atm_read_procmem,(void*)PROC_ATM); + create_proc_read_entry("amazon_atm_mib", 0,NULL, amazon_atm_read_procmem,(void*)PROC_MIB); + create_proc_read_entry("amazon_atm_vcc", 0,NULL, amazon_atm_read_procmem,(void*)PROC_VCC); +#if 0 + create_proc_read_entry("amazon_atm_aal5", 0,NULL, amazon_atm_read_procmem,(void*)PROC_AAL5); + create_proc_read_entry("amazon_atm_cbm", 0,NULL, amazon_atm_read_procmem,(void*)PROC_CBM); + create_proc_read_entry("amazon_atm_htu", 0,NULL, amazon_atm_read_procmem,(void*)PROC_HTU); + create_proc_read_entry("amazon_atm_qsb", 0,NULL, amazon_atm_read_procmem,(void*)PROC_QSB); + create_proc_read_entry("amazon_atm_swie", 0,NULL, amazon_atm_read_procmem,(void*)PROC_SWIE); +#endif +} + +/* + * Brief: Delete entry in /proc for status information + */ +void atm_delete_proc(void) +{ + remove_proc_entry("amazon_atm", NULL); + remove_proc_entry("amazon_atm_mib", NULL); + remove_proc_entry("amazon_atm_vcc", NULL); +#if 0 + remove_proc_entry("amazon_atm_aal5", NULL); + remove_proc_entry("amazon_atm_cbm", NULL); + remove_proc_entry("amazon_atm_htu", NULL); + remove_proc_entry("amazon_atm_qsb", NULL); + remove_proc_entry("amazon_atm_swie", NULL); +#endif +} +/* Brief: Initialize ATM module + * Parameters: no + * Return: &g_atm_dev - sucessful + * NULL - fails: + * 1. invalid parameter + * 2. No memory available + * Description: + * This function configure the TPE components according to the input info, + * -CBM + * -HTU + * -QSB + * -AAL5 + * + */ +amazon_atm_dev_t * amazon_atm_create(void) +{ + int i; + AMAZON_TPE_DMSG("atm_init\n"); + /************initialize global data structure****************/ + atm_constructor(&g_atm_dev); + /***********allocate kernel resources****************/ + //bottom halfs for SWEX + swex_start_task.routine = amazon_atm_swex; + swex_start_task.data = NULL; + swex_complete_task.routine = amazon_atm_swex_push; + swex_complete_task.data = NULL; +#ifdef AMAZON_TPE_SCR + a5r_task.routine = amazon_atm_a5r; + a5r_task.data = NULL; +#endif //AMAZON_TPE_SCR + //SWIN semaphore + sema_init(&(g_atm_dev.swie.in_sem), 1); + //SWIE lock + clear_bit(SWIE_LOCK, &(g_atm_dev.swie.lock)); + //SWIE wait queue + init_waitqueue_head(&(g_atm_dev.swie.sleep)); + atm_create_proc(); + + //register DMA + memset(&g_dma_dev,0,sizeof(struct dma_device_info)); + strcpy(g_dma_dev.device_name,"TPE"); + g_dma_dev.weight=1; + g_dma_dev.num_tx_chan=2; + g_dma_dev.num_rx_chan=2; + g_dma_dev.ack=1; + g_dma_dev.tx_burst_len=4; + g_dma_dev.rx_burst_len=4; + //DMA TX + + for(i=0;i<1;i++){ + g_dma_dev.tx_chan[i].weight=QOS_DEFAULT_WGT; + g_dma_dev.tx_chan[i].desc_num=10; + g_dma_dev.tx_chan[i].packet_size=g_atm_dev.aal5.tx_max_sdu + AAL5S_INBOUND_HEADER; + g_dma_dev.tx_chan[i].control=1; + } + //DMA RX + for(i=0;i<2;i++){ + g_dma_dev.rx_chan[i].weight=QOS_DEFAULT_WGT; + /* BingTao's suggestion, change from 5->10 will prevent packet loss in NO_TX_INT mode */ + g_dma_dev.rx_chan[i].desc_num=10; + g_dma_dev.rx_chan[i].packet_size=(g_atm_dev.aal5.rx_max_sdu + AAL5R_TRAILER_LEN+0x10f)&(~0xf); + g_dma_dev.rx_chan[i].control=1; + } + g_dma_dev.intr_handler=amazon_atm_dma_handler; + g_dma_dev.buffer_alloc=amazon_atm_alloc_rx; + g_dma_dev.buffer_free=amazon_atm_free_tx; + dma_device_register(&g_dma_dev); +/***********intialize the atm hardware ****************/ + if ( atm_init_hard(&g_atm_dev) != 0){ + return NULL; + } + //start CBM + AMAZON_WRITE_REGISTER_L(CBM_CFG_START,CBM_CFG_ADDR); + wmb(); + + //Start HTU + AMAZON_WRITE_REGISTER_L(HTU_CFG_START ,HTU_CFG_ADDR); + wmb(); + + + // Register interrupts for insertion and extraction + request_irq(AMAZON_SWIE_INT, amazon_atm_swie_isr, SA_INTERRUPT, "tpe_swie", NULL); + request_irq(AMAZON_CBM_INT, amazon_atm_cbm_isr, SA_INTERRUPT, "tpe_cbm", NULL); +#ifdef AMAZON_ATM_DEBUG + request_irq(AMAZON_HTU_INT , amazon_atm_htu_isr, SA_INTERRUPT, "tpe_htu", NULL); +#endif +#ifdef AMAZON_TPE_TEST_AAL5_INT + request_irq(AMAZON_AAL5_INT, amazon_atm_aal5_isr, SA_INTERRUPT, "tpe_aal5", NULL); +#endif + return &g_atm_dev; +} + +/* Brief: clean up atm + * Parameters: no + * Return: no + * Description: + * Disable the device. + */ +void amazon_atm_cleanup(void){ + int i; + clear_bit(SWIE_LOCK, &(g_atm_dev.swie.lock)); + wake_up(&g_atm_dev.swie.sleep); + up(&g_atm_dev.swie.in_sem); + // diable SWIE interrupts + AMAZON_WRITE_REGISTER_L(0, SWIE_ISRC_ADDR); + AMAZON_WRITE_REGISTER_L(0, SWIE_ESRC_ADDR); + wmb(); + + // Disable schedulers ( including interrupts )----------------------- + for (i = 0; i < AMAZON_ATM_PORT_NUM; i++); + { + AMAZON_WRITE_REGISTER_L(QSB_SET_SPT_SBVALID_MASK, QSB_RTM_ADDR); + AMAZON_WRITE_REGISTER_L( 0 ,QSB_RTD_ADDR); + AMAZON_WRITE_REGISTER_L( (QSB_TABLESEL_SPT<<QSB_TABLESEL_SHIFT) + | QSB_RAMAC_REG_LOW + | QSB_WRITE + | i, + QSB_RAMAC_ADDR); + } + // disable QSB_Interrupts + AMAZON_WRITE_REGISTER_L( 0, QSB_IMR_ADDR); + AMAZON_WRITE_REGISTER_L( 0, QSB_SRC_ADDR); + // disable CBM interrupts + AMAZON_WRITE_REGISTER_L( 0 , CBM_IMR0_ADDR); + AMAZON_WRITE_REGISTER_L( 0 , CBM_SRC0_ADDR); + // set CBM start bit to 0 + AMAZON_WRITE_REGISTER_L(0,CBM_CFG_ADDR); + // request hardware extraction of queue 0, wich should force the CBM + // to recognize that the start bit is not set + AMAZON_WRITE_REGISTER_L(CBM_HWEXPAR_PN_A5, CBM_HWEXPAR0_ADDR); + // write frame extraction command into the hw extract command register + AMAZON_WRITE_REGISTER_L(CBM_HWEXCMD_FE0, CBM_HWEXCMD_ADDR); + // disable htu + // disable all HTU interrupts + AMAZON_WRITE_REGISTER_L(0 ,HTU_IMR0_ADDR); + AMAZON_WRITE_REGISTER_L(0 ,HTU_SRC0_ADDR); + + if (g_atm_dev.cbm.allocated){ + free_pages((unsigned long)g_atm_dev.cbm.mem_addr, get_log_2(((CBM_CELL_SIZE * g_atm_dev.cbm.free_cell_cnt) >>PAGE_SHIFT)+1)); +#ifdef CONFIG_USE_VENUS + //to work around a bug, bit15 of QDOFF address should be 1 + free_pages((unsigned long)g_atm_dev.cbm.qd_addr_free,4); +#else //CONFIG_USE_VENUS + kfree(g_atm_dev.cbm.qd_addr); +#endif //CONFIG_USE_VENUS + } + atm_delete_proc(); + // free interrupts for insertion and extraction + dma_device_unregister(&g_dma_dev); + free_irq(AMAZON_SWIE_INT, NULL); + free_irq(AMAZON_CBM_INT, NULL); +#ifdef AMAZON_ATM_DEBUG + free_irq(AMAZON_HTU_INT, NULL); +#endif +#ifdef AMAZON_TPE_TEST_AAL5_INT + free_irq(AMAZON_AAL5_INT, NULL); +#endif + +} + +/************************ ATM network interface ***********************************************/ +/* Brief: getsockopt + */ +int amazon_atm_getsockopt(struct atm_vcc *vcc, int level, int optname, char *optval, int optlen) +{ + int err=0; + atm_aal5_vcc_t mib_vcc; + AMAZON_TPE_DMSG("1\n"); + switch (optname){ + case SO_AMAZON_ATM_MIB_VCC: + AMAZON_TPE_DMSG("2\n"); + err = amazon_atm_vcc_mib(vcc, &mib_vcc); + AMAZON_TPE_DMSG("%u\n",mib_vcc.aal5VccCrcErrors); + err = copy_to_user((void *)optval,&mib_vcc, sizeof(mib_vcc)); + AMAZON_TPE_DMSG("err %u\n",err); + break; + default: + return -EFAULT; + } + return err; +} + +/* Brief: IOCTL + */ + +int amazon_atm_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) +{ + int err=0; + //MIB + atm_cell_ifEntry_t mib_cell; + atm_aal5_ifEntry_t mib_aal5; + atm_aal5_vcc_x_t mib_vcc; + if (_IOC_TYPE(cmd) != AMAZON_ATM_IOC_MAGIC) return -ENOTTY; + if (_IOC_NR(cmd) > AMAZON_ATM_IOC_MAXNR) return -ENOTTY; + + if (_IOC_DIR(cmd) & _IOC_READ) + err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)); + if (err) { + AMAZON_TPE_EMSG("acess verification fails \n"); + return -EFAULT; + } + switch(cmd) { + case AMAZON_ATM_MIB_CELL: + err = amazon_atm_cell_mib(&mib_cell,(u32)arg); + if (err==0){ + err = __copy_to_user((void *)arg,&mib_cell,sizeof(mib_cell)); + }else{ + AMAZON_TPE_EMSG("cannot get MIB ATM_CELL\n"); + } + break; + case AMAZON_ATM_MIB_AAL5: + err = amazon_atm_aal5_mib(&mib_aal5); + if (err==0){ + err=__copy_to_user(arg, &mib_aal5, sizeof(mib_aal5)); + }else{ + AMAZON_TPE_EMSG("cannot get MIB ATM_AAL5\n"); + } + break; + case AMAZON_ATM_MIB_VCC: + err=__copy_from_user(&mib_vcc,arg, sizeof(mib_vcc)); + AMAZON_TPE_DMSG("return of copy_from_user %x\n",err); + err = amazon_atm_vcc_mib_x(mib_vcc.vpi, mib_vcc.vci, &(mib_vcc.mib_vcc)); + if (err==0){ + err=__copy_to_user(arg, &mib_vcc, sizeof(mib_vcc)); + }else{ + AMAZON_TPE_EMSG("cannot get MIB ATM_VCC\n"); + } + + default: + return -ENOTTY; + } + return err; +} +/* Brief: return a link list of OAM related time stamp info + * Parameter: none + * Return: + a link list of "struct oam_last_activity" data + * Description: + Each time, a F4/F5 cell or AAL5 packet is received, the time stamp is updated. + Through this call, u get a list of this time stamp for all active connection. + Please note that u have read-only access. + */ +const struct oam_last_activity* get_oam_time_stamp() +{ + int i,j; + for(i=CBM_DEFAULT_Q_OFFSET+CBM_RX_OFFSET,j=0;i<CBM_RX_OFFSET+CBM_DEFAULT_Q_OFFSET+AMAZON_ATM_MAX_VCC_NUM;i++){ + if (g_atm_dev.queues[i].free != 1 && g_atm_dev.queues[i].vcc != NULL){ + //active connection + if (j !=0 ){ + g_oam_time_stamp[j-1].next = &g_oam_time_stamp[j]; + } + g_oam_time_stamp[j].vpi = g_atm_dev.queues[i].vcc->vpi; + g_oam_time_stamp[j].vci = g_atm_dev.queues[i].vcc->vci; + g_oam_time_stamp[j].stamp = g_atm_dev.queues[i].access_time; + g_oam_time_stamp[j].next = NULL; + j++; + } + } + if (j==0) { + return NULL; + }else{ + return g_oam_time_stamp; + } +} + + +/* Brief: call back routine for rx + * Parameter: + * vcc atm_vcc pointer + * skb data if no error + err error flag, 0: no error, 1:error + * Return: + * 0 + * <>0 cannot push up + * Description: + * release the packet if cannot push up + */ +static int amazon_atm_net_push(struct atm_vcc *vcc,struct sk_buff *skb, int err) +{ + if (err){ + if (vcc && vcc->stats) { + atomic_inc(&vcc->stats->rx_err); + } + }else{ + ATM_SKB(skb)->vcc = vcc; + + if (!atm_charge(vcc, skb->truesize)){ + //no space this vcc + AMAZON_TPE_EMSG("no space for this vcc\n"); + dev_kfree_skb_any(skb); + return -ENOMEM; + } + atomic_inc(&vcc->stats->rx); + AMAZON_TPE_DMSG("push to vcc\n"); + vcc->push(vcc,skb); + } + return 0; +} +int amazon_atm_net_send_oam(struct atm_vcc*vcc, void *cell, int flags) +{ + return amazon_atm_send_oam(vcc,cell,flags); +} + +int amazon_atm_net_send(struct atm_vcc *vcc,struct sk_buff *skb) +{ + int err=0; + if (vcc->qos.aal == ATM_AAL0 || vcc->qos.aal == ATM_AAL5) { + err=amazon_atm_send(vcc,skb); + }else{ + //not supported + err = -EPROTONOSUPPORT; + } + if (err){ + atomic_inc(&vcc->stats->tx_err); + }else{ + atomic_inc(&vcc->stats->tx); + } + AMAZON_TPE_DMSG("sent, tx_inuse:%u\n", atomic_read(&vcc->tx_inuse)); + return err; +} + +int amazon_atm_net_open(struct atm_vcc *vcc,short vpi, int vci) +{ + vcc->itf = (int) vcc->dev->dev_data; + vcc->vpi = vpi; + vcc->vci = vci; + return(amazon_atm_open(vcc,amazon_atm_net_push)); +} + +static int amazon_atm_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flgs) +{ + int qid; + + if (vcc == NULL || qos == NULL){ + AMAZON_TPE_EMSG("invalid parameters\n"); + return -EINVAL; + } + qid = amazon_atm_get_queue(vcc); + if (valid_qid(qid) != 1) { + AMAZON_TPE_EMSG("no vcc connection opened\n"); + return -EINVAL; + } + set_qsb(vcc,qos,qid); + return 0; +} + +static struct atmdev_ops amazon_atm_ops = { + open: amazon_atm_net_open, + close: amazon_atm_close, + ioctl: amazon_atm_ioctl, + send: amazon_atm_net_send, + send_oam: amazon_atm_net_send_oam, +// getsockopt: amazon_atm_getsockopt, + change_qos: amazon_atm_change_qos, +// proc_read: amazon_atm_proc_read, + owner: THIS_MODULE, +}; // ATM device callback functions + +/* + * brief "/proc" function + */ +int amazon_atm_read_procmem(char *buf, char **start, off_t offset,int count, int *eof, void *data) +{ + int buf_off=0; /* for buf */ + int i=0,j=0; + int type= (u32)data;//which module + atm_aal5_ifEntry_t mib_aal5; + atm_cell_ifEntry_t mib_cell; + atm_aal5_vcc_t mib_vcc; + switch(type){ + case PROC_MIB: + //MIB counter + amazon_atm_aal5_mib(&mib_aal5); + //TX: + buf_off+=sprintf(buf+buf_off,"\n============= AAL5 Upstream =========\n"); + buf_off+=sprintf(buf+buf_off,"received %u (pkts) from upper layer\n", mib_aal5.ifOutUcastPkts); + buf_off+=sprintf(buf+buf_off,"errors: %u (pkts)\n",mib_aal5.ifOutErros); + buf_off+=sprintf(buf+buf_off,"discards: %u (ptks)\n", mib_aal5.ifOutDiscards); + buf_off+=sprintf(buf+buf_off,"transmitted: %x-%x (bytes) \n", + mib_aal5.ifHCOutOctets_h, mib_aal5.ifHCOutOctets_l); + //RX: + buf_off+=sprintf(buf+buf_off,"\n============= AAL5 Downstream =========\n"); + buf_off+=sprintf(buf+buf_off,"received %x-%x (bytes)\n", + mib_aal5.ifHCInOctets_h,mib_aal5.ifHCInOctets_l); + buf_off+=sprintf(buf+buf_off,"discards: %u (ptks)\n",mib_aal5.ifInDiscards); + buf_off+=sprintf(buf+buf_off,"errors: %u (ptks)\n",mib_aal5.ifInErrors); + buf_off+=sprintf(buf+buf_off,"passed %u (ptks) to upper layer\n",mib_aal5.ifInUcastPkts); + + //Cell level + buf_off+=sprintf(buf+buf_off,"\n============= ATM Cell =========\n"); + amazon_atm_cell_mib(&mib_cell,0); +#ifdef AMAZON_TPE_READ_ARC + buf_off+=sprintf(buf+buf_off,"Port 0: downstream received: %x-%x (bytes)\n",mib_cell.ifHCInOctets_h,mib_cell.ifHCInOctets_l); + buf_off+=sprintf(buf+buf_off,"Port 0: upstream transmitted: %x-%x (bytes)\n",mib_cell.ifHCOutOctets_h,mib_cell.ifHCOutOctets_l); + buf_off+=sprintf(buf+buf_off,"Port 0: downstream errors: %u (cells)\n",mib_cell.ifInErrors); + amazon_atm_cell_mib(&mib_cell,1); + buf_off+=sprintf(buf+buf_off,"Port 1: downstream received: %x-%x (bytes)\n",mib_cell.ifHCInOctets_h,mib_cell.ifHCInOctets_l); + buf_off+=sprintf(buf+buf_off,"Port 1: upstream transmitted: %x-%x (bytes)\n",mib_cell.ifHCOutOctets_h,mib_cell.ifHCOutOctets_l); + buf_off+=sprintf(buf+buf_off,"Port 1: downstream errors: %u (cells)\n",mib_cell.ifInErrors); +#endif + buf_off+=sprintf(buf+buf_off,"HTU discards: %u (cells)\n",mib_cell.ifInUnknownProtos); + + buf_off+=sprintf(buf+buf_off,"\n====== Specials =====\n"); + buf_off+=sprintf(buf+buf_off,"AAL5S PPD: %u (cells)\n",g_atm_dev.mib_counter.tx_ppd); +#ifdef AMAZON_TPE_SCR + buf_off+=sprintf(buf+buf_off,"Reassembly wait: %u \n",g_a5r_wait); +#endif + break; + case PROC_ATM: + //Interface (Port) + buf_off+=sprintf(buf+buf_off,"[Interfaces]\n"); + for(i=0;i<AMAZON_ATM_PORT_NUM;i++){ + if (g_atm_dev.ports[i].enable==0){ + buf_off+=sprintf(buf+buf_off,"\tport[%u] not in use\n",i); + }else{ + buf_off+=sprintf(buf+buf_off,"\tport[%u]\n\t\tmax_conn=%u\n" + ,i + ,g_atm_dev.ports[i].max_conn + ); + buf_off+=sprintf(buf+buf_off,"\t\ttx_max=%u\n\t\trem=%u\n\t\tcur=%u\n" + ,g_atm_dev.ports[i].tx_max_cr + ,g_atm_dev.ports[i].tx_rem_cr + ,g_atm_dev.ports[i].tx_cur_cr + ); + } + + } + //Units Info + //AAL5 + buf_off+=sprintf(buf+buf_off,"[AAL5]\n\tpad=%c(%x)\n\trx_mtu=%u\n\ttx_mtu=%u\n" + ,g_atm_dev.aal5.padding_byte + ,g_atm_dev.aal5.padding_byte + ,g_atm_dev.aal5.rx_max_sdu + ,g_atm_dev.aal5.tx_max_sdu + ); + //CBM + buf_off+=sprintf(buf+buf_off, + "[CBM]\n\tnrt_thr=%u\n\tclp0_thr=%u\n\tclp1_thr=%u\n\ttx_q_threshold=%u\n\trx_q_threshold=%u\n\toam_q_threshold=%u\n\tfree_cell_cnt=%u\n" + ,g_atm_dev.cbm.nrt_thr + ,g_atm_dev.cbm.clp0_thr + ,g_atm_dev.cbm.clp1_thr + ,tx_q_threshold + ,rx_q_threshold + ,oam_q_threshold + ,g_atm_dev.cbm.free_cell_cnt + ); + //QSB + buf_off+=sprintf(buf+buf_off,"[QSB]\n\ttau=%u\n\ttstepc=%u\n\tsbl=%u\n" + ,g_atm_dev.qsb.tau + ,g_atm_dev.qsb.tstepc + ,g_atm_dev.qsb.sbl + ); + buf_off+=sprintf(buf+buf_off,"[Debugging]\n\taal5_need_copy=%u\n",g_atm_dev.aal5.cnt_cpy); + break; + case PROC_VCC: + for(i=CBM_DEFAULT_Q_OFFSET,j=0;i<g_atm_dev.cbm.max_q_off+CBM_DEFAULT_Q_OFFSET;i++){ + if (g_atm_dev.queues[i].free!=1){ + buf_off+=sprintf(buf+buf_off,"vcc[%u]\n\tvpi=%u vci=%u itf=%u qid=%u access_time=%u.%u\n" + ,j++ + ,g_atm_dev.queues[i].vcc->vpi + ,g_atm_dev.queues[i].vcc->vci + ,g_atm_dev.queues[i].vcc->itf + ,i + ,(u32)g_atm_dev.queues[i+CBM_RX_OFFSET].access_time.tv_sec + ,(u32)g_atm_dev.queues[i+CBM_RX_OFFSET].access_time.tv_usec + ); + buf_off+=sprintf(buf+buf_off,"\tqos_tx class=%u max_pcr=%u pcr=%u min_pcr=%u scr=%u mbs=%u cdv=%u\n" + ,g_atm_dev.queues[i].vcc->qos.txtp.traffic_class + ,g_atm_dev.queues[i].vcc->qos.txtp.max_pcr + ,g_atm_dev.queues[i].vcc->qos.txtp.pcr + ,g_atm_dev.queues[i].vcc->qos.txtp.min_pcr + ,g_atm_dev.queues[i].vcc->qos.txtp.scr + ,g_atm_dev.queues[i].vcc->qos.txtp.mbs + ,g_atm_dev.queues[i].vcc->qos.txtp.cdv + ); + buf_off+=sprintf(buf+buf_off,"\tqos_rx class=%u max_pcr=%u pcr=%u min_pcr=%u scr=%u mbs=%u cdv=%u\n" + ,g_atm_dev.queues[i].vcc->qos.rxtp.traffic_class + ,g_atm_dev.queues[i].vcc->qos.rxtp.max_pcr + ,g_atm_dev.queues[i].vcc->qos.rxtp.pcr + ,g_atm_dev.queues[i].vcc->qos.rxtp.min_pcr + ,g_atm_dev.queues[i].vcc->qos.rxtp.scr + ,g_atm_dev.queues[i].vcc->qos.rxtp.mbs + ,g_atm_dev.queues[i].vcc->qos.rxtp.cdv + ); + __amazon_atm_vcc_mib((i+CBM_RX_OFFSET),&mib_vcc); + buf_off+=sprintf(buf+buf_off,"\tCRC error=%u\n", mib_vcc.aal5VccCrcErrors); + buf_off+=sprintf(buf+buf_off,"\toversized packet=%u\n", mib_vcc.aal5VccOverSizedSDUs); +#ifdef AMAZON_ATM_DEBUG + if ( valid_qid(i+CBM_RX_OFFSET)){ + buf_off+=sprintf(buf+buf_off,"\tdownstream statics\n" ); + buf_off+=sprintf(buf+buf_off,"\t\tpackets=%u\n",g_atm_dev.queues[i+CBM_RX_OFFSET].qs[QS_PKT]); + buf_off+=sprintf(buf+buf_off,"\t\terr_packets=%u\n",g_atm_dev.queues[i+CBM_RX_OFFSET].qs[QS_ERR] ); + buf_off+=sprintf(buf+buf_off,"\t\tsw_dropped=%u\n",g_atm_dev.queues[i+CBM_RX_OFFSET].qs[QS_SW_DROP] ); + } + + buf_off+=sprintf(buf+buf_off,"\tupstream statics\n" ); + buf_off+=sprintf(buf+buf_off,"\t\tpackets=%u\n",g_atm_dev.queues[i].qs[QS_PKT]); + buf_off+=sprintf(buf+buf_off,"\t\terr_packets=%u\n",g_atm_dev.queues[i].qs[QS_ERR] ); + buf_off+=sprintf(buf+buf_off,"\t\thw_dropped=%u\n",g_atm_dev.queues[i].qs[QS_HW_DROP] ); + buf_off+=sprintf(buf+buf_off,"\t\tsw_dropped=%u\n",g_atm_dev.queues[i].qs[QS_SW_DROP] ); + +#endif + + } + + } + break; + default: + break; + } + if(buf_off>0) *eof = 1; + return buf_off; +} + +#ifdef AMAZON_TPE_AAL5_RECOVERY +extern int (*tpe_reset)(void); +extern int (*tpe_start)(void); +extern int (*tpe_inject)(void); +/* Brief: Reset TPE hardware + * Description + * This is a wordaround for AAL5 bug. It tries to reset TPE. + * take care of software + * setup all previous connection + */ +int amazon_tpe_reset(void) +{ + struct atm_vcc * vcc; + int err=0; + int i; + u8 * qd_addr; + u32 reg_l, reg_h; + unsigned int a_cfg_value=0; + unsigned int a_cfg_old_value=0; + atm_aal5_ifEntry_t mib_aal5; + atm_cell_ifEntry_t mib_cell; + + //make sure all cells transmitting out first + //Segmentation done + amazon_atm_aal5_mib(&mib_aal5); + reg_l = g_atm_dev.mib_counter.tx_cnt_l; + reg_h = g_atm_dev.mib_counter.tx_cnt_h; + while(1){ + mdelay(10); + amazon_atm_aal5_mib(&mib_aal5); + if( (reg_l == g_atm_dev.mib_counter.tx_cnt_l) && (reg_h == g_atm_dev.mib_counter.tx_cnt_h) ){ + break; + } + AMAZON_TPE_DMSG("AAL5 Segmentation still in progress!\n"); + reg_l = g_atm_dev.mib_counter.tx_cnt_l; + reg_h = g_atm_dev.mib_counter.tx_cnt_h; + } + //QSB done + qd_addr = (u8 *) KSEG1ADDR((unsigned long)g_atm_dev.cbm.qd_addr); + for (i=1;i<15;i++){ + while ( (err=readl(qd_addr+i*CBM_QD_SIZE+0x8)&0xffff) !=0 ){ + mdelay(20); + AMAZON_TPE_DMSG("queue %u not empty (%u)\n",i,err); + } + } + //insurance for interfaces between Aware and CARB + mdelay(100); + amazon_atm_cell_mib(&mib_cell,0); + amazon_atm_cell_mib(&mib_cell,1); + amazon_atm_aal5_mib(&mib_aal5); + + mb(); + while ( (AMAZON_READ_REGISTER_L(AR_CELLRDY_BC0) != 0 ) || (AMAZON_READ_REGISTER_L(AR_CELLRDY_BC0) != 0 ) ){ + AMAZON_TPE_EMSG("\nwaiting for AWARE"); + AMAZON_TPE_EMSG(" BC0 %u ", AMAZON_READ_REGISTER_L(AR_CELLRDY_BC0)); + AMAZON_TPE_EMSG(" BC1 %u ", AMAZON_READ_REGISTER_L(AR_CELLRDY_BC1)); + AMAZON_TPE_EMSG("\n"); + mdelay(1); + } + // disable AAI module + meiDebugRead(A_CFG_ADDR,&a_cfg_value,1); + a_cfg_old_value=a_cfg_value; + a_cfg_value &= (~(0x2800)); + meiDebugWrite(A_CFG_ADDR,&a_cfg_value,1); + //clear buffer + a_cfg_value = 0x1; + meiDebugWrite(AR_CB0_STATUS_ADDR,&a_cfg_value,1); + meiDebugWrite(AR_CB1_STATUS_ADDR,&a_cfg_value,1); + + if ( atm_init_hard(&g_atm_dev) != 0){ + return -EIO; + } + sema_init(&(g_atm_dev.swie.in_sem), 1); + //SWIE lock + clear_bit(SWIE_LOCK, &(g_atm_dev.swie.lock)); + //SWIE wait queue + init_waitqueue_head(&(g_atm_dev.swie.sleep)); + + for (i=CBM_DEFAULT_Q_OFFSET;i<AMAZON_ATM_MAX_QUEUE_NUM/2;i++) { + vcc = g_atm_dev.queues[i].vcc; + if (vcc != NULL){ + set_qsb(vcc, &vcc->qos, i); + set_qd(vcc, i); + mb(); + err=set_htu(vcc,i); + if (err){ + AMAZON_TPE_EMSG("set htu entry fails %u\n",err); + } + } + } + meiDebugWrite(A_CFG_ADDR,&a_cfg_old_value,1); +#if 0 + //reset DFE + *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) | (AMAZON_RST_REQ_DFE); + mb(); + *(AMAZON_RST_REQ) = (* AMAZON_RST_REQ) & (~AMAZON_RST_REQ_DFE); + mb(); +#endif + + return 0; +} + +/* Brief: Send a ATM EoP packet to save DMA channel + */ +int amazon_tpe_inject_debug_cell(void) +{ + //Send a ATM cell to save DMA channel + u8 qid; + unsigned char atm_cell[48]; + qid = 0x11; + AMAZON_TPE_DMSG("qid = %d\n",qid); + memset(atm_cell,0,48); + atm_cell[3] = 0x2; + if ( amazon_atm_swin(qid,atm_cell)) { + AMAZON_TPE_EMSG("cannot insert EoP cell\n"); + return -1; + } + return 0; +} + +/* Brief: start HTU (TPE) + */ + +int amazon_tpe_start(void) +{ + AMAZON_WRITE_REGISTER_L(HTU_CFG_START ,HTU_CFG_ADDR); + wmb(); + return 0; +} +#endif //AMAZON_TPE_AAL5_RECOVERY + +#ifdef AMAZON_CHECK_LINK +extern int (*adsl_link_notify)(int); +/* Brief: notify link status of ADSL link + * Parameters: 0 link down + * 1 link up + * Returns: 0 OK + * Details: called by MEI driver + * should update status and inform upper layer + */ +int amazon_tpe_link_notify(int status) +{ + adsl_link_status = status; + AMAZON_TPE_DMSG("link status %s\n",(status==1)?"Up":"Down"); + if (status == 0){ + //wait until no cells in upstream queues + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(2*HZ); + } + return 0; +} +#endif //ifdef AMAZON_CHECK_LINK + +/* + * Brief: Initialize ATM module + * + * Return Value: ENOMEM - No memory available + * EBUSY - Cannot register atm device + * ERESTARTSYS - Process interrupted by other signal + * 0 - OK, module initialized + * + * Description: + * This function registers an atm device for all UTOPIA devices. + * It also allocates memory for the private device data structures + */ +int __init amazon_atm_net_init(void) +{ + int i; + int err=0; + amazon_atm_dev_t *dev = NULL; + + if ((dev=amazon_atm_create()) != NULL){ + for(i=0;i<AMAZON_ATM_PORT_NUM;i++){ + if (!dev->ports[i].enable){ + amazon_atm_devs[i] = NULL; + continue; + } + amazon_atm_devs[i] =atm_dev_register("amazon_atm",&amazon_atm_ops,-1,0UL); + if (amazon_atm_devs[i] == NULL){ + AMAZON_TPE_EMSG("atm_dev_register fails\n"); + err = -EIO; + goto amazon_atm_net_init_exit; + }else{ + AMAZON_TPE_DMSG("registering device %u\n",i); + amazon_atm_devs[i]->ci_range.vpi_bits = 8; + amazon_atm_devs[i]->ci_range.vci_bits = 16; + amazon_atm_devs[i]->link_rate = dev->ports[i].tx_max_cr; + amazon_atm_devs[i]->dev_data = (void *) i; + } + } + + }else{ + err = -ENOMEM; + AMAZON_TPE_EMSG("cannot init atm device\n"); + goto amazon_atm_net_init_exit; + } +#ifdef AMAZON_TPE_AAL5_RECOVERY + tpe_reset = & amazon_tpe_reset; + tpe_start = & amazon_tpe_start; + tpe_inject = & amazon_tpe_inject_debug_cell; +#endif //AMAZON_TPE_AAL5_RECOVERY +#ifdef AMAZON_CHECK_LINK + adsl_link_notify=amazon_tpe_link_notify; +#endif //AMAZON_CHECK_LINK +amazon_atm_net_init_exit: + return err; +} + +void __exit amazon_atm_net_cleanup(void) +{ + int i; + amazon_atm_cleanup(); + for(i=0;i<AMAZON_ATM_PORT_NUM;i++){ + if (amazon_atm_devs[i] != NULL){ + AMAZON_TPE_DMSG("unregister dev %u\n",i); + atm_dev_deregister(amazon_atm_devs[i]); + } + } + return; +} +EXPORT_SYMBOL(get_oam_time_stamp); + +MODULE_LICENSE ("GPL"); +MODULE_AUTHOR("Infineon IFAP DC COM peng.liu@infineon.com"); +MODULE_DESCRIPTION("AMAZON ATM driver"); + +module_init(amazon_atm_net_init); +module_exit(amazon_atm_net_cleanup); + + + + + diff --git a/target/linux/amazon/files/drivers/char/admmod.c b/target/linux/amazon/files/drivers/char/admmod.c new file mode 100644 index 0000000000..0229f53f55 --- /dev/null +++ b/target/linux/amazon/files/drivers/char/admmod.c @@ -0,0 +1,1486 @@ +/****************************************************************************** + Copyright (c) 2004, Infineon Technologies. All rights reserved. + + No Warranty + Because the program is licensed free of charge, there is no warranty for + the program, to the extent permitted by applicable law. Except when + otherwise stated in writing the copyright holders and/or other parties + provide the program "as is" without warranty of any kind, either + expressed or implied, including, but not limited to, the implied + warranties of merchantability and fitness for a particular purpose. The + entire risk as to the quality and performance of the program is with + you. should the program prove defective, you assume the cost of all + necessary servicing, repair or correction. + + In no event unless required by applicable law or agreed to in writing + will any copyright holder, or any other party who may modify and/or + redistribute the program as permitted above, be liable to you for + damages, including any general, special, incidental or consequential + damages arising out of the use or inability to use the program + (including but not limited to loss of data or data being rendered + inaccurate or losses sustained by you or third parties or a failure of + the program to operate with any other programs), even if such holder or + other party has been advised of the possibility of such damages. + ****************************************************************************** + Module : admmod.c + Date : 2004-09-01 + Description : JoeLin + Remarks: + + Revision: + MarsLin, add to support VLAN + + *****************************************************************************/ +//000001.joelin 2005/06/02 add"ADM6996_MDC_MDIO_MODE" define, +// if define ADM6996_MDC_MDIO_MODE==> ADM6996LC and ADM6996I will be in MDIO/MDC(SMI)(16 bit) mode, +// amazon should contrl ADM6996 by MDC/MDIO pin +// if undef ADM6996_MDC_MDIO_MODE==> ADM6996 will be in EEProm(32 bit) mode, +// amazon should contrl ADM6996 by GPIO15,16,17,18 pin +/* 507281:linmars 2005/07/28 support MDIO/EEPROM config mode */ +/* 509201:linmars remove driver testing codes */ + +#include <linux/module.h> +#include <linux/string.h> +#include <linux/proc_fs.h> +#include <linux/delay.h> +#include <asm/uaccess.h> +#include <linux/init.h> +#include <linux/ioctl.h> +#include <asm/atomic.h> +#include <asm-mips/amazon/amazon.h> +#include <asm-mips/amazon/adm6996.h> +//#include <linux/amazon/adm6996.h> + + +unsigned int ifx_sw_conf[ADM_SW_MAX_PORT_NUM+1] = \ + {ADM_SW_PORT0_CONF, ADM_SW_PORT1_CONF, ADM_SW_PORT2_CONF, \ + ADM_SW_PORT3_CONF, ADM_SW_PORT4_CONF, ADM_SW_PORT5_CONF}; +unsigned int ifx_sw_bits[8] = \ + {0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff}; +unsigned int ifx_sw_vlan_port[6] = {0, 2, 4, 6, 7, 8}; +//050613:fchang +/* 507281:linmars start */ +#ifdef CONFIG_SWITCH_ADM6996_MDIO +#define ADM6996_MDC_MDIO_MODE 1 //000001.joelin +#else +#undef ADM6996_MDC_MDIO_MODE +#endif +/* 507281:linmars end */ +#define adm6996i 0 +#define adm6996lc 1 +#define adm6996l 2 +unsigned int adm6996_mode=adm6996i; +/* + initialize GPIO pins. + output mode, low +*/ +void ifx_gpio_init(void) +{ + //GPIO16,17,18 direction:output + //GPIO16,17,18 output 0 + + AMAZON_SW_REG(AMAZON_GPIO_P1_DIR) |= (GPIO_MDIO|GPIO_MDCS|GPIO_MDC); + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT) =AMAZON_SW_REG(AMAZON_GPIO_P1_IN)& ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC); + +} + +/* read one bit from mdio port */ +int ifx_sw_mdio_readbit(void) +{ + //int val; + + //val = (AMAZON_SW_REG(GPIO_conf0_REG) & GPIO0_INPUT_MASK) >> 8; + //return val; + //GPIO16 + return AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&1; +} + +/* + MDIO mode selection + 1 -> output + 0 -> input + + switch input/output mode of GPIO 0 +*/ +void ifx_mdio_mode(int mode) +{ +// AMAZON_SW_REG(GPIO_conf0_REG) = mode ? GPIO_ENABLEBITS : +// ((GPIO_ENABLEBITS | MDIO_INPUT) & ~MDIO_OUTPUT_EN); + mode?(AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)|=GPIO_MDIO): + (AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)&=~GPIO_MDIO); + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_DIR); + mode?(r|=GPIO_MDIO):(r&=~GPIO_MDIO); + AMAZON_SW_REG(AMAZON_GPIO_P1_DIR)=r;*/ +} + +void ifx_mdc_hi(void) +{ + //GPIO_SET_HI(GPIO_MDC); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDC; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r|=GPIO_MDC; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDC; +} + +void ifx_mdio_hi(void) +{ + //GPIO_SET_HI(GPIO_MDIO); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDIO; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r|=GPIO_MDIO; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDIO; +} + +void ifx_mdcs_hi(void) +{ + //GPIO_SET_HI(GPIO_MDCS); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)|=GPIO_MDCS; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r|=GPIO_MDCS; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)|GPIO_MDCS; +} + +void ifx_mdc_lo(void) +{ + //GPIO_SET_LOW(GPIO_MDC); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDC; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r&=~GPIO_MDC; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDC); +} + +void ifx_mdio_lo(void) +{ + //GPIO_SET_LOW(GPIO_MDIO); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDIO; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r&=~GPIO_MDIO; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDIO); +} + +void ifx_mdcs_lo(void) +{ + //GPIO_SET_LOW(GPIO_MDCS); + //AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)&=~GPIO_MDCS; + /*int r=AMAZON_SW_REG(AMAZON_GPIO_P1_OUT); + r&=~GPIO_MDCS; + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=r;*/ + + AMAZON_SW_REG(AMAZON_GPIO_P1_OUT)=AMAZON_SW_REG(AMAZON_GPIO_P1_IN)&(~GPIO_MDCS); +} + +/* + mdc pulse + 0 -> 1 -> 0 +*/ +static void ifx_sw_mdc_pulse(void) +{ + ifx_mdc_lo(); + udelay(ADM_SW_MDC_DOWN_DELAY); + ifx_mdc_hi(); + udelay(ADM_SW_MDC_UP_DELAY); + ifx_mdc_lo(); +} + +/* + mdc toggle + 1 -> 0 +*/ +static void ifx_sw_mdc_toggle(void) +{ + ifx_mdc_hi(); + udelay(ADM_SW_MDC_UP_DELAY); + ifx_mdc_lo(); + udelay(ADM_SW_MDC_DOWN_DELAY); +} + +/* + enable eeprom write + For ATC 93C66 type EEPROM; accessing ADM6996 internal EEPROM type registers +*/ +static void ifx_sw_eeprom_write_enable(void) +{ + unsigned int op; + + ifx_mdcs_lo(); + ifx_mdc_lo(); + ifx_mdio_hi(); + udelay(ADM_SW_CS_DELAY); + /* enable chip select */ + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + /* start bit */ + ifx_mdio_hi(); + ifx_sw_mdc_pulse(); + + /* eeprom write enable */ + op = ADM_SW_BIT_MASK_4; + while (op) + { + if (op & ADM_SW_EEPROM_WRITE_ENABLE) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 3); + while (op) + { + ifx_mdio_lo(); + ifx_sw_mdc_pulse(); + op >>= 1; + } + /* disable chip select */ + ifx_mdcs_lo(); + udelay(ADM_SW_CS_DELAY); + ifx_sw_mdc_pulse(); +} + +/* + disable eeprom write +*/ +static void ifx_sw_eeprom_write_disable(void) +{ + unsigned int op; + + ifx_mdcs_lo(); + ifx_mdc_lo(); + ifx_mdio_hi(); + udelay(ADM_SW_CS_DELAY); + /* enable chip select */ + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + + /* start bit */ + ifx_mdio_hi(); + ifx_sw_mdc_pulse(); + /* eeprom write disable */ + op = ADM_SW_BIT_MASK_4; + while (op) + { + if (op & ADM_SW_EEPROM_WRITE_DISABLE) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 3); + while (op) + { + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + /* disable chip select */ + ifx_mdcs_lo(); + udelay(ADM_SW_CS_DELAY); + ifx_sw_mdc_pulse(); +} + +/* + read registers from ADM6996 + serial registers start at 0x200 (addr bit 9 = 1b) + EEPROM registers -> 16bits; Serial registers -> 32bits +*/ +#ifdef ADM6996_MDC_MDIO_MODE //smi mode//000001.joelin +static int ifx_sw_read_adm6996i_smi(unsigned int addr, unsigned int *dat) +{ + addr=(addr<<16)&0x3ff0000; + AMAZON_SW_REG(AMAZON_SW_MDIO_ACC) =(0xC0000000|addr); + while ((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x80000000){}; + *dat=((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x0FFFF); + return 0; +} +#endif + +static int ifx_sw_read_adm6996i(unsigned int addr, unsigned int *dat) +{ + unsigned int op; + + ifx_gpio_init(); + + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + + ifx_mdcs_lo(); + ifx_mdc_lo(); + ifx_mdio_lo(); + + udelay(ADM_SW_CS_DELAY); + + /* preamble, 32 bit 1 */ + ifx_mdio_hi(); + op = ADM_SW_BIT_MASK_32; + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* command start (01b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_START) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* read command (10b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_READ) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* send address A9 ~ A0 */ + op = ADM_SW_BIT_MASK_10; + while (op) + { + if (op & addr) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* turnaround bits */ + op = ADM_SW_BIT_MASK_2; + ifx_mdio_hi(); + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + udelay(ADM_SW_MDC_DOWN_DELAY); + + /* set MDIO pin to input mode */ + ifx_mdio_mode(ADM_SW_MDIO_INPUT); + + /* start read data */ + *dat = 0; +//adm6996i op = ADM_SW_BIT_MASK_32; + op = ADM_SW_BIT_MASK_16;//adm6996i + while (op) + { + *dat <<= 1; + if (ifx_sw_mdio_readbit()) *dat |= 1; + ifx_sw_mdc_toggle(); + + op >>= 1; + } + + /* set MDIO to output mode */ + ifx_mdio_mode(ADM_SW_MDIO_OUTPUT); + + /* dummy clock */ + op = ADM_SW_BIT_MASK_4; + ifx_mdio_lo(); + while(op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + ifx_mdc_lo(); + ifx_mdio_lo(); + ifx_mdcs_hi(); + + /* EEPROM registers */ +//adm6996i if (!(addr & 0x200)) +//adm6996i { +//adm6996i if (addr % 2) +//adm6996i *dat >>= 16; +//adm6996i else +//adm6996i *dat &= 0xffff; +//adm6996i } + + return 0; +} +//adm6996 +static int ifx_sw_read_adm6996l(unsigned int addr, unsigned int *dat) +{ + unsigned int op; + + ifx_gpio_init(); + + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + + ifx_mdcs_lo(); + ifx_mdc_lo(); + ifx_mdio_lo(); + + udelay(ADM_SW_CS_DELAY); + + /* preamble, 32 bit 1 */ + ifx_mdio_hi(); + op = ADM_SW_BIT_MASK_32; + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* command start (01b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_START) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* read command (10b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_READ) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* send address A9 ~ A0 */ + op = ADM_SW_BIT_MASK_10; + while (op) + { + if (op & addr) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* turnaround bits */ + op = ADM_SW_BIT_MASK_2; + ifx_mdio_hi(); + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + udelay(ADM_SW_MDC_DOWN_DELAY); + + /* set MDIO pin to input mode */ + ifx_mdio_mode(ADM_SW_MDIO_INPUT); + + /* start read data */ + *dat = 0; + op = ADM_SW_BIT_MASK_32; + while (op) + { + *dat <<= 1; + if (ifx_sw_mdio_readbit()) *dat |= 1; + ifx_sw_mdc_toggle(); + + op >>= 1; + } + + /* set MDIO to output mode */ + ifx_mdio_mode(ADM_SW_MDIO_OUTPUT); + + /* dummy clock */ + op = ADM_SW_BIT_MASK_4; + ifx_mdio_lo(); + while(op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + ifx_mdc_lo(); + ifx_mdio_lo(); + ifx_mdcs_hi(); + + /* EEPROM registers */ + if (!(addr & 0x200)) + { + if (addr % 2) + *dat >>= 16; + else + *dat &= 0xffff; + } + + return 0; +} + +static int ifx_sw_read(unsigned int addr, unsigned int *dat) +{ +#ifdef ADM6996_MDC_MDIO_MODE //smi mode ////000001.joelin + ifx_sw_read_adm6996i_smi(addr,dat); +#else + if (adm6996_mode==adm6996i) ifx_sw_read_adm6996i(addr,dat); + else ifx_sw_read_adm6996l(addr,dat); +#endif + return 0; + +} + +/* + write register to ADM6996 eeprom registers +*/ +//for adm6996i -start +#ifdef ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin +static int ifx_sw_write_adm6996i_smi(unsigned int addr, unsigned int dat) +{ + + AMAZON_SW_REG(AMAZON_SW_MDIO_ACC) = ((addr<<16)&0x3ff0000)|dat|0x80000000; + while ((AMAZON_SW_REG(AMAZON_SW_MDIO_ACC))&0x80000000){}; + + return 0; + +} +#endif //ADM6996_MDC_MDIO_MODE //000001.joelin + +static int ifx_sw_write_adm6996i(unsigned int addr, unsigned int dat) +{ + unsigned int op; + + ifx_gpio_init(); + + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + + ifx_mdcs_lo(); + ifx_mdc_lo(); + ifx_mdio_lo(); + + udelay(ADM_SW_CS_DELAY); + + /* preamble, 32 bit 1 */ + ifx_mdio_hi(); + op = ADM_SW_BIT_MASK_32; + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* command start (01b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_START) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* write command (01b) */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_SMI_WRITE) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* send address A9 ~ A0 */ + op = ADM_SW_BIT_MASK_10; + while (op) + { + if (op & addr) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* turnaround bits */ + op = ADM_SW_BIT_MASK_2; + ifx_mdio_hi(); + while (op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + udelay(ADM_SW_MDC_DOWN_DELAY); + + /* set MDIO pin to output mode */ + ifx_mdio_mode(ADM_SW_MDIO_OUTPUT); + + + /* start write data */ + op = ADM_SW_BIT_MASK_16; + while (op) + { + if (op & dat) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_toggle(); + op >>= 1; + } + + // /* set MDIO to output mode */ + // ifx_mdio_mode(ADM_SW_MDIO_OUTPUT); + + /* dummy clock */ + op = ADM_SW_BIT_MASK_4; + ifx_mdio_lo(); + while(op) + { + ifx_sw_mdc_pulse(); + op >>= 1; + } + + ifx_mdc_lo(); + ifx_mdio_lo(); + ifx_mdcs_hi(); + + /* EEPROM registers */ +//adm6996i if (!(addr & 0x200)) +//adm6996i { +//adm6996i if (addr % 2) +//adm6996i *dat >>= 16; +//adm6996i else +//adm6996i *dat &= 0xffff; +//adm6996i } + + return 0; +} +//for adm6996i-end +static int ifx_sw_write_adm6996l(unsigned int addr, unsigned int dat) +{ + unsigned int op; + + ifx_gpio_init(); + + /* enable write */ + ifx_sw_eeprom_write_enable(); + + /* chip select */ + ifx_mdcs_hi(); + udelay(ADM_SW_CS_DELAY); + + /* issue write command */ + /* start bit */ + ifx_mdio_hi(); + ifx_sw_mdc_pulse(); + + /* EEPROM write command */ + op = ADM_SW_BIT_MASK_2; + while (op) + { + if (op & ADM_SW_EEPROM_WRITE) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_pulse(); + op >>= 1; + } + + /* send address A7 ~ A0 */ + op = ADM_SW_BIT_MASK_1 << (EEPROM_TYPE - 1); + + while (op) + { + if (op & addr) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_toggle(); + op >>= 1; + } + + /* start write data */ + op = ADM_SW_BIT_MASK_16; + while (op) + { + if (op & dat) + ifx_mdio_hi(); + else + ifx_mdio_lo(); + + ifx_sw_mdc_toggle(); + op >>= 1; + } + + /* disable cs & wait 1 clock */ + ifx_mdcs_lo(); + udelay(ADM_SW_CS_DELAY); + ifx_sw_mdc_toggle(); + + ifx_sw_eeprom_write_disable(); + + return 0; +} + +static int ifx_sw_write(unsigned int addr, unsigned int dat) +{ +#ifdef ADM6996_MDC_MDIO_MODE //smi mode ////000001.joelin + ifx_sw_write_adm6996i_smi(addr,dat); +#else //000001.joelin + if (adm6996_mode==adm6996i) ifx_sw_write_adm6996i(addr,dat); + else ifx_sw_write_adm6996l(addr,dat); +#endif //000001.joelin + return 0; +} + +/* + do switch PHY reset +*/ +int ifx_sw_reset(void) +{ + /* reset PHY */ + ifx_sw_write(ADM_SW_PHY_RESET, 0); + + return 0; +} + +/* 509201:linmars start */ +#if 0 +/* + check port status +*/ +int ifx_check_port_status(int port) +{ + unsigned int val; + + if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM)) + { + ifx_printf(("error on port number (%d)!!\n", port)); + return -1; + } + + ifx_sw_read(ifx_sw_conf[port], &val); + if (ifx_sw_conf[port]%2) val >>= 16; + /* only 16bits are effective */ + val &= 0xFFFF; + + ifx_printf(("Port %d status (%.8x): \n", port, val)); + + if (val & ADM_SW_PORT_FLOWCTL) + ifx_printf(("\t802.3x flow control supported!\n")); + else + ifx_printf(("\t802.3x flow control not supported!\n")); + + if (val & ADM_SW_PORT_AN) + ifx_printf(("\tAuto negotiation ON!\n")); + else + ifx_printf(("\tAuto negotiation OFF!\n")); + + if (val & ADM_SW_PORT_100M) + ifx_printf(("\tLink at 100M!\n")); + else + ifx_printf(("\tLink at 10M!\n")); + + if (val & ADM_SW_PORT_FULL) + ifx_printf(("\tFull duplex!\n")); + else + ifx_printf(("\tHalf duplex!\n")); + + if (val & ADM_SW_PORT_DISABLE) + ifx_printf(("\tPort disabled!\n")); + else + ifx_printf(("\tPort enabled!\n")); + + if (val & ADM_SW_PORT_TOS) + ifx_printf(("\tTOS enabled!\n")); + else + ifx_printf(("\tTOS disabled!\n")); + + if (val & ADM_SW_PORT_PPRI) + ifx_printf(("\tPort priority first!\n")); + else + ifx_printf(("\tVLAN or TOS priority first!\n")); + + if (val & ADM_SW_PORT_MDIX) + ifx_printf(("\tAuto MDIX!\n")); + else + ifx_printf(("\tNo auto MDIX\n")); + + ifx_printf(("\tPVID: %d\n", \ + ((val >> ADM_SW_PORT_PVID_SHIFT)&ifx_sw_bits[ADM_SW_PORT_PVID_BITS]))); + + return 0; +} +/* + initialize a VLAN + clear all VLAN bits +*/ +int ifx_sw_vlan_init(int vlanid) +{ + ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, 0); + + return 0; +} + +/* + add a port to certain vlan +*/ +int ifx_sw_vlan_add(int port, int vlanid) +{ + int reg = 0; + + if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM) || (vlanid < 0) || + (vlanid > ADM_SW_MAX_VLAN_NUM)) + { + ifx_printf(("Port number or VLAN number ERROR!!\n")); + return -1; + } + ifx_sw_read(ADM_SW_VLAN0_CONF + vlanid, ®); + reg |= (1 << ifx_sw_vlan_port[port]); + ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, reg); + + return 0; +} + +/* + delete a given port from certain vlan +*/ +int ifx_sw_vlan_del(int port, int vlanid) +{ + unsigned int reg = 0; + + if ((port < 0) || (port > ADM_SW_MAX_PORT_NUM) || (vlanid < 0) || (vlanid > ADM_SW_MAX_VLAN_NUM)) + { + ifx_printf(("Port number or VLAN number ERROR!!\n")); + return -1; + } + ifx_sw_read(ADM_SW_VLAN0_CONF + vlanid, ®); + reg &= ~(1 << ifx_sw_vlan_port[port]); + ifx_sw_write(ADM_SW_VLAN0_CONF + vlanid, reg); + + return 0; +} + +/* + default VLAN setting + + port 0~3 as untag port and PVID = 1 + VLAN1: port 0~3 and port 5 (MII) +*/ +static int ifx_sw_init(void) +{ + ifx_printf(("Setting default ADM6996 registers... \n")); + + /* MAC clone, 802.1q based VLAN */ + ifx_sw_write(ADM_SW_VLAN_MODE, 0xff30); + /* auto MDIX, PVID=1, untag */ + ifx_sw_write(ADM_SW_PORT0_CONF, 0x840f); + ifx_sw_write(ADM_SW_PORT1_CONF, 0x840f); + ifx_sw_write(ADM_SW_PORT2_CONF, 0x840f); + ifx_sw_write(ADM_SW_PORT3_CONF, 0x840f); + /* auto MDIX, PVID=2, untag */ + ifx_sw_write(ADM_SW_PORT5_CONF, 0x880f); + /* port 0~3 & 5 as VLAN1 */ + ifx_sw_write(ADM_SW_VLAN0_CONF+1, 0x0155); + + return 0; +} +#endif +/* 509201:linmars end */ + +int adm_open(struct inode *node, struct file *filp) +{ + MOD_INC_USE_COUNT; + return 0; +} + +ssize_t adm_read(struct file *filep, char *buf, size_t count, loff_t *ppos) +{ + return count; +} + +ssize_t adm_write(struct file *filep, const char *buf, size_t count, loff_t *ppos) +{ + return count; +} + +/* close */ +int adm_release(struct inode *inode, struct file *filp) +{ + MOD_DEC_USE_COUNT; + return 0; +} + +/* IOCTL function */ +int adm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long args) +{ + PREGRW uREGRW; + unsigned int rtval; + unsigned int val; //6996i + unsigned int control[6] ; //6996i + unsigned int status[6] ; //6996i + + PMACENTRY mMACENTRY;//adm6996i + PPROTOCOLFILTER uPROTOCOLFILTER ;///adm6996i + + if (_IOC_TYPE(cmd) != ADM_MAGIC) + { + printk("adm_ioctl: IOC_TYPE(%x) != ADM_MAGIC(%x)! \n", _IOC_TYPE(cmd), ADM_MAGIC); + return (-EINVAL); + } + + if(_IOC_NR(cmd) >= KEY_IOCTL_MAX_KEY) + { + printk(KERN_WARNING "adm_ioctl: IOC_NR(%x) invalid! \n", _IOC_NR(cmd)); + return (-EINVAL); + } + + switch (cmd) + { + case ADM_IOCTL_REGRW: + { + uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL); + rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW)); + if (rtval != 0) + { + printk("ADM_IOCTL_REGRW: copy from user FAILED!! \n"); + return (-EFAULT); + } + + switch(uREGRW->mode) + { + case REG_READ: + uREGRW->value = 0x12345678;//inl(uREGRW->addr); + copy_to_user((PREGRW)args, uREGRW, sizeof(REGRW)); + break; + case REG_WRITE: + //outl(uREGRW->value, uREGRW->addr); + break; + + default: + printk("No such Register Read/Write function!! \n"); + return (-EFAULT); + } + kfree(uREGRW); + break; + } + + case ADM_SW_IOCTL_REGRW: + { + unsigned int val = 0xff; + + uREGRW = (PREGRW)kmalloc(sizeof(REGRW), GFP_KERNEL); + rtval = copy_from_user(uREGRW, (PREGRW)args, sizeof(REGRW)); + if (rtval != 0) + { + printk("ADM_IOCTL_REGRW: copy from user FAILED!! \n"); + return (-EFAULT); + } + + switch(uREGRW->mode) + { + case REG_READ: + ifx_sw_read(uREGRW->addr, &val); + uREGRW->value = val; + copy_to_user((PREGRW)args, uREGRW, sizeof(REGRW)); + break; + + case REG_WRITE: + ifx_sw_write(uREGRW->addr, uREGRW->value); + break; + default: + printk("No such Register Read/Write function!! \n"); + return (-EFAULT); + } + kfree(uREGRW); + break; + } +/* 509201:linmars start */ +#if 0 + case ADM_SW_IOCTL_PORTSTS: + for (rtval = 0; rtval < ADM_SW_MAX_PORT_NUM+1; rtval++) + ifx_check_port_status(rtval); + break; + case ADM_SW_IOCTL_INIT: + ifx_sw_init(); + break; +#endif +/* 509201:linmars end */ +//adm6996i + case ADM_SW_IOCTL_MACENTRY_ADD: + case ADM_SW_IOCTL_MACENTRY_DEL: + case ADM_SW_IOCTL_MACENTRY_GET_INIT: + case ADM_SW_IOCTL_MACENTRY_GET_MORE: + + + mMACENTRY = (PMACENTRY)kmalloc(sizeof(MACENTRY), GFP_KERNEL); + rtval = copy_from_user(mMACENTRY, (PMACENTRY)args, sizeof(MACENTRY)); + if (rtval != 0) + { + printk("ADM_SW_IOCTL_MACENTRY: copy from user FAILED!! \n"); + return (-EFAULT); + } + control[0]=(mMACENTRY->mac_addr[1]<<8)+mMACENTRY->mac_addr[0] ; + control[1]=(mMACENTRY->mac_addr[3]<<8)+mMACENTRY->mac_addr[2] ; + control[2]=(mMACENTRY->mac_addr[5]<<8)+mMACENTRY->mac_addr[4] ; + control[3]=(mMACENTRY->fid&0xf)+((mMACENTRY->portmap&0x3f)<<4); + if (((mMACENTRY->info_type)&0x01)) control[4]=(mMACENTRY->ctrl.info_ctrl)+0x1000; //static ,info control + else control[4]=((mMACENTRY->ctrl.age_timer)&0xff);//not static ,agetimer + if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) { + //initial the pointer to the first address + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + control[5]=0x030;//initial the first address + ifx_sw_write(0x11f,control[5]); + + + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + + } //if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) + if (cmd==ADM_SW_IOCTL_MACENTRY_ADD) control[5]=0x07;//create a new address + else if (cmd==ADM_SW_IOCTL_MACENTRY_DEL) control[5]=0x01f;//erased an existed address + else if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) + control[5]=0x02c;//search by the mac address field + + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + ifx_sw_write(0x11a,control[0]); + ifx_sw_write(0x11b,control[1]); + ifx_sw_write(0x11c,control[2]); + ifx_sw_write(0x11d,control[3]); + ifx_sw_write(0x11e,control[4]); + ifx_sw_write(0x11f,control[5]); + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + val=((val&0x7000)>>12);//result ,status5[14:12] + mMACENTRY->result=val; + + if (!val) { + printk(" Command OK!! \n"); + if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) { + ifx_sw_read(0x120,&(status[0])); + ifx_sw_read(0x121,&(status[1])); + ifx_sw_read(0x122,&(status[2])); + ifx_sw_read(0x123,&(status[3])); + ifx_sw_read(0x124,&(status[4])); + ifx_sw_read(0x125,&(status[5])); + + + mMACENTRY->mac_addr[0]=(status[0]&0x00ff) ; + mMACENTRY->mac_addr[1]=(status[0]&0xff00)>>8 ; + mMACENTRY->mac_addr[2]=(status[1]&0x00ff) ; + mMACENTRY->mac_addr[3]=(status[1]&0xff00)>>8 ; + mMACENTRY->mac_addr[4]=(status[2]&0x00ff) ; + mMACENTRY->mac_addr[5]=(status[2]&0xff00)>>8 ; + mMACENTRY->fid=(status[3]&0xf); + mMACENTRY->portmap=((status[3]>>4)&0x3f); + if (status[5]&0x2) {//static info_ctrl //status5[1]???? + mMACENTRY->ctrl.info_ctrl=(status[4]&0x00ff); + mMACENTRY->info_type=1; + } + else {//not static age_timer + mMACENTRY->ctrl.age_timer=(status[4]&0x00ff); + mMACENTRY->info_type=0; + } +//status5[13]???? mMACENTRY->occupy=(status[5]&0x02)>>1;//status5[1] + mMACENTRY->occupy=(status[5]&0x02000)>>13;//status5[13] ??? + mMACENTRY->bad=(status[5]&0x04)>>2;//status5[2] + }//if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) + + } + else if (val==0x001) + printk(" All Entry Used!! \n"); + else if (val==0x002) + printk(" Entry Not Found!! \n"); + else if (val==0x003) + printk(" Try Next Entry!! \n"); + else if (val==0x005) + printk(" Command Error!! \n"); + else + printk(" UnKnown Error!! \n"); + + copy_to_user((PMACENTRY)args, mMACENTRY,sizeof(MACENTRY)); + + break; + + case ADM_SW_IOCTL_FILTER_ADD: + case ADM_SW_IOCTL_FILTER_DEL: + case ADM_SW_IOCTL_FILTER_GET: + + uPROTOCOLFILTER = (PPROTOCOLFILTER)kmalloc(sizeof(PROTOCOLFILTER), GFP_KERNEL); + rtval = copy_from_user(uPROTOCOLFILTER, (PPROTOCOLFILTER)args, sizeof(PROTOCOLFILTER)); + if (rtval != 0) + { + printk("ADM_SW_IOCTL_FILTER_ADD: copy from user FAILED!! \n"); + return (-EFAULT); + } + + if(cmd==ADM_SW_IOCTL_FILTER_DEL) { //delete filter + uPROTOCOLFILTER->ip_p=00; //delet filter + uPROTOCOLFILTER->action=00; //delete filter + } //delete filter + + ifx_sw_read(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), &val);//rx68~rx6b,protocol filter0~7 + + if (((uPROTOCOLFILTER->protocol_filter_num)%2)==00){ + if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= val&0x00ff;//get filter ip_p + else val=(val&0xff00)|(uPROTOCOLFILTER->ip_p);//set filter ip_p + } + else { + if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= (val>>8);//get filter ip_p + else val=(val&0x00ff)|((uPROTOCOLFILTER->ip_p)<<8);//set filter ip_p + } + if(cmd!=ADM_SW_IOCTL_FILTER_GET) ifx_sw_write(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), val);//write rx68~rx6b,protocol filter0~7 + + ifx_sw_read(0x95, &val); //protocol filter action + if(cmd==ADM_SW_IOCTL_FILTER_GET) { + uPROTOCOLFILTER->action= ((val>>(uPROTOCOLFILTER->protocol_filter_num*2))&0x3);//get filter action + copy_to_user((PPROTOCOLFILTER)args, uPROTOCOLFILTER, sizeof(PROTOCOLFILTER)); + + } + else { + val=(val&(~(0x03<<(uPROTOCOLFILTER->protocol_filter_num*2))))|(((uPROTOCOLFILTER->action)&0x03)<<(uPROTOCOLFILTER->protocol_filter_num*2)); + // printk("%d----\n",val); + ifx_sw_write(0x95, val); //write protocol filter action + } + + break; +//adm6996i + + /* others */ + default: + return -EFAULT; + } + /* end of switch */ + return 0; +} + +/* Santosh: handle IGMP protocol filter ADD/DEL/GET */ +int adm_process_protocol_filter_request (unsigned int cmd, PPROTOCOLFILTER uPROTOCOLFILTER) +{ + unsigned int val; //6996i + + if(cmd==ADM_SW_IOCTL_FILTER_DEL) { //delete filter + uPROTOCOLFILTER->ip_p=00; //delet filter + uPROTOCOLFILTER->action=00; //delete filter + } //delete filter + + ifx_sw_read(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), &val);//rx68~rx6b,protocol filter0~7 + + if (((uPROTOCOLFILTER->protocol_filter_num)%2)==00){ + if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= val&0x00ff;//get filter ip_p + else val=(val&0xff00)|(uPROTOCOLFILTER->ip_p);//set filter ip_p + } + else { + if(cmd==ADM_SW_IOCTL_FILTER_GET) uPROTOCOLFILTER->ip_p= (val>>8);//get filter ip_p + else val=(val&0x00ff)|((uPROTOCOLFILTER->ip_p)<<8);//set filter ip_p + } + if(cmd!=ADM_SW_IOCTL_FILTER_GET) ifx_sw_write(((uPROTOCOLFILTER->protocol_filter_num/2)+0x68), val);//write rx68~rx6b,protocol filter0~7 + + ifx_sw_read(0x95, &val); //protocol filter action + if(cmd==ADM_SW_IOCTL_FILTER_GET) { + uPROTOCOLFILTER->action= ((val>>(uPROTOCOLFILTER->protocol_filter_num*2))&0x3);//get filter action + } + else { + val=(val&(~(0x03<<(uPROTOCOLFILTER->protocol_filter_num*2))))|(((uPROTOCOLFILTER->action)&0x03)<<(uPROTOCOLFILTER->protocol_filter_num*2)); + ifx_sw_write(0x95, val); //write protocol filter action + } + + return 0; +} + + +/* Santosh: function for MAC ENTRY ADD/DEL/GET */ + +int adm_process_mac_table_request (unsigned int cmd, PMACENTRY mMACENTRY) +{ + unsigned int rtval; + unsigned int val; //6996i + unsigned int control[6] ; //6996i + unsigned int status[6] ; //6996i + + // printk ("adm_process_mac_table_request: enter\n"); + + control[0]=(mMACENTRY->mac_addr[1]<<8)+mMACENTRY->mac_addr[0] ; + control[1]=(mMACENTRY->mac_addr[3]<<8)+mMACENTRY->mac_addr[2] ; + control[2]=(mMACENTRY->mac_addr[5]<<8)+mMACENTRY->mac_addr[4] ; + control[3]=(mMACENTRY->fid&0xf)+((mMACENTRY->portmap&0x3f)<<4); + + if (((mMACENTRY->info_type)&0x01)) control[4]=(mMACENTRY->ctrl.info_ctrl)+0x1000; //static ,info control + else control[4]=((mMACENTRY->ctrl.age_timer)&0xff);//not static ,agetimer + if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) { + //initial the pointer to the first address + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + control[5]=0x030;//initial the first address + ifx_sw_write(0x11f,control[5]); + + + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + + } //if (cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT) + if (cmd==ADM_SW_IOCTL_MACENTRY_ADD) control[5]=0x07;//create a new address + else if (cmd==ADM_SW_IOCTL_MACENTRY_DEL) control[5]=0x01f;//erased an existed address + else if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) + control[5]=0x02c;//search by the mac address field + + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + ifx_sw_write(0x11a,control[0]); + ifx_sw_write(0x11b,control[1]); + ifx_sw_write(0x11c,control[2]); + ifx_sw_write(0x11d,control[3]); + ifx_sw_write(0x11e,control[4]); + ifx_sw_write(0x11f,control[5]); + val=0x8000;//busy ,status5[15] + while(val&0x8000){ //check busy ? + ifx_sw_read(0x125, &val); + } + val=((val&0x7000)>>12);//result ,status5[14:12] + mMACENTRY->result=val; + + if (!val) { + printk(" Command OK!! \n"); + if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) { + ifx_sw_read(0x120,&(status[0])); + ifx_sw_read(0x121,&(status[1])); + ifx_sw_read(0x122,&(status[2])); + ifx_sw_read(0x123,&(status[3])); + ifx_sw_read(0x124,&(status[4])); + ifx_sw_read(0x125,&(status[5])); + + + mMACENTRY->mac_addr[0]=(status[0]&0x00ff) ; + mMACENTRY->mac_addr[1]=(status[0]&0xff00)>>8 ; + mMACENTRY->mac_addr[2]=(status[1]&0x00ff) ; + mMACENTRY->mac_addr[3]=(status[1]&0xff00)>>8 ; + mMACENTRY->mac_addr[4]=(status[2]&0x00ff) ; + mMACENTRY->mac_addr[5]=(status[2]&0xff00)>>8 ; + mMACENTRY->fid=(status[3]&0xf); + mMACENTRY->portmap=((status[3]>>4)&0x3f); + if (status[5]&0x2) {//static info_ctrl //status5[1]???? + mMACENTRY->ctrl.info_ctrl=(status[4]&0x00ff); + mMACENTRY->info_type=1; + } + else {//not static age_timer + mMACENTRY->ctrl.age_timer=(status[4]&0x00ff); + mMACENTRY->info_type=0; + } +//status5[13]???? mMACENTRY->occupy=(status[5]&0x02)>>1;//status5[1] + mMACENTRY->occupy=(status[5]&0x02000)>>13;//status5[13] ??? + mMACENTRY->bad=(status[5]&0x04)>>2;//status5[2] + }//if ((cmd==ADM_SW_IOCTL_MACENTRY_GET_INIT)||(cmd==ADM_SW_IOCTL_MACENTRY_GET_MORE)) + + } + else if (val==0x001) + printk(" All Entry Used!! \n"); + else if (val==0x002) + printk(" Entry Not Found!! \n"); + else if (val==0x003) + printk(" Try Next Entry!! \n"); + else if (val==0x005) + printk(" Command Error!! \n"); + else + printk(" UnKnown Error!! \n"); + + // printk ("adm_process_mac_table_request: Exit\n"); + return 0; +} + +/* Santosh: End of function for MAC ENTRY ADD/DEL*/ +struct file_operations adm_ops = +{ + read: adm_read, + write: adm_write, + open: adm_open, + release: adm_release, + ioctl: adm_ioctl +}; + +int adm_proc(char *buf, char **start, off_t offset, int count, int *eof, void *data) +{ + int len = 0; + + len += sprintf(buf+len, " ************ Registers ************ \n"); + *eof = 1; + return len; +} + +int __init init_adm6996_module(void) +{ + unsigned int val = 000; + unsigned int val1 = 000; + + printk("Loading ADM6996 driver... \n"); + + /* if running on adm5120 */ + /* set GPIO 0~2 as adm6996 control pins */ + //outl(0x003f3f00, 0x12000028); + /* enable switch port 5 (MII) as RMII mode (5120MAC <-> 6996MAC) */ + //outl(0x18a, 0x12000030); + /* group adm5120 port 1 ~ 5 as VLAN0, port 5 & 6(CPU) as VLAN1 */ + //outl(0x417e, 0x12000040); + /* end adm5120 fixup */ +#ifdef ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin + register_chrdev(69, "adm6996", &adm_ops); + AMAZON_SW_REG(AMAZON_SW_MDIO_CFG) = 0x27be; + AMAZON_SW_REG(AMAZON_SW_EPHY) = 0xfc; + adm6996_mode=adm6996i; + ifx_sw_read(0xa0, &val); + ifx_sw_read(0xa1, &val1); + val=((val1&0x0f)<<16)|val; + printk ("\nADM6996 SMI Mode-"); + printk ("Chip ID:%5x \n ", val); +#else //000001.joelin + + AMAZON_SW_REG(AMAZON_SW_MDIO_CFG) = 0x2c50; + AMAZON_SW_REG(AMAZON_SW_EPHY) = 0xff; + + AMAZON_SW_REG(AMAZON_GPIO_P1_ALTSEL0) &= ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC); + AMAZON_SW_REG(AMAZON_GPIO_P1_ALTSEL1) &= ~(GPIO_MDIO|GPIO_MDCS|GPIO_MDC); + AMAZON_SW_REG(AMAZON_GPIO_P1_OD) |= (GPIO_MDIO|GPIO_MDCS|GPIO_MDC); + + ifx_gpio_init(); + register_chrdev(69, "adm6996", &adm_ops); + mdelay(100); + + /* create proc entries */ + // create_proc_read_entry("admide", 0, NULL, admide_proc, NULL); + +//joelin adm6996i support start + adm6996_mode=adm6996i; + ifx_sw_read(0xa0, &val); + adm6996_mode=adm6996l; + ifx_sw_read(0x200, &val1); +// printk ("\n %0x \n",val1); + if ((val&0xfff0)==0x1020) { + printk ("\n ADM6996I .. \n"); + adm6996_mode=adm6996i; + } + else if ((val1&0xffffff00)==0x71000) {//71010 or 71020 + printk ("\n ADM6996LC .. \n"); + adm6996_mode=adm6996lc; + } + else { + printk ("\n ADM6996L .. \n"); + adm6996_mode=adm6996l; + } +#endif //ADM6996_MDC_MDIO_MODE //smi mode //000001.joelin + + if ((adm6996_mode==adm6996lc)||(adm6996_mode==adm6996i)){ +#if 0 /* removed by MarsLin */ + ifx_sw_write(0x29,0xc000); + ifx_sw_write(0x30,0x0985); +#else + ifx_sw_read(0xa0, &val); + if (val == 0x1021) // for both 6996LC and 6996I, only AB version need the patch + ifx_sw_write(0x29, 0x9000); + ifx_sw_write(0x30,0x0985); +#endif + } +//joelin adm6996i support end + return 0; +} + +void __exit cleanup_adm6996_module(void) +{ + printk("Free ADM device driver... \n"); + + unregister_chrdev(69, "adm6996"); + + /* remove proc entries */ + // remove_proc_entry("admide", NULL); +} + +/* MarsLin, add start */ +#if defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT) || defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT_MODULE) + #define SET_BIT(reg, mask) reg |= (mask) + #define CLEAR_BIT(reg, mask) reg &= (~mask) + static int ifx_hw_reset(void) + { + CLEAR_BIT((*AMAZON_GPIO_P0_ALTSEL0),0x2000); + CLEAR_BIT((*AMAZON_GPIO_P0_ALTSEL1),0x2000); + SET_BIT((*AMAZON_GPIO_P0_OD),0x2000); + SET_BIT((*AMAZON_GPIO_P0_DIR), 0x2000); + CLEAR_BIT((*AMAZON_GPIO_P0_OUT), 0x2000); + mdelay(500); + SET_BIT((*AMAZON_GPIO_P0_OUT), 0x2000); + cleanup_adm6996_module(); + return init_adm6996_module(); + } + int (*adm6996_hw_reset)(void) = ifx_hw_reset; + EXPORT_SYMBOL(adm6996_hw_reset); + EXPORT_SYMBOL(adm6996_mode); + int (*adm6996_sw_read)(unsigned int addr, unsigned int *data) = ifx_sw_read; + EXPORT_SYMBOL(adm6996_sw_read); + int (*adm6996_sw_write)(unsigned int addr, unsigned int data) = ifx_sw_write; + EXPORT_SYMBOL(adm6996_sw_write); +#endif +/* MarsLin, add end */ + +/* Santosh: for IGMP proxy/snooping, Begin */ +EXPORT_SYMBOL (adm_process_mac_table_request); +EXPORT_SYMBOL (adm_process_protocol_filter_request); +/* Santosh: for IGMP proxy/snooping, End */ + +MODULE_DESCRIPTION("ADMtek 6996 Driver"); +MODULE_AUTHOR("Joe Lin <joe.lin@infineon.com>"); +MODULE_LICENSE("GPL"); + +module_init(init_adm6996_module); +module_exit(cleanup_adm6996_module); + diff --git a/target/linux/amazon/files/drivers/char/amazon_mei.c b/target/linux/amazon/files/drivers/char/amazon_mei.c new file mode 100644 index 0000000000..7efe52ed60 --- /dev/null +++ b/target/linux/amazon/files/drivers/char/amazon_mei.c @@ -0,0 +1,7918 @@ +/* ============================================================================ + * Copyright (C) 2004 -Infineon Technologies AG. + * + * All rights reserved. + * ============================================================================ + * + *============================================================================ + * Licensed under GNU GPL v2 + * ============================================================================ + */ + + +/* =========================================================================== + * + * File Name: amazon_mei.c + * Author : Ou Ke + * + * =========================================================================== + * + * Project: Amazon + * + * =========================================================================== + * Contents:This file implements the MEI driver for Amazon ADSL/ADSL2+ + * controller. + * + * =========================================================================== + * References: + * + */ + + +/* =========================================================================== + * Revision History: + * 12/1/2005 : Ritesh Banerjee + * - Create a kernel thread kmibpoll to poll for periodic RFC 2662 + * and RFC 3440 counters. Removes the need for user space + * adsl_mibpoll_daemon and saves atleast 30KB of RAM. + * + * $Log$ + * =========================================================================== + */ + +/* + * =========================================================================== + * INCLUDE FILES + * =========================================================================== + */ +//000002:fchang 2005/6/2 joelin 04/27/2005 for pcm clock +//000003:fchang 2005/6/2 Henry added for Amazon-E support +//165001:henryhsu 2005/9/6 Modify for adsl firmware version 1.2.1.2.0.1 DATA_LED can't flash. +// 509221:tc.chen 2005/09/22 Reset DFE added when MEI_TO_ARC_CS_DONE not cleared by ARC +// 603221:tc.chen 2006/03/21 added APIs to support the WEB related parameters for ADSL Statistics + +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif +#define AMAZON_MEI_MIB_RFC3440 + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/version.h> +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/errno.h> +#include <linux/interrupt.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <asm/irq.h> +#include <asm/segment.h> +#include <asm/semaphore.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <asm/uaccess.h> +#include <linux/proc_fs.h> +#include <asm/io.h> +#include <linux/vmalloc.h> +#include <linux/delay.h> +#include <linux/poll.h> +#include <linux/list.h> +#include <linux/time.h> + +#include <asm/amazon/amazon.h> +#include <asm/irq.h> +#include <asm/amazon/irq.h> +#include <asm/amazon/amazon_mei.h> +#include <asm/amazon/amazon_mei_app.h> +#include <asm/amazon/amazon_mei_ioctl.h> +#include <asm/amazon/amazon_mei_app_ioctl.h> + +#define SET_BIT(reg, mask) reg |= (mask) +#define CLEAR_BIT(reg, mask) reg &= (~mask) +#define CLEAR_BITS(reg, mask) CLEAR_BIT(reg, mask) +#define SET_BITS(reg, mask) SET_BIT(reg, mask) +#define SET_BITFIELD(reg, mask, off, val) {reg &= (~mask); reg |= (val << off);} + +extern void mask_and_ack_amazon_irq(unsigned int irq_nr); + +#ifdef AMAZON_CHECK_LINK +//amazon_tpe.c +extern int (*adsl_link_notify)(int); +#endif //AMAZON_CHECK_LINK + +// for ARC memory access +#define WHILE_DELAY 20000 +#define AMAZON_DMA_DEBUG_MUTEX + + +//TODO +#undef DFE_LOOPBACK +#define ARC_READY_ACK + +static amazon_mei_mib * current_intvl; +static struct list_head interval_list; +static amazon_mei_mib * mei_mib; + +static int reboot_firsttime=1;//000002:fchang + + //PCM +#define PCM_CHANNEL_NUM 2 //1 rx, 1 tx +static pcm_data_struct pcm_data[PCM_CHANNEL_NUM]__attribute__ ((aligned(4))); //0=tx0, 1=rx0, 2=tx1, 3=rx1 +static u32 pcm_start_addr; +//#define PCM_HRT_TIME_HZ 4000 //?us +#define PCM_ACCESS_DEBUG +static int irqtimes=0; +#undef DATA_LED_ON_MODE +#define ADSL_LED_SUPPORT //joelin for adsl led +#ifdef ADSL_LED_SUPPORT +static int firmware_support_led=0; //joelin version check for adsl led +static int stop_led_module=0; //wakeup and clean led module +static int led_support_check=0; //1.1.2.7.1.1 +#endif //ADSL_LED_SUPPORT +#define IFX_DYING_GASP +#ifdef IFX_DYING_GASP +static wait_queue_head_t wait_queue_dying_gasp; //dying gasp +//struct tq_struct dying_gasp_task; //dying gasp +static wait_queue_head_t wait_queue_uas_poll; //joelin 04/16/2005 +static u16 unavailable_seconds=0; //joelin 04/16/2005 +static meidebug lop_debugwr; //dying gasp +#endif //IFX_DYING_GASP +static int dbg_int=0; +//#define DEBUG_ACCESS_DELAY for(dbg_int=0;dbg_int<100;dbg_int++){;} +#define DEBUG_ACCESS_DELAY +static u8 sampledata[512]; +static int firsttime[PCM_CHANNEL_NUM]={0,1}; +static int num_cmp[PCM_CHANNEL_NUM]={0,0}; +static int pcm_start_loc[PCM_CHANNEL_NUM]={0,0}; + + // for clearEoC +//#define MEI_CLREOC_BUFF_SIZE 512 //double the receive fifo size, bytes +//static u8 clreoc[MEI_CLREOC_BUFF_SIZE]__attribute__ ((aligned(4))); //buffer to hold clearEoC data in bytes +#undef AMAZON_CLEAR_EOC +#ifdef AMAZON_CLEAR_EOC +extern void ifx_push_eoc(struct sk_buff * pkt); +#endif +static int meiResetArc(void); +#define IFX_POP_EOC_DONE 0 +#define IFX_POP_EOC_FAIL -1 +static struct list_head clreoc_list; +static amazon_clreoc_pkt * clreoc_pkt; +#define CLREOC_BUFF_SIZE 12 //number of clreoc commands being buffered +//static int clreoc_wr=0; +//static int clreoc_rd=0; //used to control clreoc circular buffer +static wait_queue_head_t wait_queue_clreoc; +#ifdef ADSL_LED_SUPPORT +static wait_queue_head_t wait_queue_led; //adsl led +static wait_queue_head_t wait_queue_led_polling;// adsl led +struct tq_struct led_task; // adsl led +static DECLARE_TASK_QUEUE(tq_ifx_led); // task +int adsl_led_flash_task(void *ptr); // adsl led +#endif //ADSL_LED_SUPPORT +static void * clreoc_command_pkt=NULL; +static int clreoc_max_tx_len=0; + +// 603221:tc.chen start +#define ME_HDLC_IDLE 0 +#define ME_HDLC_INVALID_MSG 1 +#define ME_HDLC_MSG_QUEUED 2 +#define ME_HDLC_MSG_SENT 3 +#define ME_HDLC_RESP_RCVD 4 +#define ME_HDLC_RESP_TIMEOUT 5 +#define ME_HDLC_RX_BUF_OVERFLOW 6 +#define ME_HDLC_UNRESOLVED 1 +#define ME_HDLC_RESOLVED 2 +// 603221:tc.chen end + +#ifdef LOCK_RETRY +static int reboot_lock=0; +#endif + +static mib_previous_read mib_pread={0,0,0,0,0,0,0,0,0,0,0,0}; +static mib_flags_pretime mib_pflagtime;// initialized when module loaded + + static u32 ATUC_PERF_LOFS=0; + static u32 ATUC_PERF_LOSS=0; + static u32 ATUC_PERF_ESS=0; + static u32 ATUC_PERF_INITS=0; + static u32 ATUR_PERF_LOFS=0; + static u32 ATUR_PERF_LOSS=0; + static u32 ATUR_PERF_LPR=0; + static u32 ATUR_PERF_ESS=0; + static u32 ATUR_CHAN_RECV_BLK=0; + static u32 ATUR_CHAN_TX_BLK=0; + static u32 ATUR_CHAN_CORR_BLK=0; + static u32 ATUR_CHAN_UNCORR_BLK=0; + //RFC-3440 + static u32 ATUC_PERF_STAT_FASTR=0; + static u32 ATUC_PERF_STAT_FAILED_FASTR=0; + static u32 ATUC_PERF_STAT_SESL=0; + static u32 ATUC_PERF_STAT_UASL=0; + static u32 ATUR_PERF_STAT_SESL=0; + static u32 ATUR_PERF_STAT_UASL=0; + + static adslChanPrevTxRate PrevTxRate={0,0}; + static adslPhysCurrStatus CurrStatus={0,0}; + static ChanType chantype={0,0}; + static adslLineAlarmConfProfileEntry AlarmConfProfile={"No Name\0",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; +// 603221:tc.chen start + static adslFarEndPerfStats FarendStatsData; + struct timeval FarendData_acquire_time={0}; + static u32 adsl_mode,adsl_mode_extend; // adsl mode : adsl/ 2/ 2+ + static adslInitStats AdslInitStatsData; +//603221:tc.chen end +static u32 loop_diagnostics_mode=0; +static wait_queue_head_t wait_queue_loop_diagnostic; +#ifdef AMAZON_MEI_MIB_RFC3440 + static adslLineAlarmConfProfileExtEntry AlarmConfProfileExt={"No Name\0",0,0,0,0,0,0}; +#endif + +static int showtime=0; +static int loop_diagnostics_completed=0; +////////////////////////////////////////////////////////////////////////////////// +static int phy_mei_net_init(struct net_device * dev); +static int interleave_mei_net_init(struct net_device * dev); +static int fast_mei_net_init(struct net_device * dev); +static struct net_device_stats * phy_mei_net_get_stats(struct net_device * dev); +static struct net_device_stats * interleave_mei_net_get_stats(struct net_device * dev); +static struct net_device_stats * fast_mei_net_get_stats(struct net_device * dev); + +typedef struct mei_priv{ + struct net_device_stats stats; +}mei_priv; + +static struct net_device phy_mei_net = { init: phy_mei_net_init, name: "MEI_PHY"}; +static struct net_device interleave_mei_net = { init: interleave_mei_net_init, name: "MEI_INTL"}; +static struct net_device fast_mei_net = { init: fast_mei_net_init, name: "MEI_FAST"}; +/////////////////////////////////////////////////////////////////////////////////// + +static int major=AMAZON_MEI_MAJOR; + +static struct semaphore mei_sema; + +// Mei to ARC CMV count, reply count, ARC Indicator count +static int indicator_count=0; +static int cmv_count=0; +static int reply_count=0; +static u16 Recent_indicator[MSG_LENGTH]; + +// Used in interrupt handler as flags +static int arcmsgav=0; +static int cmv_reply=0; +static int cmv_waiting=0; + +#define PROC_ITEMS 8 + +long mei_debug_mode = 0; //509221:tc.chen for adsl firmware debug + +// to wait for arc cmv reply, sleep on wait_queue_arcmsgav; +static wait_queue_head_t wait_queue_arcmsgav; +static wait_queue_head_t wait_queue_codeswap; +static wait_queue_head_t wait_queue_mibdaemon; +static wait_queue_head_t wait_queue_reboot; +static u32 * image_buffer=NULL; // holding adsl firmware image +static u16 RxMessage[MSG_LENGTH]__attribute__ ((aligned(4))); +static u16 TxMessage[MSG_LENGTH]__attribute__ ((aligned(4))); +static u32 * mei_arc_swap_buff=NULL; // holding swap pages +static ARC_IMG_HDR * img_hdr; +static int reboot_flag; + +#ifdef DFE_LOOPBACK +#include "arc_pm.h" +#endif + + +///////////////// net device /////////////////////////////////////////////////// +static int phy_mei_net_init(struct net_device * dev) +{ + //ether_setup(dev); + dev->get_stats = phy_mei_net_get_stats; + dev->ip_ptr = NULL; + dev->type = 94; + +// dev->mtu=12345; + dev->flags=IFF_UP; + + dev->priv = kmalloc(sizeof(struct mei_priv), GFP_KERNEL); + if(dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct mei_priv)); + return 0; +} + +static int interleave_mei_net_init(struct net_device * dev) +{ + //ether_setup(dev); + dev->get_stats = interleave_mei_net_get_stats; + dev->ip_ptr = NULL; + dev->type = 124; + dev->flags=IFF_UP; + dev->priv = kmalloc(sizeof(struct mei_priv), GFP_KERNEL); + if(dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct mei_priv)); + return 0; +} + +static int fast_mei_net_init(struct net_device * dev) +{ + //ether_setup(dev); + dev->get_stats = fast_mei_net_get_stats; + dev->ip_ptr = NULL; + dev->type = 125; + dev->flags=IFF_UP; + dev->priv = kmalloc(sizeof(struct mei_priv), GFP_KERNEL); + if(dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct mei_priv)); + return 0; +} + +static struct net_device_stats * phy_mei_net_get_stats(struct net_device * dev) +{ + struct mei_priv * priv; + priv = (struct mei_priv *)dev->priv; + // update statistics + (priv->stats).rx_packets = ATUR_CHAN_RECV_BLK; + (priv->stats).tx_packets = ATUR_CHAN_TX_BLK; + (priv->stats).rx_errors = ATUR_CHAN_CORR_BLK + ATUR_CHAN_UNCORR_BLK; + (priv->stats).rx_dropped = ATUR_CHAN_UNCORR_BLK; + + return &(priv->stats); +} + +static struct net_device_stats * interleave_mei_net_get_stats(struct net_device * dev) +{ + struct mei_priv * priv; + priv = (struct mei_priv *)dev->priv; + // update statistics + (priv->stats).rx_packets = ATUR_CHAN_RECV_BLK; + (priv->stats).tx_packets = ATUR_CHAN_TX_BLK; + (priv->stats).rx_errors = ATUR_CHAN_CORR_BLK + ATUR_CHAN_UNCORR_BLK; + (priv->stats).rx_dropped = ATUR_CHAN_UNCORR_BLK; + + return &(priv->stats); +} + +static struct net_device_stats * fast_mei_net_get_stats(struct net_device * dev) +{ + struct mei_priv * priv; + priv = (struct mei_priv *)dev->priv; + // update statistics + (priv->stats).rx_packets = ATUR_CHAN_RECV_BLK; + (priv->stats).tx_packets = ATUR_CHAN_TX_BLK; + (priv->stats).rx_errors = ATUR_CHAN_CORR_BLK + ATUR_CHAN_UNCORR_BLK; + (priv->stats).rx_dropped = ATUR_CHAN_UNCORR_BLK; + + return &(priv->stats); +} +///////////////// mei access Rd/Wr methods /////////////////////////////////////////////////// +void meiLongwordWrite(u32 ul_address, u32 ul_data) +{ + *((volatile u32 *)ul_address) = ul_data; + asm("SYNC"); + return; +} // end of "meiLongwordWrite(..." + +void meiLongwordRead(u32 ul_address, u32 *pul_data) +{ + *pul_data = *((volatile u32 *)ul_address); + asm("SYNC"); + return; +} // end of "meiLongwordRead(..." + +MEI_ERROR meiDMAWrite(u32 destaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( destaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the write transfer address + meiLongwordWrite(MEI_XFR_ADDR, destaddr); + + // Write the data pushed across DMA + while (databuffsize--) + { + temp = *p; + if(databuff==(u32 *)TxMessage) // swap half word + temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16); + meiLongwordWrite(MEI_DATA_XFR, temp); + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMAWrite(..." + +MEI_ERROR meiDMAWrite_16(u32 destaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( destaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the write transfer address + meiLongwordWrite(MEI_XFR_ADDR, destaddr); + + // Write the data pushed across DMA + while (databuffsize--) + { + temp = *p; + temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16);//swap half word + meiLongwordWrite(MEI_DATA_XFR, temp); + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMAWrite_16(..." + +MEI_ERROR meiDMAWrite_8(u32 destaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( destaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the write transfer address + meiLongwordWrite(MEI_XFR_ADDR, destaddr); + + // Write the data pushed across DMA + while (databuffsize--) + { + temp = *p; + temp = ((temp & 0xff)<<24) + ((temp & 0xff00)<<8)+ ((temp & 0xff0000)>>8)+ ((temp & 0xff000000)>>24);//swap byte + meiLongwordWrite(MEI_DATA_XFR, temp); + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMAWrite_8(..." + +MEI_ERROR meiDMARead(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( srcaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the read transfer address + meiLongwordWrite(MEI_XFR_ADDR, srcaddr); + + // Read the data popped across DMA + while (databuffsize--) + { + meiLongwordRead(MEI_DATA_XFR, &temp); + if(databuff==(u32 *)RxMessage) // swap half word + temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16); + *p=temp; + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMARead(..." + +MEI_ERROR meiDMARead_16(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( srcaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the read transfer address + meiLongwordWrite(MEI_XFR_ADDR, srcaddr); + + // Read the data popped across DMA + while (databuffsize--) + { + meiLongwordRead(MEI_DATA_XFR, &temp); + temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16); + *p=temp; + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMARead_16(..." + +MEI_ERROR meiDMARead_8(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 *p = databuff; + u32 temp; + u32 flags; + + if( srcaddr & 3) + return MEI_FAILURE; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Set the read transfer address + meiLongwordWrite(MEI_XFR_ADDR, srcaddr); + + // Read the data popped across DMA + while (databuffsize--) + { + meiLongwordRead(MEI_DATA_XFR, &temp); + temp = ((temp & 0xff)<<24) + ((temp & 0xff00)<<8)+ ((temp & 0xff0000)>>8)+ ((temp & 0xff000000)>>24);//swap byte + *p=temp; + p++; + } // end of "while(..." + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + return MEI_SUCCESS; + +} // end of "meiDMARead_8(..." + +void meiPollForDbgDone(void) +{ + u32 query = 0; + int i=0; + while (i<WHILE_DELAY) + { + meiLongwordRead(ARC_TO_MEI_INT, &query); + query &= (ARC_TO_MEI_DBG_DONE); + if(query) + break; + i++; + if(i==WHILE_DELAY){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n PollforDbg fail"); +#endif + } + DEBUG_ACCESS_DELAY; + } + meiLongwordWrite(ARC_TO_MEI_INT, ARC_TO_MEI_DBG_DONE); // to clear this interrupt +} // end of "meiPollForDbgDone(..." + +MEI_ERROR meiDebugWrite_8(u32 destaddr, u32 *databuff, u32 databuffsize) +{ + u32 i; + u32 temp = 0x0; + u32 address = 0x0; + u32 *buffer = 0x0; + u32 flags; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Open the debug port before DMP memory write + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK); + DEBUG_ACCESS_DELAY; + + // For the requested length, write the address and write the data + address = destaddr; + buffer = databuff; + for (i=0; i < databuffsize; i++) + { + meiLongwordWrite(MEI_DEBUG_WAD, address); + DEBUG_ACCESS_DELAY; + temp=*buffer; + temp = ((temp & 0xff)<<24) + ((temp & 0xff00)<<8)+ ((temp & 0xff0000)>>8)+ ((temp & 0xff000000)>>24);//swap byte + meiLongwordWrite(MEI_DEBUG_DATA, temp); + DEBUG_ACCESS_DELAY; + meiPollForDbgDone(); + address += 4; + buffer++; + } // end of "for(..." + + // Close the debug port after DMP memory write + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + // Return + return MEI_SUCCESS; + +} // end of "meiDebugWrite_8(..." + +MEI_ERROR meiDebugRead_8(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 i; + u32 temp = 0x0; + u32 address = 0x0; + u32 *buffer = 0x0; + u32 flags; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Open the debug port before DMP memory read + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP2_MASK); + DEBUG_ACCESS_DELAY; + + // For the requested length, write the address and read the data + address = srcaddr; + buffer = databuff; + for (i=0; i<databuffsize; i++) + { + meiLongwordWrite(MEI_DEBUG_RAD, address); + DEBUG_ACCESS_DELAY; + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &temp); + DEBUG_ACCESS_DELAY; + temp = ((temp & 0xff)<<24) + ((temp & 0xff00)<<8)+ ((temp & 0xff0000)>>8)+ ((temp & 0xff000000)>>24);//swap byte + *buffer=temp; + address += 4; + buffer++; + } // end of "for(..." + + // Close the debug port after DMP memory read + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + // Return + return MEI_SUCCESS; + +} // end of "meiDebugRead_8(..." + +MEI_ERROR meiDebugWrite_16(u32 destaddr, u32 *databuff, u32 databuffsize) +{ + u32 i; + u32 temp = 0x0; + u32 address = 0x0; + u32 *buffer = 0x0; + u32 flags; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Open the debug port before DMP memory write + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK); + DEBUG_ACCESS_DELAY; + + // For the requested length, write the address and write the data + address = destaddr; + buffer = databuff; + for (i=0; i < databuffsize; i++) + { + meiLongwordWrite(MEI_DEBUG_WAD, address); + DEBUG_ACCESS_DELAY; + temp=*buffer; + temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16);//swap half word + meiLongwordWrite(MEI_DEBUG_DATA, temp); + DEBUG_ACCESS_DELAY; + meiPollForDbgDone(); + address += 4; + buffer++; + } // end of "for(..." + + // Close the debug port after DMP memory write + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + // Return + return MEI_SUCCESS; + +} // end of "meiDebugWrite_16(..." + +MEI_ERROR meiDebugRead_16(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 i; + u32 temp = 0x0; + u32 address = 0x0; + u32 *buffer = 0x0; + u32 flags; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Open the debug port before DMP memory read + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP2_MASK); + DEBUG_ACCESS_DELAY; + + // For the requested length, write the address and read the data + address = srcaddr; + buffer = databuff; + for (i=0; i<databuffsize; i++) + { + meiLongwordWrite(MEI_DEBUG_RAD, address); + DEBUG_ACCESS_DELAY; + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &temp); + DEBUG_ACCESS_DELAY; + temp = ((temp & 0xffff)<<16) + ((temp & 0xffff0000)>>16);//swap half word + *buffer=temp; + address += 4; + buffer++; + } // end of "for(..." + + // Close the debug port after DMP memory read + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + // Return + return MEI_SUCCESS; + +} // end of "meiDebugRead_16(..." + +MEI_ERROR meiDebugWrite(u32 destaddr, u32 *databuff, u32 databuffsize) +{ + u32 i; + u32 temp = 0x0; + u32 address = 0x0; + u32 *buffer = 0x0; + u32 flags; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Open the debug port before DMP memory write + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK); + DEBUG_ACCESS_DELAY; + + // For the requested length, write the address and write the data + address = destaddr; + buffer = databuff; + for (i=0; i < databuffsize; i++) + { + meiLongwordWrite(MEI_DEBUG_WAD, address); + DEBUG_ACCESS_DELAY; + temp=*buffer; + meiLongwordWrite(MEI_DEBUG_DATA, temp); + DEBUG_ACCESS_DELAY; + meiPollForDbgDone(); + address += 4; + buffer++; + } // end of "for(..." + + // Close the debug port after DMP memory write + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + // Return + return MEI_SUCCESS; + +} // end of "meiDebugWrite(..." + +MEI_ERROR meiDebugRead(u32 srcaddr, u32 *databuff, u32 databuffsize) +{ + u32 i; + u32 temp = 0x0; + u32 address = 0x0; + u32 *buffer = 0x0; + u32 flags; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + save_flags(flags); + cli(); +#endif + + + // Open the debug port before DMP memory read + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP2_MASK); + DEBUG_ACCESS_DELAY; + + // For the requested length, write the address and read the data + address = srcaddr; + buffer = databuff; + for (i=0; i<databuffsize; i++) + { + meiLongwordWrite(MEI_DEBUG_RAD, address); + DEBUG_ACCESS_DELAY; + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &temp); + DEBUG_ACCESS_DELAY; + *buffer=temp; + address += 4; + buffer++; + } // end of "for(..." + + // Close the debug port after DMP memory read + meiLongwordRead(MEI_CONTROL, &temp); + DEBUG_ACCESS_DELAY; + temp &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, temp); + DEBUG_ACCESS_DELAY; + +#ifdef AMAZON_DMA_DEBUG_MUTEX + restore_flags(flags); +#endif + + // Return + return MEI_SUCCESS; + +} // end of "meiDebugRead(..." +EXPORT_SYMBOL(meiDebugRead); + +void meiMailboxInterruptsDisable(void) +{ + meiLongwordWrite(ARC_TO_MEI_INT_MASK, 0x0); +} // end of "meiMailboxInterruptsDisable(..." + +void meiMailboxInterruptsEnable(void) +{ + meiLongwordWrite(ARC_TO_MEI_INT_MASK, MSGAV_EN); +} // end of "meiMailboxInterruptsEnable(..." + +MEI_ERROR meiMailboxWrite(u16 *msgsrcbuffer, u16 msgsize) +{ + int i; + u32 arc_mailbox_status = 0x0; + u32 temp=0; + MEI_ERROR meiMailboxError = MEI_SUCCESS; + + // Check arc if mailbox write can be initiated +/* meiLongwordRead(MEI_TO_ARC_INT, &arc_mailbox_status); + if ((arc_mailbox_status & MEI_TO_ARC_MSGAV)) + { + return MEI_MAILBOX_FULL; + } +*/ + // Write to mailbox + meiMailboxError = meiDMAWrite(MEI_TO_ARC_MAILBOX, (u32*)msgsrcbuffer, msgsize/2); + meiMailboxError = meiDMAWrite(MEI_TO_ARC_MAILBOXR, (u32 *)(&temp), 1); + + // Notify arc that mailbox write completed + cmv_waiting=1; + meiLongwordWrite(MEI_TO_ARC_INT, MEI_TO_ARC_MSGAV); + + i=0; + while(i<WHILE_DELAY){ // wait for ARC to clear the bit + meiLongwordRead(MEI_TO_ARC_INT, &arc_mailbox_status); + if((arc_mailbox_status & MEI_TO_ARC_MSGAV) != MEI_TO_ARC_MSGAV) + break; + i++; + if(i==WHILE_DELAY){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n MEI_TO_ARC_MSGAV not cleared by ARC"); +#endif + meiMailboxError = MEI_FAILURE; +#if 0 + for(i=0;i<msgsize;i++) + printk("\n %8x", (*(msgsrcbuffer+i))); +#endif + } + } + + // Return + return meiMailboxError; + +} // end of "meiMailboxWrite(..." + +MEI_ERROR meiMailboxRead(u16 *msgdestbuffer, u16 msgsize) +{ + //u32 arc_mailbox_status = 0x0; + //u32 *mei_arc_msgbuff = 0x0; + MEI_ERROR meiMailboxError = MEI_SUCCESS; + + /* + // Check arc if mailbox read can be initiated + meiLongwordRead(ARC_TO_MEI_INT, &arc_mailbox_status); + if ((arc_mailbox_status & ARC_TO_MEI_MSGAV) == 0) + { + return MEI_MAILBOX_EMPTY; + } // end of "if(..." + */ + + // Read from mailbox + meiMailboxError = meiDMARead(ARC_TO_MEI_MAILBOX, (u32*)msgdestbuffer, msgsize/2); + + // Notify arc that mailbox read completed + meiLongwordWrite(ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV); + + // Return + return meiMailboxError; + +} // end of "meiMailboxRead(..." + +MEI_ERROR meiHaltArc(void) +{ + u32 arc_control_mode = 0x0; + u32 arc_debug_addr = 0x5; + u32 arc_debug_data = 0x0; + + // Switch arc control from JTAG mode to MEI mode- write '1' to bit0 + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + + // Write arc aux reg access mask (0x0) into debug addr decode reg + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_AUX_MASK); + + // Write arc debug reg addr (0x5) into debug read addr reg + meiLongwordWrite(MEI_DEBUG_RAD, arc_debug_addr); + meiPollForDbgDone(); + + // Read debug data reg and save content + meiLongwordRead(MEI_DEBUG_DATA, &arc_debug_data); + + // Write arc debug reg addr (0x5) into debug write addr reg + meiLongwordWrite(MEI_DEBUG_WAD, arc_debug_addr); + + // Write debug data reg with content ORd with 0x2 (halt bit set) + arc_debug_data |= (BIT1); + meiLongwordWrite(MEI_DEBUG_DATA, arc_debug_data); + meiPollForDbgDone(); + + // Switch arc control from MEI mode to JTAG mode- write '0' to bit0 + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + + // Return + return MEI_SUCCESS; + +} // end of "meiHalt(..." + +MEI_ERROR meiDownloadBootCode(void) +{ + u32 arc_control_mode; + u32 boot_loop; + u32 page_size; + u32 dest_addr; + + u32 arc_debug_addr = 0x31F00; + u32 arc_debug_data = 0x10; + u32 temp; +// int i; + + //MEI_ERROR meiDMAError = MEI_SUCCESS; + + // Disable mask for arc codeswap interrupts + meiMailboxInterruptsDisable(); + + // Switch arc control from JTAG mode to MEI mode- write '1' to bit0 + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + + // Write (0x10) to CRI_CCR0(0x31F00) to enable ac_clk signal + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK); + meiLongwordWrite(MEI_DEBUG_RAD, arc_debug_addr); + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &temp); + temp |=arc_debug_data; + + meiLongwordWrite(MEI_DEBUG_WAD, arc_debug_addr); + meiLongwordWrite(MEI_DEBUG_DATA, temp); + meiPollForDbgDone(); + //meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_AUX_MASK); + + // Switch arc control from MEI mode to JTAG mode- write '0' to bit0 + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + +#ifdef AMAZON_MEI_DEBUG_ON //to test ac_clk setting correctness + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK); + meiLongwordWrite(MEI_DEBUG_RAD, arc_debug_addr); + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &arc_debug_data); + + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + +// printk("\n\n ac_clk is %8x\n", arc_debug_data); +#endif + + /* + ** DMA the boot code page(s) + */ +#ifdef AMAZON_MEI_DEBUG_ON +// printk("\n\n start download pages"); +#endif + for( boot_loop = 0; boot_loop < img_hdr->count; boot_loop++) + { + if( img_hdr->page[boot_loop].p_size & BOOT_FLAG) + { + page_size = meiGetPage( boot_loop, GET_PROG, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( page_size > 0) + { + meiDMAWrite(dest_addr, mei_arc_swap_buff, page_size); + } + } + if( img_hdr->page[boot_loop].d_size & BOOT_FLAG) + { + page_size = meiGetPage( boot_loop, GET_DATA, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( page_size > 0) + { + meiDMAWrite( dest_addr, mei_arc_swap_buff, page_size); + } + } + } +#ifdef AMAZON_MEI_DEBUG_ON +// printk("\n\n pages downloaded"); +#endif + return MEI_SUCCESS; + +} // end of "meiDownloadBootCode(..." + +MEI_ERROR meiRunArc(void) +{ + u32 arc_control_mode = 0x0; + u32 arc_debug_addr = 0x0; + u32 arc_debug_data = 0x0; + + // Switch arc control from JTAG mode to MEI mode- write '1' to bit0 + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + + // Write arc aux reg access mask (0x0) into debug addr decode reg + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_AUX_MASK); + + // Write arc status aux reg addr (0x0) into debug read addr reg + meiLongwordWrite(MEI_DEBUG_RAD, arc_debug_addr); + meiPollForDbgDone(); + + // Read debug data reg and save content + meiLongwordRead(MEI_DEBUG_DATA, &arc_debug_data); + + // Write arc status aux reg addr (0x0) into debug write addr reg + meiLongwordWrite(MEI_DEBUG_WAD, arc_debug_addr); + + // Write debug data reg with content ANDd with 0xFDFFFFFF (halt bit cleared) + arc_debug_data &= ~(BIT25); + meiLongwordWrite(MEI_DEBUG_DATA, arc_debug_data); + meiPollForDbgDone(); + + // Switch arc control from MEI mode to JTAG mode- write '0' to bit0 + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + + // Enable mask for arc codeswap interrupts + meiMailboxInterruptsEnable(); + + // Return + return MEI_SUCCESS; + +} // end of "meiActivate(..." + +int meiGetPage( u32 Page, u32 data, u32 MaxSize, u32 *Buffer, u32 *Dest) +{ + u32 size; + u32 i; + u32 *p; + + if( Page > img_hdr->count) + return -2; + + /* + ** Get program or data size, depending on "data" flag + */ + size = (data == GET_DATA) ? img_hdr->page[ Page].d_size : img_hdr->page[ Page].p_size; + + size &= BOOT_FLAG_MASK; // Clear boot bit! + if( size > MaxSize) + return -1; + + if( size == 0) + return 0; + /* + ** Get program or data offset, depending on "data" flag + */ + i = data ? img_hdr->page[ Page].d_offset : img_hdr->page[ Page].p_offset; + + /* + ** Copy data/program to buffer + */ + + i /= 4; // Adjust offset for byte-to-UINT for array operation + + p = (u32 *)img_hdr + i; + for(i = 0; i < size; i++) + Buffer[i] = *p++; + /* + ** Pass back data/program destination address + */ + *Dest = data ? img_hdr->page[Page].d_dest : img_hdr->page[Page].p_dest; + + return size; +} + +MEI_ERROR meiCMV(u16 * request, int reply) // write cmv to arc, if reply needed, wait for reply +{ + MEI_ERROR meierror; + wait_queue_t wait; + + cmv_reply=reply; + + meierror = meiMailboxWrite(request, MSG_LENGTH); + + if(meierror != MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n MailboxWrite Fail."); +#endif + return meierror; + } + else{ + cmv_count++; + } + + if(cmv_reply == NO_REPLY) + return MEI_SUCCESS; + + init_waitqueue_entry(&wait, current); + add_wait_queue(&wait_queue_arcmsgav, &wait); + set_current_state(TASK_INTERRUPTIBLE); +// cmv_waiting=1; + + if(arcmsgav==1){ + set_current_state(TASK_RUNNING); + remove_wait_queue(&wait_queue_arcmsgav, &wait); + } + else{ + schedule_timeout(CMV_TIMEOUT); + remove_wait_queue(&wait_queue_arcmsgav, &wait); + } + if(arcmsgav==0){//CMV_timeout + cmv_waiting=0; + arcmsgav=0; +#ifdef AMAZON_MEI_DEBUG_ON + printk("\nmeiCMV: MEI_MAILBOX_TIMEOUT\n"); +#endif + return MEI_MAILBOX_TIMEOUT; + } + else{ + arcmsgav=0; + reply_count++; + return MEI_SUCCESS; + } +} + +//TODO, for loopback test +#ifdef DFE_LOOPBACK +#define mte_reg_base (0x4800*4+0x20000) + +/* Iridia Registers Address Constants */ +#define MTE_Reg(r) (int)(mte_reg_base + (r*4)) + +#define IT_AMODE MTE_Reg(0x0004) + + +#define OMBOX_BASE 0x15F80 +#define IMBOX_BASE 0x15FC0 + +#define TIMER_DELAY (1024) +#define BC0_BYTES (32) +#define BC1_BYTES (30) +#define NUM_MB (12) +#define TIMEOUT_VALUE 2000 + +void BFMWait (u32 cycle) { + u32 i; + for (i = 0 ; i< cycle ; i++); +} + +void WriteRegLong(u32 addr, u32 data){ + //printk("[%8x] <= %8x \n\n", addr, data); + *((volatile u32 *)(addr)) = data; +} + +u32 ReadRegLong (u32 addr) { + u32 rd_val; + + rd_val = *((volatile u32 *)(addr)); + //printk("[%8x] => %8x \n\n", addr, rd_val); + return rd_val; + +} + +/* This routine writes the mailbox with the data in an input array */ +void WriteMbox(u32 *mboxarray,u32 size) { + u32 i; + + WriteRegLong(MEI_XFR_ADDR,IMBOX_BASE); + for (i=0;i<size;i++) { + WriteRegLong(MEI_DATA_XFR,*(mboxarray+i)); + } +} + +/* This routine reads the output mailbox and places the results into an array */ +void ReadMbox(u32 *mboxarray,u32 size) { + u32 i; + + WriteRegLong(MEI_XFR_ADDR,OMBOX_BASE); + for (i=0;i<size;i++) { + mboxarray[i] = ReadRegLong(MEI_DATA_XFR); + } +} + +void MEIWriteARCValue(u32 address, u32 value) +{ + u32 i,check = 0; + /* Write address register */ + *((volatile u32 *)MEI_DEBUG_WAD) = address; + + /* Write data register */ + *((volatile u32 *)MEI_DEBUG_DATA) = value; + + /* wait until complete - timeout at 40*/ + for (i=0;i<40;i++) { + check = *((volatile u32 *)ARC_TO_MEI_INT); + if ((check & 0x20)) break; + //printk("MEIWriteARCValue: check:%8x\n\n", check); + } + + /* clear the flag */ + *((volatile u32 *)ARC_TO_MEI_INT) = 0x20; + +} + + +void post_mei_init(void) +{ +u32 mailbox[NUM_MB]; + + mailbox[0] = TIMER_DELAY; + + /* set bytes per bearer channel */ + mailbox[1] = BC0_BYTES; + mailbox[2] = BC1_BYTES; + WriteMbox(mailbox, 3); + + WriteRegLong(AAI_ACCESS, 0x00000001); + + /* enable ADSL block clock, ac_clk */ + WriteRegLong(MEI_CONTROL, 0x01); + WriteRegLong(MEI_DEBUG_DEC, 0x00000001); // select ld/st space + MEIWriteARCValue(0x31F00, 0x00000010); // write CRI_CCR0 to enable ac_clk + + /* set the MTE to register start */ + MEIWriteARCValue(IT_AMODE, 0xF); + BFMWait(10); +} + + +int wait_sync(void) +{ +u32 mailbox[NUM_MB]; + /* wait for ATM sync to be achieved on both BC0 and BC1 */ + u32 timeout=0; + ReadMbox(mailbox, 1); + u32 readval = mailbox[0]; + while( ((readval & 0xFFFFFFFF) == 0) && (timeout < TIMEOUT_VALUE) ) { + BFMWait(1); + //printk("wait_sync\n\n"); + ReadMbox(mailbox, 1); + readval = mailbox[0]; + timeout++; + } + if(timeout == TIMEOUT_VALUE)return 0; + else return 1; +} +#endif //DFE_LOOPBACK +//end of TODO, for loopback test + +MEI_ERROR meiForceRebootAdslModem(void) +{ +#if 0 +//#ifdef ARC_READY_ACK + if(down_interruptible(&mei_sema)) //disable CMV access until ARC ready + { + return -ERESTARTSYS; + } +#endif + if(reboot_firsttime==1){//000002:fchang Start + // reset ARC + *((volatile u32 *)0xB0100910) = 0x80; //reset DFE + asm("SYNC"); + *((volatile u32 *)0xB0100910) = 0x0; + asm("SYNC"); + if((*((volatile u32 *)0xB0100910))!=0x0) +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n reset DFE fail"); +#endif + + // reset ARC + meiLongwordWrite(MEI_CONTROL, SOFT_RESET); + asm("SYNC"); + meiLongwordWrite(MEI_CONTROL, 0); + asm("SYNC"); + + } //000002:fchang End +#ifdef DFE_LOOPBACK + img_hdr=(ARC_IMG_HDR *)lp_image; +#else + img_hdr=(ARC_IMG_HDR *)image_buffer; +#endif +// printk("\n\n enter haltarc"); + meiHaltArc(); +// printk("\n\n haltarc done"); +//000002:fchang Start + if(reboot_firsttime==0){ + printk("\n\n new reboot"); + meiResetArc(); + meiResetCore(); + } + if(reboot_firsttime==1) + meiDownloadBootCode(); + else + mei_ioctl((struct inode *)NULL, (struct file *)NULL, AMAZON_MEI_DOWNLOAD, (unsigned long)NULL); + +//000002:fchang End +#ifdef AMAZON_MEI_DEBUG_ON +// printk("\n\n Download Done"); +#endif + +#ifdef DFE_LOOPBACK + post_mei_init(); +#endif + +// sema_init(&mei_sema, 1); + //up(&mei_sema); + +// enable_irq(AMAZON_MEI_INT); + + meiRunArc(); +//000002:fchang Start + if(reboot_firsttime==0){ + meiEnalbeMailboxInt(); + } +//000002:fchang End + +#ifdef AMAZON_MEI_DEBUG_ON +// printk("\n\n ARC Running"); +#endif + +#ifdef AMAZON_MEI_DEBUG_ON //to test ac_clk setting correctness + { + u32 arc_control_mode; + u32 arc_debug_addr = 0x31F00; + u32 arc_debug_data = 0x10; + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode |= (HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + + meiLongwordWrite(MEI_DEBUG_DEC, MEI_DEBUG_DEC_DMP1_MASK); + meiLongwordWrite(MEI_DEBUG_RAD, arc_debug_addr); + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &arc_debug_data); + + meiLongwordRead(MEI_CONTROL, &arc_control_mode); + arc_control_mode &= ~(HOST_MSTR); + meiLongwordWrite(MEI_CONTROL, arc_control_mode); + +// printk("\n\n ac_clk is %8x\n", arc_debug_data); + } +#endif + + +#ifdef DFE_LOOPBACK + if (wait_sync() == 0){ + printk("ARC fails to run: time out\n\n"); + }else{ +// printk("ARC is ready\n\n"); + } +#endif + if(reboot_firsttime==1) //000002:fchang + reboot_firsttime=0; //000002:fchang + + return MEI_SUCCESS; +} + +//////////////////// procfs debug //////////////////////////////////////////////////////// +#define MEI_DIRNAME "mei" +static struct proc_dir_entry *meidir; + +static ssize_t proc_write(struct file *, const char *, size_t, loff_t *); +static ssize_t proc_read(struct file *, char *, size_t, loff_t *); + +static struct file_operations proc_operations = { + read: proc_read, + write: proc_write, +}; + +typedef struct reg_entry { + int * flag; + char name[30]; // big enough to hold names + char description[100]; // big enough to hold description + unsigned short low_ino; +} reg_entry_t; + +static reg_entry_t regs[PROC_ITEMS]; // total items to be monitored by /proc/mei + +#define NUM_OF_REG_ENTRY (sizeof(regs)/sizeof(reg_entry_t)) + +static int proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos) +{ + int i_ino = (file->f_dentry->d_inode)->i_ino; + char outputbuf[64]; + int count=0; + int i; + u32 version=0; + reg_entry_t* current_reg=NULL; + + for (i=0;i<NUM_OF_REG_ENTRY;i++) { + if (regs[i].low_ino==i_ino) { + current_reg = ®s[i]; + break; + } + } + if (current_reg==NULL) + return -EINVAL; + + if (current_reg->flag == (int *) 8){ + ///proc/mei/version + //format: + //Firmware version: major.minor.sub_version.int_version.rel_state.spl_appl + //Firmware Date Time Code: date/month min:hour + if (*ppos>0) /* Assume reading completed in previous read*/ + return 0; // indicates end of file + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + //if (indicator_count != 1){ + if (indicator_count < 1){ + up(&mei_sema); + return -EAGAIN; + } + //major:bits 0-7 + //minor:bits 8-15 + makeCMV(H2D_CMV_READ, INFO, 54, 0, 1, NULL); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#if 0 +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n WINHOST CMV fail"); +#endif +#endif + up(&mei_sema); + return -EIO; + } + version = RxMessage[4]; + count = sprintf(outputbuf, "%d.%d.",(version)&0xff,(version>>8)&0xff); + + //sub_version:bits 4-7 + //int_version:bits 0-3 + //spl_appl:bits 8-13 + //rel_state:bits 14-15 + makeCMV(H2D_CMV_READ, INFO, 54, 1, 1, NULL); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#if 0 +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n WINHOST CMV fail"); +#endif +#endif + up(&mei_sema); + return -EFAULT; + } + version =RxMessage[4]; + count += sprintf(outputbuf+count, "%d.%d.%d.%d", + (version>>4)&0xf, + version&0xf, + (version>>14)&0x3, + (version>>8)&0x3f); +#ifdef ADSL_LED_SUPPORT +// version check -start for adsl led + if ((((version>>4)&0xf)==2)&&((version&0xf)>=3)&&((version&0xf)<7)) firmware_support_led=1; + else if ((((version>>4)&0xf)==2)&&((version&0xf)>=7)) firmware_support_led=2; + else if (((version>>4)&0xf)>2) firmware_support_led=2; + +//165001:henryhsu:20050906:Modify for adsl firmware version 1.2.1.2.0.1 DATA_LED can't flash. + //else firmware_support_led=0; + else firmware_support_led=2; +//165001 + + +// version check -end +#endif + //Date:bits 0-7 + //Month:bits 8-15 + makeCMV(H2D_CMV_READ, INFO, 55, 0, 1, NULL); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#if 0 +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n WINHOST CMV fail"); +#endif +#endif + up(&mei_sema); + return -EIO; + } + version = RxMessage[4]; + + //Hour:bits 0-7 + //Minute:bits 8-15 + makeCMV(H2D_CMV_READ, INFO, 55, 1, 1, NULL); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#if 0 +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n WINHOST CMV fail"); +#endif +#endif + up(&mei_sema); + return -EFAULT; + } + version += (RxMessage[4]<<16); + count += sprintf(outputbuf+count, " %d/%d %d:%d\n" + ,version&0xff + ,(version>>8)&0xff + ,(version>>25)&0xff + ,(version>>16)&0xff); + + up(&mei_sema); + + *ppos+=count; + }else if(current_reg->flag != (int *)Recent_indicator){ + if (*ppos>0) /* Assume reading completed in previous read*/ + return 0; // indicates end of file + count = sprintf(outputbuf, "0x%08X\n\n", *(current_reg->flag)); + *ppos+=count; + if (count>nbytes) /* Assume output can be read at one time */ + return -EINVAL; + }else{ + if((int)(*ppos)/((int)7)==16) + return 0; // indicate end of the message + count = sprintf(outputbuf, "0x%04X\n\n", *(((u16 *)(current_reg->flag))+ (int)(*ppos)/((int)7))); + *ppos+=count; + } + if (copy_to_user(buf, outputbuf, count)) + return -EFAULT; + return count; +} + +static ssize_t proc_write(struct file * file, const char * buffer, size_t count, loff_t *ppos) +{ + int i_ino = (file->f_dentry->d_inode)->i_ino; + reg_entry_t* current_reg=NULL; + int i; + unsigned long newRegValue; + char *endp; + + for (i=0;i<NUM_OF_REG_ENTRY;i++) { + if (regs[i].low_ino==i_ino) { + current_reg = ®s[i]; + break; + } + } + if ((current_reg==NULL) || (current_reg->flag == (int *)Recent_indicator)) + return -EINVAL; + + newRegValue = simple_strtoul(buffer,&endp,0); + *(current_reg->flag)=(int)newRegValue; + return (count+endp-buffer); +} +////////////////makeCMV(Opcode, Group, Address, Index, Size, Data), CMV in u16 TxMessage[MSG_LENGTH]/////////////////////////// +void makeCMV(u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data) +{ + memset(TxMessage, 0, MSG_LENGTH*2); + TxMessage[0]= (opcode<<4) + (size&0xf); + TxMessage[1]= (((index==0)?0:1)<<7) + (group&0x7f); + TxMessage[2]= address; + TxMessage[3]= index; + if(opcode == H2D_CMV_WRITE) + memcpy(TxMessage+4, data, size*2); + return; +} + +////////////////makeCMV(Opcode, Group, Address, Index, Size, Data), CMV in u16 TxMessage[MSG_LENGTH]/////////////////////////// +void makeCMV_local(u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data,u16 *CMVMSG) +{ + memset(CMVMSG, 0, MSG_LENGTH*2); + CMVMSG[0]= (opcode<<4) + (size&0xf); + CMVMSG[1]= (((index==0)?0:1)<<7) + (group&0x7f); + CMVMSG[2]= address; + CMVMSG[3]= index; + if(opcode == H2D_CMV_WRITE) + memcpy(CMVMSG+4, data, size*2); + return; +} + +//////////////// Driver Structure ///////////////////////////////////////////////////////////////////////////// +static ssize_t mei_write(struct file *, const char *, size_t, loff_t *); +static int mei_ioctl(struct inode *, struct file *, unsigned int, unsigned long); + +static struct file_operations mei_operations = { + write: mei_write, + ioctl: mei_ioctl, +}; + + +static ssize_t mei_write(struct file * filp, const char * buf, size_t size, loff_t * loff) +{ +// printk("\n\n mei_write entered"); +// image_buffer = (u32 *)kmalloc(size, GFP_KERNEL); + image_buffer = (u32 *)vmalloc(size); +// printk("\n\n image_buffer kmalloc done"); + if(image_buffer == NULL){ +#ifdef AMAZON_MEI_DEBUG_ON +// printk("\n\n kmalloc for firmware image fail"); + printk("\n\n vmalloc for firmware image fail"); +#endif + return -1; + } + copy_from_user((char *)image_buffer, buf, size); +// printk("\n\n copy_from_user done"); + return size; +} + + ////////// ISR GPTU Timer 6 for high resolution timer ///////////// +void amazon_timer6_interrupt_MEI(int irq, void *dev_id, struct pt_regs *regs) +{ + int i,j; + u32 temp; + u16 temp16; + u16 rdindex, wrindex; + u16 num_rd=0; //num of byte can be read + u16 bytes_to_wr=0; + +// printk("\n\nenter timer\n\n"); + irqtimes++; +// printk("\n%d\n",irqtimes); + + +/* +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_8(0x30f20, &temp, 1); +#else + meiDMARead_8(0x30f20, &temp, 1); +#endif + if((temp&0x4000)!=0){ + printk("\nER_ERR"); +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_8(0x30f20, &temp, 1); +#else + meiDMAWrite_8(0x30f20, &temp, 1); +#endif +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_8(0x30f20, &temp, 1); +#else + meiDMARead_8(0x30f20, &temp, 1); +#endif + if((temp&0x4000)!=0) + printk("\nER_ERR not cleared"); + } +*/ + + for(i=PCM_CHANNEL_NUM-1;i>=0;i--){// start from last channel, which is rx +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16(pcm_start_addr+i*16+12, &temp, 1); +#else + meiDMARead_16(pcm_start_addr+i*16+12, &temp, 1); +#endif + wrindex = (u16)((temp & 0xffff0000)>>16); +// printk(" %d",wrindex); +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16(pcm_start_addr+i*16+8, &temp, 1); +#else + meiDMARead_16(pcm_start_addr+i*16+8, &temp, 1); +#endif + rdindex = (u16)(temp & 0xffff); +// printk(" %d",rdindex); + if(rdindex<=wrindex) + num_rd=((wrindex-rdindex)/4)*4; //read multiply of 4 bytes + else + num_rd=((pcm_data[i].len-(rdindex-wrindex))/4)*4; //read multiply of 4 bytes + + if(i%2!=0){//rx channel + pcm_data[i].point=0; + for(j=0;j<num_rd/4;j++){ + if(pcm_data[i].finish!=1){ + if((rdindex+j*4)>=pcm_data[i].len) + temp16=(rdindex+j*4) - pcm_data[i].len; + else + temp16=rdindex+j*4; +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16, (u32*)(pcm_data[i].buff+pcm_data[i].point), 1); +#else + meiDMARead_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16, (u32*)(pcm_data[i].buff+pcm_data[i].point), 1); +#endif + // printk(" %8x", *((u32*)(pcm_data[i].buff+pcm_data[i].point))); + /* if(pcm_data[i].point==0){ + if(pcm_data[i].buff[0]==0xA5){// start of loopback data + pcm_data[i].point+=4; + printk("\nstart receive data"); + } + } + else*/ + pcm_data[i].point+=4; + /* if(pcm_data[i].point==PCM_BUFF_SIZE){ //finish rx + pcm_data[i].finish=1; + printk("\nchannel[%d] finished", i); + } */ + } + } + if(firsttime[i]==1){ + for(j=0;j<num_rd;j++){ + if(pcm_data[i].buff[j]==0x1){ + num_cmp[i]=num_rd-j; + firsttime[i]=0; + break; + } + } + if(memcmp(sampledata+1, pcm_data[i].buff+j, num_cmp[i])!=0) + printk("\n\ndata wrong,1st\n\n"); + else + pcm_start_loc[i] = num_cmp[i]+1; + } + else{ + if(memcmp(sampledata+pcm_start_loc[i], pcm_data[i].buff, num_rd)!=0) + printk("\n\ndata wrong\n\n"); + else{ + pcm_start_loc[i]+=num_rd; + if(pcm_start_loc[i]>=256) + pcm_start_loc[i]=pcm_start_loc[i]-256; + } + } + + rdindex +=num_rd; + if(rdindex>=pcm_data[i].len) + rdindex=rdindex-pcm_data[i].len; +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16(pcm_start_addr+i*16+8, &temp, 1); +#else + meiDMARead_16(pcm_start_addr+i*16+8, &temp, 1); +#endif + temp= (temp & 0xffff0000) + rdindex; +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_16(pcm_start_addr+i*16+8, &temp, 1); // update rdindex +#else + meiDMAWrite_16(pcm_start_addr+i*16+8, &temp, 1); // update rdindex +#endif + + bytes_to_wr = num_rd; + + // if(bytes_to_wr>0){ + // printk(" %d", num_rd); + // printk(" %d", rdindex); +// printk("\n\nrdindex = %d", rdindex); + //} + } + else{ //tx channel + // if((bytes_to_wr + num_rd) < pcm_data[i].len){ + for(j=0;j<bytes_to_wr/4;j++){ + if(pcm_data[i].finish!=1){ + if((wrindex+j*4)>=pcm_data[i].len) + temp16=(wrindex+j*4) - pcm_data[i].len; + else + temp16=wrindex + j*4; +/* +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i+1].buff+j*4), 1); +#else + meiDMAWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i+1].buff+j*4), 1); +#endif*/ + +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i].buff+pcm_data[i].point), 1); + // meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i].buff), 1); +#else + meiDMAWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16))+temp16,(u32*)(pcm_data[i].buff+pcm_data[i].point), 1); +#endif + pcm_data[i].point+=4; + if(pcm_data[i].point==PCM_BUFF_SIZE){ + // pcm_data[i].finish=1; + // printk("\nchannel[%d] finished", i); + pcm_data[i].point=0; + } + } + } + wrindex+=bytes_to_wr; + if(wrindex>=pcm_data[i].len) + wrindex=wrindex-pcm_data[i].len; +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16(pcm_start_addr+i*16+12, &temp, 1); +#else + meiDMARead_16(pcm_start_addr+i*16+12, &temp, 1); +#endif + temp=(temp&0xffff) + (wrindex<<16); +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_16(pcm_start_addr+i*16+12, &temp, 1); // update wrindex +#else + meiDMAWrite_16(pcm_start_addr+i*16+12, &temp, 1); // update wrindex +#endif + + //if(bytes_to_wr>0){ + // printk(" %d", bytes_to_wr); + // printk(" %d", wrindex); +// printk("\n\nwrindex = %d", wrindex); + //} + // } + } + } + return; +} +//000002:fchang Start +static int meiResetArc(void) +{ + u32 auxreg0; + u32 auxreg5; + int flshcnt=0; + int flshcnt1=0; + int flshcnt2=0; + + meiLongwordWrite(MEI_CONTROL, 1); + meiLongwordWrite(MEI_DEBUG_DEC, 3); + meiLongwordWrite(MEI_DEBUG_WAD, 0x3c); + meiLongwordWrite(MEI_DEBUG_DATA, 0x10); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_DEC, 0x0); + meiLongwordWrite(MEI_DEBUG_WAD, 0x2); + meiLongwordWrite(MEI_DEBUG_DATA, 0x0); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_WAD, 0x3); + meiLongwordWrite(MEI_DEBUG_DATA, 0x0); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_DEC, 0x0); + meiLongwordWrite(MEI_DEBUG_RAD, 0x0); + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &auxreg0); + auxreg0 = auxreg0 & 0x03ffffff; + meiLongwordWrite(MEI_DEBUG_WAD, 0x0); + meiLongwordWrite(MEI_DEBUG_DATA, auxreg0); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_WAD, 0x10a); + meiLongwordWrite(MEI_DEBUG_DATA, 0x0); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_DEC, 0x2); + meiLongwordWrite(MEI_DEBUG_WAD, 0xfffc); + meiLongwordWrite(MEI_DEBUG_DATA, 0x1fffffff); + meiPollForDbgDone(); + while(flshcnt<3){ + meiLongwordWrite(MEI_DEBUG_DEC, 0x0); + meiLongwordWrite(MEI_DEBUG_RAD, 0x0); + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &auxreg0); + auxreg0 = auxreg0 & 0xff000000; + auxreg0 = auxreg0 | 0x3fff; + meiLongwordWrite(MEI_DEBUG_WAD, 0x0); + meiLongwordWrite(MEI_DEBUG_DATA, auxreg0); + meiPollForDbgDone(); + + meiLongwordWrite(MEI_DEBUG_DEC, 0x0); + meiLongwordWrite(MEI_DEBUG_RAD, 0x5); + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &auxreg5); + auxreg5 = auxreg5 | 0x801; + meiLongwordWrite(MEI_DEBUG_WAD, 0x5); + meiLongwordWrite(MEI_DEBUG_DATA, auxreg5); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_RAD, 0x0); + meiPollForDbgDone(); + meiLongwordRead(MEI_DEBUG_DATA, &auxreg0); + auxreg0 = auxreg0 & 0x00ffffff; + if(auxreg0 == 0x4000) + flshcnt = flshcnt+1; + else{ + if(flshcnt == 0) + flshcnt1 = flshcnt1 +1; + else + flshcnt2 = flshcnt2 +1; + } + } + + return 1; +} + +static int meiResetCore(void) +{ + meiLongwordWrite(MEI_CONTROL, 0x1); + meiLongwordWrite(MEI_DEBUG_DEC, 0x2); + meiLongwordWrite(MEI_DEBUG_WAD, 0x31f10); + meiLongwordWrite(MEI_DEBUG_DATA, 0xf); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_WAD, 0x31f10); + meiLongwordWrite(MEI_DEBUG_DATA, 0x0); + meiPollForDbgDone(); + meiLongwordWrite(MEI_DEBUG_WAD, 0x31f00); + meiLongwordWrite(MEI_DEBUG_DATA, 0x55); + meiPollForDbgDone(); + return 1; +} + +static int meiEnalbeMailboxInt(void) +{ + u32 arc2meiintmsk; + meiLongwordRead(ARC_TO_MEI_INT_MASK, &arc2meiintmsk); + arc2meiintmsk = arc2meiintmsk | 0x1; + meiLongwordWrite(ARC_TO_MEI_INT_MASK, arc2meiintmsk); + meiLongwordWrite(MEI_CONTROL, 0x0); + return 1; +} + + + +//000002:fchang End + +static int mei_ioctl(struct inode * ino, struct file * fil, unsigned int command, unsigned long lon) +{ + int i,k; + u32 boot_loop; + u32 page_size; + u32 dest_addr; + u32 j; + u32 temp; + u32 temp2; + u16 trapsflag=0; + amazon_clreoc_pkt * current_clreoc; + struct timeval time_now; + struct timeval time_fini; + struct list_head * ptr; + amazon_mei_mib * mib_ptr; +// u16 buff[MSG_LENGTH]__attribute__ ((aligned(4))); + structpts pts; + int meierr=MEI_SUCCESS; + u16 data[12]; //used in makeCMV, to pass in payload when CMV set, ignored when CMV read. + meireg regrdwr; + meidebug debugrdwr; + amazon_mei_mib * temp_intvl; + struct sk_buff * eoc_skb; +// 603221:tc.chen start + u16 hdlc_cmd[2]; + u16 hdlc_rx_buffer[32]; + int hdlc_rx_len=0; +// 603221:tc.chen end + + int from_kernel = 0;//joelin + if (ino == (struct inode *)0) from_kernel = 1;//joelin + +// printk("\n switch.command = %i\n", command); + switch(command){ + case GET_ADSL_LINE_CODE: + pts.adslLineTableEntry_pt = (adslLineTableEntry *)kmalloc(sizeof(adslLineTableEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineTableEntry_pt, (char *)lon, sizeof(adslLineTableEntry)); + if(IS_FLAG_SET((&(pts.adslLineTableEntry_pt->flags)), LINE_CODE_FLAG)){ + pts.adslLineTableEntry_pt->adslLineCode = 2; + } + copy_to_user((char *)lon, (char *)pts.adslLineTableEntry_pt, sizeof(adslLineTableEntry)); + kfree(pts.adslLineTableEntry_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ATUC_LINE_EXT: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + pts.adslLineExtTableEntry_pt = (adslLineExtTableEntry *)kmalloc(sizeof(adslLineExtTableEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineExtTableEntry_pt, (char *)lon, sizeof(adslLineExtTableEntry)); + if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CAP_FLAG)){ + ATUC_LINE_TRANS_CAP_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 67 Index 0"); +#endif + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CAP_FLAG); + } + else{ + memcpy((&(pts.adslLineExtTableEntry_pt->adslLineTransAtucCap)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG)){ + ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 67 Index 0"); +#endif + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG); + } + else{ + memcpy((&(pts.adslLineExtTableEntry_pt->adslLineTransAtucConfig)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_ACTUAL_FLAG)){ + ATUC_LINE_TRANS_ACTUAL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 2 Address 1 Index 0"); +#endif + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_ACTUAL_FLAG); + } + else{ + memcpy((&(pts.adslLineExtTableEntry_pt->adslLineTransAtucActual)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG)){ // not supported currently +/* + LINE_GLITE_POWER_STATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 2 Address 0 Index 0"); +#endif + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG); + } + else{ + memcpy((&(pts.adslLineExtTableEntry_pt->adslLineGlitePowerState)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } +*/ + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG); + } + copy_to_user((char *)lon, (char *)pts.adslLineExtTableEntry_pt, sizeof(adslLineExtTableEntry)); + kfree(pts.adslLineTableEntry_pt); + up(&mei_sema); + break; +#endif + +#ifdef AMAZON_MEI_MIB_RFC3440 + case SET_ADSL_ATUC_LINE_EXT: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + pts.adslLineExtTableEntry_pt = (adslLineExtTableEntry *)kmalloc(sizeof(adslLineExtTableEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineExtTableEntry_pt, (char *)lon, sizeof(adslLineExtTableEntry)); + + //only adslLineTransAtucConfig can be set. + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CAP_FLAG); + if(IS_FLAG_SET((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG)){ + memcpy(data,(&(pts.adslLineExtTableEntry_pt->adslLineTransAtucConfig)), 2); + ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV_WR; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 67 Index 0"); +#endif + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_CONFIG_FLAG); + } + } + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), ATUC_LINE_TRANS_ACTUAL_FLAG); + CLR_FLAG((&(pts.adslLineExtTableEntry_pt->flags)), LINE_GLITE_POWER_STATE_FLAG); + + copy_to_user((char *)lon, (char *)pts.adslLineExtTableEntry_pt, sizeof(adslLineExtTableEntry)); + kfree(pts.adslLineTableEntry_pt); + up(&mei_sema); + break; +#endif + + case GET_ADSL_ATUC_PHY: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslAtucPhysEntry_pt = (adslAtucPhysEntry *)kmalloc(sizeof(adslAtucPhysEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslAtucPhysEntry_pt, (char *)lon, sizeof(adslAtucPhysEntry)); + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_SER_NUM_FLAG)){ + ATUC_PHY_SER_NUM_FLAG_MAKECMV1; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 57 Index 0"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_SER_NUM_FLAG); + } + else{ + memcpy(pts.adslAtucPhysEntry_pt->serial_no, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + ATUC_PHY_SER_NUM_FLAG_MAKECMV2; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 57 Index 12"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_SER_NUM_FLAG); + } + else{ + memcpy((pts.adslAtucPhysEntry_pt->serial_no+24), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VENDOR_ID_FLAG)){ + ATUC_PHY_VENDOR_ID_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 64 Index 0"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VENDOR_ID_FLAG); + } + else{ + memcpy(pts.adslAtucPhysEntry_pt->vendor_id.vendor_id, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VER_NUM_FLAG)){ + ATUC_PHY_VER_NUM_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 58 Index 0"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_PHY_VER_NUM_FLAG); + } + else{ + memcpy(pts.adslAtucPhysEntry_pt->version_no, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_STAT_FLAG)){ + pts.adslAtucPhysEntry_pt->status = CurrStatus.adslAtucCurrStatus; + } + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_OUT_PWR_FLAG)){ + ATUC_CURR_OUT_PWR_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 68 Index 5"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_OUT_PWR_FLAG); + } + else{ + memcpy((&(pts.adslAtucPhysEntry_pt->outputPwr)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_ATTR_FLAG)){ + ATUC_CURR_ATTR_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 69 Index 0"); +#endif + CLR_FLAG((&(pts.adslAtucPhysEntry_pt->flags)), ATUC_CURR_ATTR_FLAG); + } + else{ + memcpy((&(pts.adslAtucPhysEntry_pt->attainableRate)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + copy_to_user((char *)lon, (char *)pts.adslAtucPhysEntry_pt, sizeof(adslAtucPhysEntry)); + kfree(pts.adslAtucPhysEntry_pt); + + up(&mei_sema); + break; + case GET_ADSL_ATUR_PHY: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslAturPhysEntry_pt = (adslAturPhysEntry *)kmalloc(sizeof(adslAturPhysEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslAturPhysEntry_pt, (char *)lon, sizeof(adslAturPhysEntry)); + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_SER_NUM_FLAG)){ + ATUR_PHY_SER_NUM_FLAG_MAKECMV1; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 62 Index 0"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_SER_NUM_FLAG); + } + else{ + memcpy(pts.adslAturPhysEntry_pt->serial_no, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + ATUR_PHY_SER_NUM_FLAG_MAKECMV2; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 62 Index 12"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_SER_NUM_FLAG); + } + else{ + memcpy((pts.adslAturPhysEntry_pt->serial_no+24), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VENDOR_ID_FLAG)){ + ATUR_PHY_VENDOR_ID_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 65 Index 0"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VENDOR_ID_FLAG); + } + else{ + memcpy(pts.adslAturPhysEntry_pt->vendor_id.vendor_id, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VER_NUM_FLAG)){ + ATUR_PHY_VER_NUM_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 61 Index 0"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_PHY_VER_NUM_FLAG); + } + else{ + memcpy(pts.adslAturPhysEntry_pt->version_no, RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_SNRMGN_FLAG)){ + ATUR_SNRMGN_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 68 Index 4"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_SNRMGN_FLAG); + } + else{ + memcpy((&(pts.adslAturPhysEntry_pt->SnrMgn)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_ATTN_FLAG)){ + ATUR_ATTN_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 68 Index 2"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_ATTN_FLAG); + } + else{ + memcpy((&(pts.adslAturPhysEntry_pt->Attn)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_STAT_FLAG)){ + pts.adslAturPhysEntry_pt->status = CurrStatus.adslAturCurrStatus; + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_OUT_PWR_FLAG)){ + ATUR_CURR_OUT_PWR_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 69 Index 5"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_OUT_PWR_FLAG); + } + else{ + memcpy((&(pts.adslAturPhysEntry_pt->outputPwr)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + if(IS_FLAG_SET((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_ATTR_FLAG)){ + ATUR_CURR_ATTR_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 68 Index 0"); +#endif + CLR_FLAG((&(pts.adslAturPhysEntry_pt->flags)), ATUR_CURR_ATTR_FLAG); + } + else{ + memcpy((&(pts.adslAturPhysEntry_pt->attainableRate)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + copy_to_user((char *)lon, (char *)pts.adslAturPhysEntry_pt, sizeof(adslAturPhysEntry)); + kfree(pts.adslAturPhysEntry_pt); + + up(&mei_sema); + break; + case GET_ADSL_ATUC_CHAN_INFO: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslAtucChanInfo_pt = (adslAtucChanInfo *)kmalloc(sizeof(adslAtucChanInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAtucChanInfo_pt, (char *)lon, sizeof(adslAtucChanInfo)); + if(IS_FLAG_SET((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_INTLV_DELAY_FLAG)){ + if((chantype.interleave!=1) || (chantype.fast==1)){ + CLR_FLAG((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_INTLV_DELAY_FLAG); + } + else{ + ATUC_CHAN_INTLV_DELAY_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 3 Index 1"); +#endif + CLR_FLAG((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_INTLV_DELAY_FLAG); + } + else{ + memcpy((&(pts.adslAtucChanInfo_pt->interleaveDelay)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + } + if(IS_FLAG_SET((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_CURR_TX_RATE_FLAG)){ + ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 1 Index 0"); +#endif + CLR_FLAG((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_CURR_TX_RATE_FLAG); + } + else{ + pts.adslAtucChanInfo_pt->currTxRate = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + if(IS_FLAG_SET((&(pts.adslAtucChanInfo_pt->flags)), ATUC_CHAN_PREV_TX_RATE_FLAG)){ + pts.adslAtucChanInfo_pt->prevTxRate = PrevTxRate.adslAtucChanPrevTxRate; + } + copy_to_user((char *)lon, (char *)pts.adslAtucChanInfo_pt, sizeof(adslAtucChanInfo)); + kfree(pts.adslAtucChanInfo_pt); + + up(&mei_sema); + break; + case GET_ADSL_ATUR_CHAN_INFO: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslAturChanInfo_pt = (adslAturChanInfo *)kmalloc(sizeof(adslAturChanInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAturChanInfo_pt, (char *)lon, sizeof(adslAturChanInfo)); + if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_INTLV_DELAY_FLAG)){ + if((chantype.interleave!=1) || (chantype.fast==1)){ + CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_INTLV_DELAY_FLAG); + } + else{ + ATUR_CHAN_INTLV_DELAY_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 2 Index 1"); +#endif + CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_INTLV_DELAY_FLAG); + } + else{ + memcpy((&(pts.adslAturChanInfo_pt->interleaveDelay)), RxMessage+4, ((RxMessage[0]&0xf)*2)); + } + } + } + if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CURR_TX_RATE_FLAG)){ + ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 0 Index 0"); +#endif + CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CURR_TX_RATE_FLAG); + } + else{ + pts.adslAturChanInfo_pt->currTxRate = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_PREV_TX_RATE_FLAG)){ + pts.adslAturChanInfo_pt->prevTxRate = PrevTxRate.adslAturChanPrevTxRate; + } + if(IS_FLAG_SET((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CRC_BLK_LEN_FLAG)){ + // ? no CMV to update this + CLR_FLAG((&(pts.adslAturChanInfo_pt->flags)), ATUR_CHAN_CRC_BLK_LEN_FLAG); + } + copy_to_user((char *)lon, (char *)pts.adslAturChanInfo_pt, sizeof(adslAturChanInfo)); + kfree(pts.adslAturChanInfo_pt); + + up(&mei_sema); + break; + case GET_ADSL_ATUC_PERF_DATA: + pts.atucPerfDataEntry_pt = (atucPerfDataEntry *)kmalloc(sizeof(atucPerfDataEntry), GFP_KERNEL); + copy_from_user((char *)pts.atucPerfDataEntry_pt, (char *)lon, sizeof(atucPerfDataEntry)); + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_LOFS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfLofs=ATUC_PERF_LOFS; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_LOSS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfLoss=ATUC_PERF_LOSS; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_ESS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfESs=ATUC_PERF_ESS; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_INITS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfInits=ATUC_PERF_INITS; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_VALID_INTVLS_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==96) + break; + } + pts.atucPerfDataEntry_pt->adslAtucPerfValidIntervals=i; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_INVALID_INTVLS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfInvalidIntervals=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_TIME_ELAPSED_FLAG)){ + do_gettimeofday(&time_now); + pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinTimeElapsed=time_now.tv_sec - (current_intvl->start_time).tv_sec; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_LOFS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinLofs=current_intvl->AtucPerfLof; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_LOSS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinLoss=current_intvl->AtucPerfLos; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_ESS_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinESs=current_intvl->AtucPerfEs; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_15MIN_INIT_FLAG)){ + pts.atucPerfDataEntry_pt->adslAtucPerfCurr15MinInits=current_intvl->AtucPerfInit; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_TIME_ELAPSED_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i+=900; + } + do_gettimeofday(&time_now); + i+=time_now.tv_sec - (current_intvl->start_time).tv_sec; + if(i>=86400) + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayTimeElapsed=i-86400; + else + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayTimeElapsed=i; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_LOFS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfLof; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfLof; + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayLofs=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_LOSS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfLos; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfLos; + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayLoss=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_ESS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfEs; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfEs; + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayESs=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_CURR_1DAY_INIT_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfInit; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfInit; + pts.atucPerfDataEntry_pt->adslAtucPerfCurr1DayInits=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_MON_SEC_FLAG)){ + i=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + i++; + } + if(i>=96) + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayMoniSecs=86400; + else + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayMoniSecs=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_LOFS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfLof; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLofs=j; + else + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLofs=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_LOSS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfLos; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLoss=j; + else + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayLoss=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_ESS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfEs; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayESs=j; + else + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayESs=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataEntry_pt->flags)), ATUC_PERF_PREV_1DAY_INITS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfInit; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayInits=j; + else + pts.atucPerfDataEntry_pt->adslAtucPerfPrev1DayInits=0; + } + + copy_to_user((char *)lon, (char *)pts.atucPerfDataEntry_pt, sizeof(atucPerfDataEntry)); + kfree(pts.atucPerfDataEntry_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ATUC_PERF_DATA_EXT: //??? CMV mapping not available + pts.atucPerfDataExtEntry_pt = (atucPerfDataExtEntry *)kmalloc(sizeof(atucPerfDataExtEntry), GFP_KERNEL); + copy_from_user((char *)pts.atucPerfDataExtEntry_pt, (char *)lon, sizeof(atucPerfDataExtEntry)); + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_FASTR_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfStatFastR=ATUC_PERF_STAT_FASTR; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_FAILED_FASTR_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfStatFailedFastR=ATUC_PERF_STAT_FAILED_FASTR; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_SESL_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfStatSesL=ATUC_PERF_STAT_SESL; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_STAT_UASL_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfStatUasL=ATUC_PERF_STAT_UASL; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_FASTR_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinFastR=current_intvl->AtucPerfStatFastR; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_FAILED_FASTR_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinFailedFastR=current_intvl->AtucPerfStatFailedFastR; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_SESL_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinSesL=current_intvl->AtucPerfStatSesL; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_15MIN_UASL_FLAG)){ + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr15MinUasL=current_intvl->AtucPerfStatUasL; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_FASTR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatFastR; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfStatFastR; + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DayFastR=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_FAILED_FASTR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatFailedFastR; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfStatFailedFastR; + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DayFailedFastR=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_SESL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatSesL; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfStatSesL; + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DaySesL=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_CURR_1DAY_UASL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatUasL; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AtucPerfStatUasL; + pts.atucPerfDataExtEntry_pt->adslAtucPerfCurr1DayUasL=j; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_FASTR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatFastR; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFastR=j; + else + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFastR=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_FAILED_FASTR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatFailedFastR; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFailedFastR=j; + else + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayFailedFastR=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_SESL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatSesL; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DaySesL=j; + else + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DaySesL=0; + } + if(IS_FLAG_SET((&(pts.atucPerfDataExtEntry_pt->flags)), ATUC_PERF_PREV_1DAY_UASL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AtucPerfStatUasL; + i++; + if(i==96) + break; + } + if(i==96) + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayUasL=j; + else + pts.atucPerfDataExtEntry_pt->adslAtucPerfPrev1DayUasL=0; + } + copy_to_user((char *)lon, (char *)pts.atucPerfDataExtEntry_pt, sizeof(atucPerfDataExtEntry)); + kfree(pts.atucPerfDataExtEntry_pt); + break; +#endif + case GET_ADSL_ATUR_PERF_DATA: + pts.aturPerfDataEntry_pt = (aturPerfDataEntry *)kmalloc(sizeof(aturPerfDataEntry), GFP_KERNEL); + copy_from_user((char *)pts.aturPerfDataEntry_pt, (char *)lon, sizeof(aturPerfDataEntry)); + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_LOFS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfLofs=ATUR_PERF_LOFS; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_LOSS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfLoss=ATUR_PERF_LOSS; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_LPR_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfLprs=ATUR_PERF_LPR; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_ESS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfESs=ATUR_PERF_ESS; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_VALID_INTVLS_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==96) + break; + } + pts.aturPerfDataEntry_pt->adslAturPerfValidIntervals=i; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_INVALID_INTVLS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfInvalidIntervals=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_TIME_ELAPSED_FLAG)){ + do_gettimeofday(&time_now); + pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinTimeElapsed=time_now.tv_sec - (current_intvl->start_time).tv_sec; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_LOFS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinLofs=current_intvl->AturPerfLof; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_LOSS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinLoss=current_intvl->AturPerfLos; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_LPR_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinLprs=current_intvl->AturPerfLpr; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_15MIN_ESS_FLAG)){ + pts.aturPerfDataEntry_pt->adslAturPerfCurr15MinESs=current_intvl->AturPerfEs; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_TIME_ELAPSED_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i+=900; + } + do_gettimeofday(&time_now); + i+=time_now.tv_sec - (current_intvl->start_time).tv_sec; + if(i>=86400) + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayTimeElapsed=i-86400; + else + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayTimeElapsed=i; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_LOFS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLof; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfLof; + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayLofs=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_LOSS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLos; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfLos; + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayLoss=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_LPR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLpr; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfLpr; + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayLprs=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_CURR_1DAY_ESS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfEs; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfEs; + pts.aturPerfDataEntry_pt->adslAturPerfCurr1DayESs=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_MON_SEC_FLAG)){ + i=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + i++; + } + if(i>=96) + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayMoniSecs=86400; + else + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayMoniSecs=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_LOFS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLof; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLofs=j; + else + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLofs=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_LOSS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLos; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLoss=j; + else + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLoss=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_LPR_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfLpr; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLprs=j; + else + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayLprs=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataEntry_pt->flags)), ATUR_PERF_PREV_1DAY_ESS_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfEs; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayESs=j; + else + pts.aturPerfDataEntry_pt->adslAturPerfPrev1DayESs=0; + } + + copy_to_user((char *)lon, (char *)pts.aturPerfDataEntry_pt, sizeof(aturPerfDataEntry)); + kfree(pts.aturPerfDataEntry_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ATUR_PERF_DATA_EXT: + pts.aturPerfDataExtEntry_pt = (aturPerfDataExtEntry *)kmalloc(sizeof(aturPerfDataExtEntry), GFP_KERNEL); + copy_from_user((char *)pts.aturPerfDataExtEntry_pt, (char *)lon, sizeof(aturPerfDataExtEntry)); + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_STAT_SESL_FLAG)){ + pts.aturPerfDataExtEntry_pt->adslAturPerfStatSesL=ATUR_PERF_STAT_SESL; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_STAT_UASL_FLAG)){ + pts.aturPerfDataExtEntry_pt->adslAturPerfStatUasL=ATUR_PERF_STAT_UASL; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_15MIN_SESL_FLAG)){ + pts.aturPerfDataExtEntry_pt->adslAturPerfCurr15MinSesL=current_intvl->AturPerfStatSesL; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_15MIN_UASL_FLAG)){ + pts.aturPerfDataExtEntry_pt->adslAturPerfCurr15MinUasL=current_intvl->AturPerfStatUasL; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_1DAY_SESL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfStatSesL; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfStatSesL; + pts.aturPerfDataExtEntry_pt->adslAturPerfCurr1DaySesL=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_CURR_1DAY_UASL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfStatUasL; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturPerfStatUasL; + pts.aturPerfDataExtEntry_pt->adslAturPerfCurr1DayUasL=j; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_PREV_1DAY_SESL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfStatSesL; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DaySesL=j; + else + pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DaySesL=0; + } + if(IS_FLAG_SET((&(pts.aturPerfDataExtEntry_pt->flags)), ATUR_PERF_PREV_1DAY_UASL_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturPerfStatUasL; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DayUasL=j; + else + pts.aturPerfDataExtEntry_pt->adslAturPerfPrev1DayUasL=0; + } + copy_to_user((char *)lon, (char *)pts.aturPerfDataExtEntry_pt, sizeof(aturPerfDataExtEntry)); + kfree(pts.aturPerfDataExtEntry_pt); + break; +#endif + case GET_ADSL_ATUC_INTVL_INFO: + pts.adslAtucIntvlInfo_pt = (adslAtucIntvlInfo *)kmalloc(sizeof(adslAtucIntvlInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAtucIntvlInfo_pt, (char *)lon, sizeof(adslAtucIntvlInfo)); + + if(pts.adslAtucIntvlInfo_pt->IntervalNumber <1){ + pts.adslAtucIntvlInfo_pt->intervalLOF = ATUC_PERF_LOFS; + pts.adslAtucIntvlInfo_pt->intervalLOS = ATUC_PERF_LOSS; + pts.adslAtucIntvlInfo_pt->intervalES = ATUC_PERF_ESS; + pts.adslAtucIntvlInfo_pt->intervalInits = ATUC_PERF_INITS; + pts.adslAtucIntvlInfo_pt->intervalValidData = 1; + } + else{ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==pts.adslAtucIntvlInfo_pt->IntervalNumber){ + temp_intvl = list_entry(ptr, amazon_mei_mib, list); + pts.adslAtucIntvlInfo_pt->intervalLOF = temp_intvl->AtucPerfLof; + pts.adslAtucIntvlInfo_pt->intervalLOS = temp_intvl->AtucPerfLos; + pts.adslAtucIntvlInfo_pt->intervalES = temp_intvl->AtucPerfEs; + pts.adslAtucIntvlInfo_pt->intervalInits = temp_intvl->AtucPerfInit; + pts.adslAtucIntvlInfo_pt->intervalValidData = 1; + break; + } + } + if(ptr==&interval_list){ + pts.adslAtucIntvlInfo_pt->intervalValidData = 0; + pts.adslAtucIntvlInfo_pt->flags = 0; + pts.adslAtucIntvlInfo_pt->intervalLOF = 0; + pts.adslAtucIntvlInfo_pt->intervalLOS = 0; + pts.adslAtucIntvlInfo_pt->intervalES = 0; + pts.adslAtucIntvlInfo_pt->intervalInits = 0; + } + } + + copy_to_user((char *)lon, (char *)pts.adslAtucIntvlInfo_pt, sizeof(adslAtucIntvlInfo)); + kfree(pts.adslAtucIntvlInfo_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ATUC_INTVL_EXT_INFO: + pts.adslAtucInvtlExtInfo_pt = (adslAtucInvtlExtInfo *)kmalloc(sizeof(adslAtucInvtlExtInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAtucInvtlExtInfo_pt, (char *)lon, sizeof(adslAtucInvtlExtInfo)); + if(pts.adslAtucInvtlExtInfo_pt->IntervalNumber <1){ + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFastR = ATUC_PERF_STAT_FASTR; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFailedFastR = ATUC_PERF_STAT_FAILED_FASTR; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalSesL = ATUC_PERF_STAT_SESL; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalUasL = ATUC_PERF_STAT_UASL; +// pts.adslAtucInvtlExtInfo_pt->intervalValidData = 1; + } + else{ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==pts.adslAtucInvtlExtInfo_pt->IntervalNumber){ + temp_intvl = list_entry(ptr, amazon_mei_mib, list); + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFastR = temp_intvl->AtucPerfStatFastR; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFailedFastR = temp_intvl->AtucPerfStatFailedFastR; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalSesL = temp_intvl->AtucPerfStatSesL; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalUasL = temp_intvl->AtucPerfStatUasL; +// pts.adslAtucInvtlExtInfo_pt->intervalValidData = 1; + break; + } + } + if(ptr==&interval_list){ +// pts.adslAtucInvtlExtInfo_pt->intervalValidData = 0; + pts.adslAtucInvtlExtInfo_pt->flags = 0; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFastR = 0; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalFailedFastR = 0; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalSesL = 0; + pts.adslAtucInvtlExtInfo_pt->adslAtucIntervalUasL = 0; + } + } + copy_to_user((char *)lon, (char *)pts.adslAtucInvtlExtInfo_pt, sizeof(adslAtucInvtlExtInfo)); + kfree(pts.adslAtucInvtlExtInfo_pt); + break; +#endif + case GET_ADSL_ATUR_INTVL_INFO: + pts.adslAturIntvlInfo_pt = (adslAturIntvlInfo *)kmalloc(sizeof(adslAturIntvlInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAturIntvlInfo_pt, (char *)lon, sizeof(adslAturIntvlInfo)); + + if(pts.adslAturIntvlInfo_pt->IntervalNumber <1){ + pts.adslAturIntvlInfo_pt->intervalLOF = ATUR_PERF_LOFS; + pts.adslAturIntvlInfo_pt->intervalLOS = ATUR_PERF_LOSS; + pts.adslAturIntvlInfo_pt->intervalES = ATUR_PERF_ESS; + pts.adslAturIntvlInfo_pt->intervalLPR = ATUR_PERF_LPR; + pts.adslAturIntvlInfo_pt->intervalValidData = 1; + } + else{ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==pts.adslAturIntvlInfo_pt->IntervalNumber){ + temp_intvl = list_entry(ptr, amazon_mei_mib, list); + pts.adslAturIntvlInfo_pt->intervalLOF = temp_intvl->AturPerfLof; + pts.adslAturIntvlInfo_pt->intervalLOS = temp_intvl->AturPerfLos; + pts.adslAturIntvlInfo_pt->intervalES = temp_intvl->AturPerfEs; + pts.adslAturIntvlInfo_pt->intervalLPR = temp_intvl->AturPerfLpr; + pts.adslAturIntvlInfo_pt->intervalValidData = 1; + break; + } + } + if(ptr==&interval_list){ + pts.adslAturIntvlInfo_pt->intervalValidData = 0; + pts.adslAturIntvlInfo_pt->flags = 0; + pts.adslAturIntvlInfo_pt->intervalLOF = 0; + pts.adslAturIntvlInfo_pt->intervalLOS = 0; + pts.adslAturIntvlInfo_pt->intervalES = 0; + pts.adslAturIntvlInfo_pt->intervalLPR = 0; + } + } + + copy_to_user((char *)lon, (char *)pts.adslAturIntvlInfo_pt, sizeof(adslAturIntvlInfo)); + kfree(pts.adslAturIntvlInfo_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ATUR_INTVL_EXT_INFO: + pts.adslAturInvtlExtInfo_pt = (adslAturInvtlExtInfo *)kmalloc(sizeof(adslAturInvtlExtInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAturInvtlExtInfo_pt, (char *)lon, sizeof(adslAturInvtlExtInfo)); + + if(pts.adslAturInvtlExtInfo_pt->IntervalNumber <1){ + pts.adslAturInvtlExtInfo_pt->adslAturIntervalSesL = ATUR_PERF_STAT_SESL; + pts.adslAturInvtlExtInfo_pt->adslAturIntervalUasL = ATUR_PERF_STAT_UASL; +// pts.adslAturInvtlExtInfo_pt->intervalValidData = 1; + } + else{ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==pts.adslAturInvtlExtInfo_pt->IntervalNumber){ + temp_intvl = list_entry(ptr, amazon_mei_mib, list); + pts.adslAturInvtlExtInfo_pt->adslAturIntervalSesL = temp_intvl->AturPerfStatSesL; + pts.adslAturInvtlExtInfo_pt->adslAturIntervalUasL = temp_intvl->AturPerfStatUasL; +// pts.adslAturInvtlExtInfo_pt->intervalValidData = 1; + break; + } + } + if(ptr==&interval_list){ +// pts.adslAturInvtlExtInfo_pt->intervalValidData = 0; + pts.adslAturInvtlExtInfo_pt->flags = 0; + pts.adslAturInvtlExtInfo_pt->adslAturIntervalSesL = 0; + pts.adslAturInvtlExtInfo_pt->adslAturIntervalUasL = 0; + } + } + + copy_to_user((char *)lon, (char *)pts.adslAturInvtlExtInfo_pt, sizeof(adslAturInvtlExtInfo)); + kfree(pts.adslAturInvtlExtInfo_pt); + break; +#endif + case GET_ADSL_ATUC_CHAN_PERF_DATA: + pts.atucChannelPerfDataEntry_pt = (atucChannelPerfDataEntry *)kmalloc(sizeof(atucChannelPerfDataEntry), GFP_KERNEL); + copy_from_user((char *)pts.atucChannelPerfDataEntry_pt, (char *)lon, sizeof(atucChannelPerfDataEntry)); + + pts.atucChannelPerfDataEntry_pt->flags = 0; + + copy_to_user((char *)lon, (char *)pts.atucChannelPerfDataEntry_pt, sizeof(atucChannelPerfDataEntry)); + kfree(pts.atucChannelPerfDataEntry_pt); + break; + case GET_ADSL_ATUR_CHAN_PERF_DATA: + pts.aturChannelPerfDataEntry_pt = (aturChannelPerfDataEntry *)kmalloc(sizeof(aturChannelPerfDataEntry), GFP_KERNEL); + copy_from_user((char *)pts.aturChannelPerfDataEntry_pt, (char *)lon, sizeof(aturChannelPerfDataEntry)); + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_RECV_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanReceivedBlks=ATUR_CHAN_RECV_BLK; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_TX_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanTransmittedBlks=ATUR_CHAN_TX_BLK; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_CORR_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanCorrectedBlks=ATUR_CHAN_CORR_BLK; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_UNCORR_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanUncorrectBlks=ATUR_CHAN_UNCORR_BLK; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_VALID_INTVL_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==96) + break; + } + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfValidIntervals=i; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_INVALID_INTVL_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfInvalidIntervals=0; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_TIME_ELAPSED_FLAG)){ + do_gettimeofday(&time_now); + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinTimeElapsed=time_now.tv_sec - (current_intvl->start_time).tv_sec; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_RECV_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinReceivedBlks=current_intvl->AturChanPerfRxBlk; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_TX_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinTransmittedBlks=current_intvl->AturChanPerfTxBlk; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_CORR_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinCorrectedBlks=current_intvl->AturChanPerfCorrBlk; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_15MIN_UNCORR_BLK_FLAG)){ + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr15MinUncorrectBlks=current_intvl->AturChanPerfUncorrBlk; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_TIME_ELAPSED_FLAG)){ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i+=900; + } + do_gettimeofday(&time_now); + i+=time_now.tv_sec - (current_intvl->start_time).tv_sec; + if(i>=86400) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayTimeElapsed=i-86400; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayTimeElapsed=i; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_RECV_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfRxBlk; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturChanPerfRxBlk; + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayReceivedBlks=j; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_TX_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfTxBlk; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturChanPerfTxBlk; + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayTransmittedBlks=j; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_CORR_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfCorrBlk; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturChanPerfCorrBlk; + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayCorrectedBlks=j; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_CURR_1DAY_UNCORR_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfUncorrBlk; + i++; + if(i==96) + j=0; + } + j+=current_intvl->AturChanPerfUncorrBlk; + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfCurr1DayUncorrectBlks=j; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_MONI_SEC_FLAG)){ + i=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + i++; + } + if(i>=96) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayMoniSecs=86400; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayMoniSecs=0; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_RECV_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfRxBlk; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayReceivedBlks=j; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayReceivedBlks=0; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_TRANS_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfTxBlk; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayTransmittedBlks=j; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayTransmittedBlks=0; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_CORR_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfCorrBlk; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayCorrectedBlks=j; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayCorrectedBlks=0; + } + if(IS_FLAG_SET((&(pts.aturChannelPerfDataEntry_pt->flags)), ATUR_CHAN_PERF_PREV_1DAY_UNCORR_BLK_FLAG)){ + i=0; + j=0; + for(ptr=interval_list.next; ptr!=&(current_intvl->list); ptr=ptr->next){ + mib_ptr = list_entry(ptr, amazon_mei_mib, list); + j+=mib_ptr->AturChanPerfUncorrBlk; + i++; + if(i==96) + break; + } + if(i==96) + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayUncorrectBlks=j; + else + pts.aturChannelPerfDataEntry_pt->adslAturChanPerfPrev1DayUncorrectBlks=0; + } + + copy_to_user((char *)lon, (char *)pts.aturChannelPerfDataEntry_pt, sizeof(aturChannelPerfDataEntry)); + kfree(pts.aturChannelPerfDataEntry_pt); + break; + case GET_ADSL_ATUC_CHAN_INTVL_INFO: + pts.adslAtucChanIntvlInfo_pt = (adslAtucChanIntvlInfo *)kmalloc(sizeof(adslAtucChanIntvlInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAtucChanIntvlInfo_pt, (char *)lon, sizeof(adslAtucChanIntvlInfo)); + + pts.adslAtucChanIntvlInfo_pt->flags = 0; + + copy_to_user((char *)lon, (char *)pts.adslAtucChanIntvlInfo_pt, sizeof(adslAtucChanIntvlInfo)); + kfree(pts.adslAtucChanIntvlInfo_pt); + break; + case GET_ADSL_ATUR_CHAN_INTVL_INFO: + pts.adslAturChanIntvlInfo_pt = (adslAturChanIntvlInfo *)kmalloc(sizeof(adslAturChanIntvlInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslAturChanIntvlInfo_pt, (char *)lon, sizeof(adslAturChanIntvlInfo)); + + if(pts.adslAturChanIntvlInfo_pt->IntervalNumber <1){ + pts.adslAturChanIntvlInfo_pt->chanIntervalRecvdBlks = ATUR_CHAN_RECV_BLK; + pts.adslAturChanIntvlInfo_pt->chanIntervalXmitBlks = ATUR_CHAN_TX_BLK; + pts.adslAturChanIntvlInfo_pt->chanIntervalCorrectedBlks = ATUR_CHAN_CORR_BLK; + pts.adslAturChanIntvlInfo_pt->chanIntervalUncorrectBlks = ATUR_CHAN_UNCORR_BLK; + pts.adslAturChanIntvlInfo_pt->intervalValidData = 1; + } + else{ + i=0; + for(ptr=(current_intvl->list).prev; ptr!=&interval_list; ptr=ptr->prev){ + i++; + if(i==pts.adslAturChanIntvlInfo_pt->IntervalNumber){ + temp_intvl = list_entry(ptr, amazon_mei_mib, list); + pts.adslAturChanIntvlInfo_pt->chanIntervalRecvdBlks = temp_intvl->AturChanPerfRxBlk; + pts.adslAturChanIntvlInfo_pt->chanIntervalXmitBlks = temp_intvl->AturChanPerfTxBlk; + pts.adslAturChanIntvlInfo_pt->chanIntervalCorrectedBlks = temp_intvl->AturChanPerfCorrBlk; + pts.adslAturChanIntvlInfo_pt->chanIntervalUncorrectBlks = temp_intvl->AturChanPerfUncorrBlk; + pts.adslAturChanIntvlInfo_pt->intervalValidData = 1; + break; + } + } + if(ptr==&interval_list){ + pts.adslAturChanIntvlInfo_pt->intervalValidData = 0; + pts.adslAturChanIntvlInfo_pt->flags = 0; + } + } + + copy_to_user((char *)lon, (char *)pts.adslAturChanIntvlInfo_pt, sizeof(adslAturChanIntvlInfo)); + kfree(pts.adslAturChanIntvlInfo_pt); + break; + case GET_ADSL_ALRM_CONF_PROF: + pts.adslLineAlarmConfProfileEntry_pt = (adslLineAlarmConfProfileEntry *)kmalloc(sizeof(adslLineAlarmConfProfileEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineAlarmConfProfileEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileEntry)); + + strncpy(pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileName, AlarmConfProfile.adslLineAlarmConfProfileName, 32); + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOFS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLofs=AlarmConfProfile.adslAtucThresh15MinLofs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOSS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLoss=AlarmConfProfile.adslAtucThresh15MinLoss; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_ESS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinESs=AlarmConfProfile.adslAtucThresh15MinESs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEUP_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateUp=AlarmConfProfile.adslAtucThreshFastRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEUP_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateUp=AlarmConfProfile.adslAtucThreshInterleaveRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEDOWN_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateDown=AlarmConfProfile.adslAtucThreshFastRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEDOWN_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateDown=AlarmConfProfile.adslAtucThreshInterleaveRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_INIT_FAILURE_TRAP_ENABLE_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAtucInitFailureTrapEnable=AlarmConfProfile.adslAtucInitFailureTrapEnable; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOFS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLofs=AlarmConfProfile.adslAturThresh15MinLofs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOSS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLoss=AlarmConfProfile.adslAturThresh15MinLoss; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LPRS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLprs=AlarmConfProfile.adslAturThresh15MinLprs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_ESS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinESs=AlarmConfProfile.adslAturThresh15MinESs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEUP_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateUp=AlarmConfProfile.adslAturThreshFastRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEUP_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateUp=AlarmConfProfile.adslAturThreshInterleaveRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEDOWN_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateDown=AlarmConfProfile.adslAturThreshFastRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEDOWN_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateDown=AlarmConfProfile.adslAturThreshInterleaveRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), LINE_ALARM_CONF_PROFILE_ROWSTATUS_FLAG)){ + pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileRowStatus=AlarmConfProfile.adslLineAlarmConfProfileRowStatus; + } + copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileEntry_pt, sizeof(adslLineAlarmConfProfileEntry)); + kfree(pts.adslLineAlarmConfProfileEntry_pt); + break; +#ifdef AMAZON_MEI_MIB_RFC3440 + case GET_ADSL_ALRM_CONF_PROF_EXT: + pts.adslLineAlarmConfProfileExtEntry_pt = (adslLineAlarmConfProfileExtEntry *)kmalloc(sizeof(adslLineAlarmConfProfileExtEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineAlarmConfProfileExtEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileExtEntry)); + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_FAILED_FASTR_FLAG)){ + pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinFailedFastR=AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_SESL_FLAG)){ + pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinSesL=AlarmConfProfileExt.adslAtucThreshold15MinSesL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_UASL_FLAG)){ + pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinUasL=AlarmConfProfileExt.adslAtucThreshold15MinUasL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_SESL_FLAG)){ + pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinSesL=AlarmConfProfileExt.adslAturThreshold15MinSesL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_UASL_FLAG)){ + pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinUasL=AlarmConfProfileExt.adslAturThreshold15MinUasL; + } + copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileExtEntry_pt, sizeof(adslLineAlarmConfProfileExtEntry)); + kfree(pts.adslLineAlarmConfProfileExtEntry_pt); + break; +#endif + case SET_ADSL_ALRM_CONF_PROF: + pts.adslLineAlarmConfProfileEntry_pt = (adslLineAlarmConfProfileEntry *)kmalloc(sizeof(adslLineAlarmConfProfileEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineAlarmConfProfileEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileEntry)); + + strncpy(AlarmConfProfile.adslLineAlarmConfProfileName, pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileName, 32); + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOFS_FLAG)){ + AlarmConfProfile.adslAtucThresh15MinLofs=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLofs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_LOSS_FLAG)){ + AlarmConfProfile.adslAtucThresh15MinLoss=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinLoss; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_15MIN_ESS_FLAG)){ + AlarmConfProfile.adslAtucThresh15MinESs=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThresh15MinESs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEUP_FLAG)){ + AlarmConfProfile.adslAtucThreshFastRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEUP_FLAG)){ + AlarmConfProfile.adslAtucThreshInterleaveRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_FAST_RATEDOWN_FLAG)){ + AlarmConfProfile.adslAtucThreshFastRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshFastRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_THRESH_INTERLEAVE_RATEDOWN_FLAG)){ + AlarmConfProfile.adslAtucThreshInterleaveRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAtucThreshInterleaveRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUC_INIT_FAILURE_TRAP_ENABLE_FLAG)){ + AlarmConfProfile.adslAtucInitFailureTrapEnable=pts.adslLineAlarmConfProfileEntry_pt->adslAtucInitFailureTrapEnable; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOFS_FLAG)){ + AlarmConfProfile.adslAturThresh15MinLofs=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLofs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LOSS_FLAG)){ + AlarmConfProfile.adslAturThresh15MinLoss=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLoss; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_LPRS_FLAG)){ + AlarmConfProfile.adslAturThresh15MinLprs=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinLprs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_15MIN_ESS_FLAG)){ + AlarmConfProfile.adslAturThresh15MinESs=pts.adslLineAlarmConfProfileEntry_pt->adslAturThresh15MinESs; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEUP_FLAG)){ + AlarmConfProfile.adslAturThreshFastRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEUP_FLAG)){ + AlarmConfProfile.adslAturThreshInterleaveRateUp=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateUp; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_FAST_RATEDOWN_FLAG)){ + AlarmConfProfile.adslAturThreshFastRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshFastRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), ATUR_THRESH_INTERLEAVE_RATEDOWN_FLAG)){ + AlarmConfProfile.adslAturThreshInterleaveRateDown=pts.adslLineAlarmConfProfileEntry_pt->adslAturThreshInterleaveRateDown; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileEntry_pt->flags)), LINE_ALARM_CONF_PROFILE_ROWSTATUS_FLAG)){ + AlarmConfProfile.adslLineAlarmConfProfileRowStatus=pts.adslLineAlarmConfProfileEntry_pt->adslLineAlarmConfProfileRowStatus; + } + copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileEntry_pt, sizeof(adslLineAlarmConfProfileEntry)); + kfree(pts.adslLineAlarmConfProfileEntry_pt); + break; + +#ifdef AMAZON_MEI_MIB_RFC3440 + case SET_ADSL_ALRM_CONF_PROF_EXT: + pts.adslLineAlarmConfProfileExtEntry_pt = (adslLineAlarmConfProfileExtEntry *)kmalloc(sizeof(adslLineAlarmConfProfileExtEntry), GFP_KERNEL); + copy_from_user((char *)pts.adslLineAlarmConfProfileExtEntry_pt, (char *)lon, sizeof(adslLineAlarmConfProfileExtEntry)); + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_FAILED_FASTR_FLAG)){ + AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR=pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinFailedFastR; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_SESL_FLAG)){ + AlarmConfProfileExt.adslAtucThreshold15MinSesL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinSesL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUC_THRESH_15MIN_UASL_FLAG)){ + AlarmConfProfileExt.adslAtucThreshold15MinUasL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAtucThreshold15MinUasL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_SESL_FLAG)){ + AlarmConfProfileExt.adslAturThreshold15MinSesL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinSesL; + } + if(IS_FLAG_SET((&(pts.adslLineAlarmConfProfileExtEntry_pt->flags)), ATUR_THRESH_15MIN_UASL_FLAG)){ + AlarmConfProfileExt.adslAturThreshold15MinUasL=pts.adslLineAlarmConfProfileExtEntry_pt->adslAturThreshold15MinUasL; + } + copy_to_user((char *)lon, (char *)pts.adslLineAlarmConfProfileExtEntry_pt, sizeof(adslLineAlarmConfProfileExtEntry)); + kfree(pts.adslLineAlarmConfProfileExtEntry_pt); + break; +#endif + + case ADSL_ATUR_TRAPS: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + trapsflag=0; + if(AlarmConfProfile.adslAtucThresh15MinLofs!=0 && current_intvl->AtucPerfLof>=AlarmConfProfile.adslAtucThresh15MinLofs) + trapsflag|=ATUC_PERF_LOFS_THRESH_FLAG; + if(AlarmConfProfile.adslAtucThresh15MinLoss!=0 && current_intvl->AtucPerfLos>=AlarmConfProfile.adslAtucThresh15MinLoss) + trapsflag|=ATUC_PERF_LOSS_THRESH_FLAG; + if(AlarmConfProfile.adslAtucThresh15MinESs!=0 && current_intvl->AtucPerfEs>=AlarmConfProfile.adslAtucThresh15MinESs) + trapsflag|=ATUC_PERF_ESS_THRESH_FLAG; + if(chantype.fast==1){ + if(AlarmConfProfile.adslAtucThreshFastRateUp!=0 || AlarmConfProfile.adslAtucThreshFastRateDown!=0){ + ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 1 Index 0"); +#endif + } + else{ + temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + if((AlarmConfProfile.adslAtucThreshFastRateUp!=0) && (temp>=PrevTxRate.adslAtucChanPrevTxRate+AlarmConfProfile.adslAtucThreshFastRateUp)){ + trapsflag|=ATUC_RATE_CHANGE_FLAG; + PrevTxRate.adslAtucChanPrevTxRate = temp; + } + if((AlarmConfProfile.adslAtucThreshFastRateDown!=0) && (temp<=PrevTxRate.adslAtucChanPrevTxRate-AlarmConfProfile.adslAtucThreshFastRateDown)){ + trapsflag|=ATUC_RATE_CHANGE_FLAG; + PrevTxRate.adslAtucChanPrevTxRate = temp; + } + } + } + } + if(chantype.interleave==1){ + if(AlarmConfProfile.adslAtucThreshInterleaveRateUp!=0 || AlarmConfProfile.adslAtucThreshInterleaveRateDown!=0){ + ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 1 Index 0"); +#endif + } + else{ + temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + if((AlarmConfProfile.adslAtucThreshInterleaveRateUp!=0) && (temp>=PrevTxRate.adslAtucChanPrevTxRate+AlarmConfProfile.adslAtucThreshInterleaveRateUp)){ + trapsflag|=ATUC_RATE_CHANGE_FLAG; + PrevTxRate.adslAtucChanPrevTxRate = temp; + } + if((AlarmConfProfile.adslAtucThreshInterleaveRateDown!=0) && (temp<=PrevTxRate.adslAtucChanPrevTxRate-AlarmConfProfile.adslAtucThreshInterleaveRateDown)){ + trapsflag|=ATUC_RATE_CHANGE_FLAG; + PrevTxRate.adslAtucChanPrevTxRate = temp; + } + } + } + } + if(AlarmConfProfile.adslAturThresh15MinLofs!=0 && current_intvl->AturPerfLof>=AlarmConfProfile.adslAturThresh15MinLofs) + trapsflag|=ATUR_PERF_LOFS_THRESH_FLAG; + if(AlarmConfProfile.adslAturThresh15MinLoss!=0 && current_intvl->AturPerfLos>=AlarmConfProfile.adslAturThresh15MinLoss) + trapsflag|=ATUR_PERF_LOSS_THRESH_FLAG; + if(AlarmConfProfile.adslAturThresh15MinLprs!=0 && current_intvl->AturPerfLpr>=AlarmConfProfile.adslAturThresh15MinLprs) + trapsflag|=ATUR_PERF_LPRS_THRESH_FLAG; + if(AlarmConfProfile.adslAturThresh15MinESs!=0 && current_intvl->AturPerfEs>=AlarmConfProfile.adslAturThresh15MinESs) + trapsflag|=ATUR_PERF_ESS_THRESH_FLAG; + if(chantype.fast==1){ + if(AlarmConfProfile.adslAturThreshFastRateUp!=0 || AlarmConfProfile.adslAturThreshFastRateDown!=0){ + ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 0 Index 0"); +#endif + } + else{ + temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + if((AlarmConfProfile.adslAturThreshFastRateUp!=0) && (temp>=PrevTxRate.adslAturChanPrevTxRate+AlarmConfProfile.adslAturThreshFastRateUp)){ + trapsflag|=ATUR_RATE_CHANGE_FLAG; + PrevTxRate.adslAturChanPrevTxRate = temp; + } + if((AlarmConfProfile.adslAturThreshFastRateDown!=0) && (temp<=PrevTxRate.adslAturChanPrevTxRate-AlarmConfProfile.adslAturThreshFastRateDown)){ + trapsflag|=ATUR_RATE_CHANGE_FLAG; + PrevTxRate.adslAturChanPrevTxRate = temp; + } + } + } + } + if(chantype.interleave==1){ + if(AlarmConfProfile.adslAturThreshInterleaveRateUp!=0 || AlarmConfProfile.adslAturThreshInterleaveRateDown!=0){ + ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 0 Index 0"); +#endif + } + else{ + temp = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + if((AlarmConfProfile.adslAturThreshInterleaveRateUp!=0) && (temp>=PrevTxRate.adslAturChanPrevTxRate+AlarmConfProfile.adslAturThreshInterleaveRateUp)){ + trapsflag|=ATUR_RATE_CHANGE_FLAG; + PrevTxRate.adslAturChanPrevTxRate = temp; + } + if((AlarmConfProfile.adslAturThreshInterleaveRateDown!=0) && (temp<=PrevTxRate.adslAturChanPrevTxRate-AlarmConfProfile.adslAturThreshInterleaveRateDown)){ + trapsflag|=ATUR_RATE_CHANGE_FLAG; + PrevTxRate.adslAturChanPrevTxRate = temp; + } + } + } + } + copy_to_user((char *)lon, (char *)(&trapsflag), 2); + + up(&mei_sema); + break; + +#ifdef AMAZON_MEI_MIB_RFC3440 + case ADSL_ATUR_EXT_TRAPS: + trapsflag=0; + if(AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR!=0 && current_intvl->AtucPerfStatFailedFastR>=AlarmConfProfileExt.adslAtucThreshold15MinFailedFastR) + trapsflag|=ATUC_15MIN_FAILED_FASTR_TRAP_FLAG; + if(AlarmConfProfileExt.adslAtucThreshold15MinSesL!=0 && current_intvl->AtucPerfStatSesL>=AlarmConfProfileExt.adslAtucThreshold15MinSesL) + trapsflag|=ATUC_15MIN_SESL_TRAP_FLAG; + if(AlarmConfProfileExt.adslAtucThreshold15MinUasL!=0 && current_intvl->AtucPerfStatUasL>=AlarmConfProfileExt.adslAtucThreshold15MinUasL) + trapsflag|=ATUC_15MIN_UASL_TRAP_FLAG; + if(AlarmConfProfileExt.adslAturThreshold15MinSesL!=0 && current_intvl->AturPerfStatSesL>=AlarmConfProfileExt.adslAturThreshold15MinSesL) + trapsflag|=ATUR_15MIN_SESL_TRAP_FLAG; + if(AlarmConfProfileExt.adslAturThreshold15MinUasL!=0 && current_intvl->AturPerfStatUasL>=AlarmConfProfileExt.adslAturThreshold15MinUasL) + trapsflag|=ATUR_15MIN_UASL_TRAP_FLAG; + copy_to_user((char *)lon, (char *)(&trapsflag), 2); + break; +#endif + +// 603221:tc.chen start + case GET_ADSL_LINE_STATUS: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslLineStatusInfo_pt = (adslLineStatusInfo *)kmalloc(sizeof(adslLineStatusInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslLineStatusInfo_pt, (char *)lon, sizeof(adslLineStatusInfo)); + + if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_MODEM_STATUS_FLAG)){ + LINE_STAT_MODEM_STATUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 0 Index 0"); +#endif + pts.adslLineStatusInfo_pt->adslModemStatus = 0; + } + else{ + pts.adslLineStatusInfo_pt->adslModemStatus = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_MODE_SEL_FLAG)){ + LINE_STAT_MODE_SEL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 1 Index 0"); +#endif + pts.adslLineStatusInfo_pt->adslModeSelected = 0; + } + else{ + pts.adslLineStatusInfo_pt->adslModeSelected = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_TRELLCOD_ENABLE_FLAG)){ + LINE_STAT_TRELLCOD_ENABLE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group OPTN Address 2 Index 0"); +#endif + pts.adslLineStatusInfo_pt->adslTrellisCodeEnable = 0; + } + else{ + + pts.adslLineStatusInfo_pt->adslTrellisCodeEnable = (RxMessage[4]>>13)&0x1==0x1?0:1; + } + } + + if(IS_FLAG_SET((&(pts.adslLineStatusInfo_pt->flags)), LINE_STAT_LATENCY_FLAG)){ + LINE_STAT_LATENCY_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 12 Index 0"); +#endif + pts.adslLineStatusInfo_pt->adslLatency = 0; + } + else{ + pts.adslLineStatusInfo_pt->adslLatency = RxMessage[4]; + } + } + + copy_to_user((char *)lon, (char *)pts.adslLineStatusInfo_pt, sizeof(adslLineStatusInfo)); + kfree(pts.adslLineStatusInfo_pt); + + up(&mei_sema); + break; + + + case GET_ADSL_LINE_RATE: + if (showtime!=1) + return -ERESTARTSYS; + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslLineRateInfo_pt = (adslLineRateInfo *)kmalloc(sizeof(adslLineRateInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslLineRateInfo_pt, (char *)lon, sizeof(adslLineRateInfo)); + + if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_DATA_RATEDS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + if (chantype.interleave) + LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP0_MAKECMV; + else + LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP1_MAKECMV; + + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group RATE Address 1 Index 0"); +#endif + pts.adslLineRateInfo_pt->adslDataRateds = 0; + } + else{ + pts.adslLineRateInfo_pt->adslDataRateds = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + }else // adsl 2/2+ + { + unsigned long Mp,Lp,Tp,Rp,Kp,Bpn,DataRate,DataRate_remain; + Mp=Lp=Tp=Rp=Kp=Bpn=DataRate=DataRate_remain=0; + //// up stream data rate + + if (chantype.interleave) + { + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 25 Index 0"); +#endif + Lp = 0; + }else + Lp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 23 Index 0"); +#endif + Rp = 0; + }else + Rp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 24 Index 0"); +#endif + Mp = 0; + }else + Mp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 26 Index 0"); +#endif + Tp = 0; + }else + Tp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 28 Index 0"); +#endif + Kp = 0; + }else + { + Kp=RxMessage[4]+ RxMessage[5]+1; + Bpn=RxMessage[4]+ RxMessage[5]; + } + }else + { + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 25 Index 1"); +#endif + Lp = 0; + }else + Lp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 23 Index 1"); +#endif + Rp = 0; + }else + Rp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 24 Index 1"); +#endif + Mp = 0; + }else + Mp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 26 Index 1"); +#endif + Tp = 0; + }else + Tp=RxMessage[4]; + + LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 28 Index 2"); +#endif + Kp = 0; + }else + { + Kp=RxMessage[4]+ RxMessage[5]+1; + Bpn=RxMessage[4]+ RxMessage[5]; + } + } + DataRate=((Tp*(Bpn+1)-1)*Mp*Lp*4)/(Tp*(Kp*Mp+Rp)); + //DataRate_remain=((((Tp*(Bpn+1)-1)*Mp*Lp*4)%(Tp*(Kp*Mp+Rp)))*1000)/(Tp*(Kp*Mp+Rp)); + //pts.adslLineRateInfo_pt->adslDataRateds = DataRate * 1000 + DataRate_remain; + pts.adslLineRateInfo_pt->adslDataRateds = DataRate; + } + } + + if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_DATA_RATEUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + if (chantype.interleave) + LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP0_MAKECMV; + else + LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP1_MAKECMV; + + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ + #ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group RATE Address 0 Index 0"); + #endif + pts.adslLineRateInfo_pt->adslDataRateus = 0; + } + else{ + pts.adslLineRateInfo_pt->adslDataRateus = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + }else // adsl 2/2+ + { + unsigned long Mp,Lp,Tp,Rp,Kp,Bpn,DataRate,DataRate_remain; + Mp=Lp=Tp=Rp=Kp=Bpn=DataRate=DataRate_remain=0; + //// down stream data rate + + if (chantype.interleave) + { + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 14 Index 0"); +#endif + Lp = 0; + }else + Lp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 12 Index 0"); +#endif + Rp = 0; + }else + Rp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 13 Index 0"); +#endif + Mp = 0; + }else + Mp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 15 Index 0"); +#endif + Tp = 0; + }else + Tp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP0_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 17 Index 0"); +#endif + Kp = 0; + }else + { + Kp=RxMessage[4]+ RxMessage[5]+1; + Bpn=RxMessage[4]+ RxMessage[5]; + } + }else + { + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 14 Index 1"); +#endif + Lp = 0; + }else + Lp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 12 Index 1"); +#endif + Rp = 0; + }else + Rp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 13 Index 1"); +#endif + Mp = 0; + }else + Mp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 15 Index 1"); +#endif + Tp = 0; + }else + Tp=RxMessage[4]; + + LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 17 Index 2"); +#endif + Kp = 0; + }else + { + Kp=RxMessage[4]+ RxMessage[5]+1; + Bpn=RxMessage[4]+ RxMessage[5]; + } + } + DataRate=((Tp*(Bpn+1)-1)*Mp*Lp*4)/(Tp*(Kp*Mp+Rp)); + //DataRate_remain=((((Tp*(Bpn+1)-1)*Mp*Lp*4)%(Tp*(Kp*Mp+Rp)))*1000)/(Tp*(Kp*Mp+Rp)); + //pts.adslLineRateInfo_pt->adslDataRateus = DataRate * 1000 + DataRate_remain; + pts.adslLineRateInfo_pt->adslDataRateus = DataRate; + } + } + + if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_ATTNDRDS_FLAG)){ + LINE_RATE_ATTNDRDS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 68 Index 4"); +#endif + pts.adslLineRateInfo_pt->adslATTNDRds = 0; + } + else{ + pts.adslLineRateInfo_pt->adslATTNDRds = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + + if(IS_FLAG_SET((&(pts.adslLineRateInfo_pt->flags)), LINE_RATE_ATTNDRUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + LINE_RATE_ATTNDRUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ + #ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 69 Index 4"); + #endif + pts.adslLineRateInfo_pt->adslATTNDRus = 0; + } + else{ + pts.adslLineRateInfo_pt->adslATTNDRus = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x24; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_RATE_END; + } + pts.adslLineRateInfo_pt->adslATTNDRus = (u32)le16_to_cpu(hdlc_rx_buffer[1])<<16 | (u32)le16_to_cpu(hdlc_rx_buffer[2]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_RATE_END; + } + } + } + copy_to_user((char *)lon, (char *)pts.adslLineRateInfo_pt, sizeof(adslLineRateInfo)); + up(&mei_sema); + +GET_ADSL_LINE_RATE_END: + kfree(pts.adslLineRateInfo_pt); + break; + + case GET_ADSL_LINE_INFO: + if (showtime!=1) + return -ERESTARTSYS; + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslLineInfo_pt = (adslLineInfo *)kmalloc(sizeof(adslLineInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslLineInfo_pt, (char *)lon, sizeof(adslLineInfo)); + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_INTLV_DEPTHDS_FLAG)){ + if (chantype.interleave) + LINE_INFO_INTLV_DEPTHDS_FLAG_LP0_MAKECMV; + else + LINE_INFO_INTLV_DEPTHDS_FLAG_LP1_MAKECMV; + + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 27 Index 0"); +#endif + pts.adslLineInfo_pt->adslInterleaveDepthds = 0; + } + else{ + pts.adslLineInfo_pt->adslInterleaveDepthds = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_INTLV_DEPTHUS_FLAG)){ + if (chantype.interleave) + LINE_INFO_INTLV_DEPTHUS_FLAG_LP0_MAKECMV; + else + LINE_INFO_INTLV_DEPTHUS_FLAG_LP1_MAKECMV; + + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group CNFG Address 16 Index 0"); +#endif + pts.adslLineInfo_pt->adslInterleaveDepthus = 0; + } + else{ + pts.adslLineInfo_pt->adslInterleaveDepthus = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_LATNDS_FLAG)){ + LINE_INFO_LATNDS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 68 Index 1"); +#endif + pts.adslLineInfo_pt->adslLATNds = 0; + } + else{ + pts.adslLineInfo_pt->adslLATNds = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_LATNUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + LINE_INFO_LATNUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 69 Index 1"); +#endif + pts.adslLineInfo_pt->adslLATNus = 0; + } + else{ + pts.adslLineInfo_pt->adslLATNus = RxMessage[4]; + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x21; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + pts.adslLineInfo_pt->adslLATNus = le16_to_cpu(hdlc_rx_buffer[1]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SATNDS_FLAG)){ + LINE_INFO_SATNDS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 68 Index 2"); +#endif + pts.adslLineInfo_pt->adslSATNds = 0; + } + else{ + pts.adslLineInfo_pt->adslSATNds = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SATNUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + LINE_INFO_SATNUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 69 Index 2"); +#endif + pts.adslLineInfo_pt->adslSATNus = 0; + } + else{ + pts.adslLineInfo_pt->adslSATNus = RxMessage[4]; + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x22; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + pts.adslLineInfo_pt->adslSATNus = le16_to_cpu(hdlc_rx_buffer[1]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SNRMNDS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend==0) // adsl mode + { + LINE_INFO_SNRMNDS_FLAG_ADSL1_MAKECMV; + } + else if ((adsl_mode == 0x4000) || (adsl_mode == 0x8000) || adsl_mode_extend > 0) + { + LINE_INFO_SNRMNDS_FLAG_ADSL2PLUS_MAKECMV; + } + else + { + LINE_INFO_SNRMNDS_FLAG_ADSL2_MAKECMV; + } + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 68 Index 3"); +#endif + pts.adslLineInfo_pt->adslSNRMds = 0; + } + else{ + if (adsl_mode>8 || adsl_mode_extend>0) + { + int SNRMds,SNRMds_remain; + SNRMds=RxMessage[4]; + SNRMds_remain=((SNRMds&0xff)*1000)/256; + SNRMds=(SNRMds>>8)&0xff; + if ((SNRMds_remain%100)>=50) SNRMds_remain=(SNRMds_remain/100)+1; + else SNRMds_remain=(SNRMds_remain/100); + pts.adslLineInfo_pt->adslSNRMds = SNRMds*10 + SNRMds_remain; + }else + { + pts.adslLineInfo_pt->adslSNRMds = RxMessage[4]; + } + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_SNRMNUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend == 0) + { + LINE_INFO_SNRMNUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 69 Index 3"); +#endif + pts.adslLineInfo_pt->adslSNRMus = 0; + } + else{ + pts.adslLineInfo_pt->adslSNRMus = RxMessage[4]; + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x23; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + pts.adslLineInfo_pt->adslSNRMus = le16_to_cpu(hdlc_rx_buffer[1]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_ACATPDS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend == 0) + { + LINE_INFO_ACATPDS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ + #ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 68 Index 6"); + #endif + pts.adslLineInfo_pt->adslACATPds = 0; + } + else{ + pts.adslLineInfo_pt->adslACATPds = RxMessage[4]; + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x25; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + pts.adslLineInfo_pt->adslACATPds = le16_to_cpu(hdlc_rx_buffer[1]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + } + } + + if(IS_FLAG_SET((&(pts.adslLineInfo_pt->flags)), LINE_INFO_ACATPUS_FLAG)){ + if (adsl_mode <=8 && adsl_mode_extend == 0) + { + LINE_INFO_ACATPUS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 69 Index 6"); +#endif + pts.adslLineInfo_pt->adslACATPus = 0; + } + else{ + pts.adslLineInfo_pt->adslACATPus = RxMessage[4]; + } + }else + { + hdlc_cmd[0]=0x0181; + hdlc_cmd[1]=0x26; + up(&mei_sema); + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],4)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + pts.adslLineInfo_pt->adslACATPus = le16_to_cpu(hdlc_rx_buffer[1]); + } + if(down_interruptible(&mei_sema)) + { + meierr = -ERESTARTSYS; + goto GET_ADSL_LINE_INFO_END; + } + } + } + + copy_to_user((char *)lon, (char *)pts.adslLineInfo_pt, sizeof(adslLineInfo)); + up(&mei_sema); + +GET_ADSL_LINE_INFO_END: + kfree(pts.adslLineInfo_pt); + break; + + case GET_ADSL_NEAREND_STATS: + if (showtime!=1) + return -ERESTARTSYS; + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslNearEndPerfStats_pt = (adslNearEndPerfStats *)kmalloc(sizeof(adslNearEndPerfStats), GFP_KERNEL); + copy_from_user((char *)pts.adslNearEndPerfStats_pt, (char *)lon, sizeof(adslNearEndPerfStats)); + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_SUPERFRAME_FLAG)){ + NEAREND_PERF_SUPERFRAME_FLAG_LSW_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 20 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslSuperFrames = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslSuperFrames = (u32)(RxMessage[4]); + } + NEAREND_PERF_SUPERFRAME_FLAG_MSW_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 21 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslSuperFrames = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslSuperFrames += (((u32)(RxMessage[4]))<<16); + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOS_FLAG) || + IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOF_FLAG) || + IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LPR_FLAG) || + IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_NCD_FLAG) || + IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LCD_FLAG) ){ + NEAREND_PERF_LOS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 0 Index 0"); +#endif + RxMessage[4] = 0; + } + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOS_FLAG)){ + if( (RxMessage[4]&0x1) == 0x1) + pts.adslNearEndPerfStats_pt->adslneLOS = 1; + else + pts.adslNearEndPerfStats_pt->adslneLOS = 0; + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOF_FLAG)){ + if( (RxMessage[4]&0x2) == 0x2) + pts.adslNearEndPerfStats_pt->adslneLOF = 1; + else + pts.adslNearEndPerfStats_pt->adslneLOF = 0; + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LPR_FLAG)){ + if( (RxMessage[4]&0x4) == 0x4) + pts.adslNearEndPerfStats_pt->adslneLPR = 1; + else + pts.adslNearEndPerfStats_pt->adslneLPR = 0; + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_NCD_FLAG)){ + pts.adslNearEndPerfStats_pt->adslneNCD = (RxMessage[4]>>4)&0x3; + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LCD_FLAG)){ + pts.adslNearEndPerfStats_pt->adslneLCD = (RxMessage[4]>>6)&0x3; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_CRC_FLAG)){ + if (chantype.interleave) + NEAREND_PERF_CRC_FLAG_LP0_MAKECMV; + else + NEAREND_PERF_CRC_FLAG_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 2 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneCRC = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneCRC = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_RSCORR_FLAG)){ + if (chantype.interleave) + NEAREND_PERF_RSCORR_FLAG_LP0_MAKECMV; + else + NEAREND_PERF_RSCORR_FLAG_LP1_MAKECMV; + + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 3 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneRSCorr = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneRSCorr = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_FECS_FLAG)){ + NEAREND_PERF_FECS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 6 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneFECS = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneFECS = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_ES_FLAG)){ + NEAREND_PERF_ES_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 7 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneES = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneES = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_SES_FLAG)){ + NEAREND_PERF_SES_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 8 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneSES = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneSES = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_LOSS_FLAG)){ + NEAREND_PERF_LOSS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 9 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneLOSS = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneLOSS = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_UAS_FLAG)){ + NEAREND_PERF_UAS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 10 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneUAS = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneUAS = RxMessage[4]; + } + } + + if(IS_FLAG_SET((&(pts.adslNearEndPerfStats_pt->flags)), NEAREND_PERF_HECERR_FLAG)){ + if (chantype.bearchannel0) + { + NEAREND_PERF_HECERR_FLAG_BC0_MAKECMV; + }else if (chantype.bearchannel1) + { + NEAREND_PERF_HECERR_FLAG_BC1_MAKECMV; + } + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 11 Index 0"); +#endif + pts.adslNearEndPerfStats_pt->adslneHECErrors = 0; + } + else{ + pts.adslNearEndPerfStats_pt->adslneHECErrors = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + + copy_to_user((char *)lon, (char *)pts.adslNearEndPerfStats_pt, sizeof(adslNearEndPerfStats)); + kfree(pts.adslNearEndPerfStats_pt); + + up(&mei_sema); + break; + + case GET_ADSL_FAREND_STATS: + + if (showtime!=1) + return -ERESTARTSYS; + + if (adsl_mode>8 || adsl_mode_extend > 0) + { + do_gettimeofday(&time_now); + if( FarendData_acquire_time.tv_sec==0 || time_now.tv_sec - FarendData_acquire_time.tv_sec>=1) + { + hdlc_cmd[0]=0x105; + + if (ifx_me_hdlc_send((unsigned char *)&hdlc_cmd[0],2)!= -EBUSY) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1); + hdlc_rx_len=0; + hdlc_rx_len = ifx_mei_hdlc_read(&hdlc_rx_buffer,32*2); + if (hdlc_rx_len <=0) + { + return -ERESTARTSYS; + } + FarendStatsData.adslfeRSCorr = ((u32)le16_to_cpu(hdlc_rx_buffer[1]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[2]); + FarendStatsData.adslfeCRC = ((u32)le16_to_cpu(hdlc_rx_buffer[3]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[4]); + FarendStatsData.adslfeFECS = ((u32)le16_to_cpu(hdlc_rx_buffer[5]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[6]); + FarendStatsData.adslfeES = ((u32)le16_to_cpu(hdlc_rx_buffer[7]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[8]); + FarendStatsData.adslfeSES = ((u32)le16_to_cpu(hdlc_rx_buffer[9]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[10]); + FarendStatsData.adslfeLOSS = ((u32)le16_to_cpu(hdlc_rx_buffer[11]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[12]); + FarendStatsData.adslfeUAS = ((u32)le16_to_cpu(hdlc_rx_buffer[13]) << 16) + (u32)le16_to_cpu(hdlc_rx_buffer[14]); + do_gettimeofday(&FarendData_acquire_time); + } + + } + } + + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + pts.adslFarEndPerfStats_pt = (adslFarEndPerfStats *)kmalloc(sizeof(adslFarEndPerfStats), GFP_KERNEL); + copy_from_user((char *)pts.adslFarEndPerfStats_pt, (char *)lon, sizeof(adslFarEndPerfStats)); + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOS_FLAG) || + IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOF_FLAG) || + IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LPR_FLAG) || + IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_NCD_FLAG) || + IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LCD_FLAG) ){ + FAREND_PERF_LOS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 1 Index 0"); +#endif + RxMessage[4] = 0; + } + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOS_FLAG)){ + if((RxMessage[4]&0x1) == 0x1) + pts.adslFarEndPerfStats_pt->adslfeLOS = 1; + else + pts.adslFarEndPerfStats_pt->adslfeLOS = 0; + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOF_FLAG)){ + if((RxMessage[4]&0x2) == 0x2) + pts.adslFarEndPerfStats_pt->adslfeLOF = 1; + else + pts.adslFarEndPerfStats_pt->adslfeLOF = 0; + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LPR_FLAG)){ + if((RxMessage[4]&0x4) == 0x4) + pts.adslFarEndPerfStats_pt->adslfeLPR = 1; + else + pts.adslFarEndPerfStats_pt->adslfeLPR = 0; + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_NCD_FLAG)){ + pts.adslFarEndPerfStats_pt->adslfeNCD = (RxMessage[4]>>4)&0x3; + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LCD_FLAG)){ + pts.adslFarEndPerfStats_pt->adslfeLCD = (RxMessage[4]>>6)&0x3; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_CRC_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + if (chantype.interleave) + { + FAREND_PERF_CRC_FLAG_LP0_MAKECMV; + } + else + { + FAREND_PERF_CRC_FLAG_LP1_MAKECMV; + } + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 24 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeCRC = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeCRC = RxMessage[4]; + } + }else + { + pts.adslFarEndPerfStats_pt->adslfeCRC = FarendStatsData.adslfeCRC; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_RSCORR_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + if (chantype.interleave) + FAREND_PERF_RSCORR_FLAG_LP0_MAKECMV; + else + FAREND_PERF_RSCORR_FLAG_LP1_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 28 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeRSCorr = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeRSCorr = RxMessage[4]; + + } + } + else + { + pts.adslFarEndPerfStats_pt->adslfeRSCorr = FarendStatsData.adslfeRSCorr; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_FECS_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + FAREND_PERF_FECS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 32 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeFECS = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeFECS = RxMessage[4]; + } + }else { + pts.adslFarEndPerfStats_pt->adslfeFECS = FarendStatsData.adslfeFECS; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_ES_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + FAREND_PERF_ES_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 33 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeES = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeES = RxMessage[4]; + } + }else + { + pts.adslFarEndPerfStats_pt->adslfeES = FarendStatsData.adslfeES; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_SES_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + FAREND_PERF_SES_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 34 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeSES = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeSES = RxMessage[4]; + + } + }else + { + pts.adslFarEndPerfStats_pt->adslfeSES = FarendStatsData.adslfeSES; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_LOSS_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + FAREND_PERF_LOSS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeLOSS = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeLOSS = RxMessage[4]; + + } + }else + { + pts.adslFarEndPerfStats_pt->adslfeLOSS = FarendStatsData.adslfeLOSS; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_UAS_FLAG)){ + if (adsl_mode<=8 && adsl_mode_extend == 0) + { + FAREND_PERF_UAS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 36 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeUAS = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeUAS = RxMessage[4]; + + } + }else + { + pts.adslFarEndPerfStats_pt->adslfeUAS = FarendStatsData.adslfeUAS; + } + } + + if(IS_FLAG_SET((&(pts.adslFarEndPerfStats_pt->flags)), FAREND_PERF_HECERR_FLAG)){ + if (chantype.bearchannel0) + { + FAREND_PERF_HECERR_FLAG_BC0_MAKECMV; + }else if (chantype.bearchannel1) + { + FAREND_PERF_HECERR_FLAG_BC1_MAKECMV; + } + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 37 Index 0"); +#endif + pts.adslFarEndPerfStats_pt->adslfeHECErrors = 0; + } + else{ + pts.adslFarEndPerfStats_pt->adslfeHECErrors = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + } + + copy_to_user((char *)lon, (char *)pts.adslFarEndPerfStats_pt, sizeof(adslFarEndPerfStats)); + kfree(pts.adslFarEndPerfStats_pt); + + up(&mei_sema); + + break; +// 603221:tc.chen end + case GET_ADSL_LOOP_DIAGNOSTICS_MODE: + //lon = loop_diagnostics_mode; + copy_to_user((char *)lon, (char *)&loop_diagnostics_mode, sizeof(int)); + break; +//>> SHC + case IS_ADSL_LOOP_DIAGNOSTICS_MODE_COMPLETE: + copy_to_user((char *)lon, (char *)&loop_diagnostics_completed, sizeof(int)); + break; + +//<< end SHC + case LOOP_DIAGNOSTIC_MODE_COMPLETE: + loop_diagnostics_completed = 1; + // read adsl mode + makeCMV(H2D_CMV_READ, STAT, 1, 0, 1, data); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 1 Index 0"); +#endif + } + adsl_mode = RxMessage[4]; + + makeCMV(H2D_CMV_READ, STAT, 17, 0, 1, data); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 1 Index 0"); +#endif + } + adsl_mode_extend = RxMessage[4]; + wake_up_interruptible(&wait_queue_loop_diagnostic); + break; + case SET_ADSL_LOOP_DIAGNOSTICS_MODE: + if (lon != loop_diagnostics_mode) + { + loop_diagnostics_completed = 0; + loop_diagnostics_mode = lon; + + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_REBOOT, NULL); + + } + break; + case GET_ADSL_ATUR_SUBCARRIER_STATS: + if (loop_diagnostics_completed == 0) + { + interruptible_sleep_on_timeout(&wait_queue_loop_diagnostic,300*HZ); + if (loop_diagnostics_completed==0) + { + return -ERESTARTSYS; + } + } + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + pts.adslATURSubcarrierInfo_pt = (adslATURSubcarrierInfo *)kmalloc(sizeof(adslATURSubcarrierInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslATURSubcarrierInfo_pt, (char *)lon, sizeof(adslATURSubcarrierInfo)); + + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_HLINSC)){ + FAREND_HLINSC_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + pts.adslATURSubcarrierInfo_pt->HLINSCds = 0; + } + else{ + pts.adslATURSubcarrierInfo_pt->HLINSCds = RxMessage[4]; + + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_HLINPS)){ + int index=0,size=12; + //printk("FAREND_HLINPS\n"); + for (index=0;index<1024;index+=size) + { + if (index+size>=1024) + size = 1024-index; + FAREND_HLINPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + memcpy(&pts.adslATURSubcarrierInfo_pt->HLINpsds[index],&RxMessage[4],size*2); +#if 0 + int msg_idx; + for(msg_idx=0;msg_idx<size;msg_idx++) + printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); +#endif + } + } + } + + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_HLOGMT)){ + FAREND_HLOGMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + pts.adslATURSubcarrierInfo_pt->HLOGMTds = 0; + } + else{ + pts.adslATURSubcarrierInfo_pt->HLOGMTds = RxMessage[4]; + + } + } + + ///////////////////////////////////////////////////////////////////////// + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_HLOGPS)){ + //printk("FAREND_HLOGPS\n"); + int index=0,size=12; + for (index=0;index<256;index+=size) + { + if (index+size>=256) + size = 256-index; + + FAREND_HLOGPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + if (adsl_mode < 0x4000 && adsl_mode_extend==0)//adsl2 mode + { + memcpy(&pts.adslATURSubcarrierInfo_pt->HLOGpsds[index],&RxMessage[4],size*2); + }else + { + int msg_idx=0; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + pts.adslATURSubcarrierInfo_pt->HLOGpsds[(index+msg_idx)*2+1] = RxMessage[4+msg_idx]; + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + } + } + } + if (adsl_mode >= 0x4000 || adsl_mode_extend >0)//adsl2+ mode + { + pts.adslATURSubcarrierInfo_pt->HLOGpsds[0] = pts.adslATURSubcarrierInfo_pt->HLOGpsds[1]; + for (index=1;index<256;index++) + { + pts.adslATURSubcarrierInfo_pt->HLOGpsds[index*2] = (pts.adslATURSubcarrierInfo_pt->HLOGpsds[(index)*2-1] + pts.adslATURSubcarrierInfo_pt->HLOGpsds[(index)*2+1] +1) >>1; + } + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_QLNMT)){ + FAREND_QLNMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + pts.adslATURSubcarrierInfo_pt->QLNMTds = 0; + } + else{ + pts.adslATURSubcarrierInfo_pt->QLNMTds = RxMessage[4]; + } + } + + ///////////////////////////////////////////////////////////////////////// + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_QLNPS)){ + int index=0,size=12; + //printk("FAREND_QLNPS\n"); + for (index=0;index<128;index+=size) + { + if (index+size>=128) + size = 128-index; + FAREND_QLNPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + int msg_idx=0; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + //memcpy(&pts.adslATURSubcarrierInfo_pt->QLNpsds[index],&RxMessage[4],size*2); + if (adsl_mode < 0x4000 && adsl_mode_extend==0)//adsl2 mode + { + pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + }else + { + pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*4+1] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATURSubcarrierInfo_pt->QLNpsds[(index+msg_idx)*4+3] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + } + + + } + } + if (adsl_mode >= 0x4000 || adsl_mode_extend >0)//adsl2+ mode + { + pts.adslATURSubcarrierInfo_pt->QLNpsds[0] = pts.adslATURSubcarrierInfo_pt->QLNpsds[1]; + for (index=1;index<256;index++) + { + pts.adslATURSubcarrierInfo_pt->QLNpsds[index*2] = (pts.adslATURSubcarrierInfo_pt->QLNpsds[(index)*2-1] + pts.adslATURSubcarrierInfo_pt->QLNpsds[(index)*2+1]) >>1; + } + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_SNRMT)){ + FAREND_SNRMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + pts.adslATURSubcarrierInfo_pt->SNRMTds = 0; + } + else{ + pts.adslATURSubcarrierInfo_pt->SNRMTds = RxMessage[4]; + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_SNRPS)){ + int index=0,size=12; + //printk("FAREND_SNRPS\n"); + for (index=0;index<512;index+=size) + { + if (index+size>=512) + size = 512-index; + FAREND_SNRPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + //memcpy(&pts.adslATURSubcarrierInfo_pt->SNRpsds[index],&RxMessage[4],size*2); + int msg_idx=0; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + pts.adslATURSubcarrierInfo_pt->SNRpsds[index+msg_idx] = (u16)(RxMessage[4+msg_idx]&0xFF); + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + + } + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_BITPS)){ + int index=0,size=12; + //printk("FAREND_BITPS\n"); + for (index=0;index<256;index+=size) + { + if (index+size>=256) + size = 256-index; + FAREND_BITPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + int msg_idx=0; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + pts.adslATURSubcarrierInfo_pt->BITpsds[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATURSubcarrierInfo_pt->BITpsds[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + //printk("index:%d ,cmv_result: %04X, %d\n",index+msg_idx,RxMessage[4+msg_idx],RxMessage[4+msg_idx]); + + } + + } + } + } + if(IS_FLAG_SET((&(pts.adslATURSubcarrierInfo_pt->flags)), FAREND_GAINPS)){ + int index=0,size=12; + //printk("FAREND_GAINPS\n"); + for (index=0;index<512;index+=size) + { + FAREND_GAINPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + } + else{ + /* + int msg_idx=0; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + pts.adslATURSubcarrierInfo_pt->GAINpsds[(index+msg_idx)*2] = RxMessage[4+msg_idx]&0xFF; + pts.adslATURSubcarrierInfo_pt->GAINpsds[(index+msg_idx)*2+1] = (RxMessage[4+msg_idx]>>8)&0xFF; + + } + */ + memcpy(&pts.adslATURSubcarrierInfo_pt->GAINpsds[index],&RxMessage[4],size*2); +#if 0 + int msg_idx=0; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + + } +#endif + } + } + } + copy_to_user((char *)lon, (char *)pts.adslATURSubcarrierInfo_pt, sizeof(adslATURSubcarrierInfo)); + kfree(pts.adslATURSubcarrierInfo_pt); + + up(&mei_sema); + break; + case GET_ADSL_ATUC_SUBCARRIER_STATS: + if (loop_diagnostics_completed == 0) + { + interruptible_sleep_on_timeout(&wait_queue_loop_diagnostic,300*HZ); + if (loop_diagnostics_completed==0) + { + return -ERESTARTSYS; + } + } + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + pts.adslATUCSubcarrierInfo_pt = (adslATUCSubcarrierInfo *)kmalloc(sizeof(adslATUCSubcarrierInfo), GFP_KERNEL); + copy_from_user((char *)pts.adslATUCSubcarrierInfo_pt, (char *)lon, sizeof(adslATUCSubcarrierInfo)); + + + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_HLINSC)){ + NEAREND_HLINSC_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 71 Index 2"); +#endif + pts.adslATUCSubcarrierInfo_pt->HLINSCus = 0; + } + else{ + pts.adslATUCSubcarrierInfo_pt->HLINSCus = RxMessage[4]; + + } + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_HLINPS)){ + int index=0,size=12; + //printk("NEAREND_HLINPS\n"); + for (index=0;index<128;index+=size) + { + if (index+size>=128) + size = 128-index; + NEAREND_HLINPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 73 Index 0"); +#endif + } + else{ + memcpy(&pts.adslATUCSubcarrierInfo_pt->HLINpsus[index],&RxMessage[4],size*2); +#if 0 + int msg_idx; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } +#endif + } + } + } + + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_HLOGMT)){ + NEAREND_HLOGMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 80 Index 0"); +#endif + pts.adslATUCSubcarrierInfo_pt->HLOGMTus = 0; + } + else{ + pts.adslATUCSubcarrierInfo_pt->HLOGMTus = RxMessage[4]; + + } + } + + ///////////////////////////////////////////////////////////////////////// + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_HLOGPS)){ + int index=0,size=12; + //printk("NEAREND_HLOGPS\n"); + for (index=0;index<64;index+=size) + { + if (index+size>=64) + size = 64-index; + NEAREND_HLOGPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 75 Index 0"); +#endif + } + else{ +#if 0 + if (adsl_mode <0x4000)//adsl /adsl2 mode + { +#endif + memcpy(&pts.adslATUCSubcarrierInfo_pt->HLOGpsus[index],&RxMessage[4],size*2); +#if 0 + }else + { + int msg_idx=0; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + //pts.adslATUCSubcarrierInfo_pt->HLOGpsus[(index+msg_idx)*2+1] = RxMessage[4+msg_idx]; + pts.adslATUCSubcarrierInfo_pt->HLOGpsus[(index+msg_idx)] = RxMessage[4+msg_idx]; + } + } +#endif + } + } +#if 0 + if (adsl_mode >= 0x4000)//adsl2 mode + { + pts.adslATUCSubcarrierInfo_pt->HLOGpsus[0] = pts.adslATUCSubcarrierInfo_pt->HLOGpsus[1]; + for (index=1;index<64;index++) + { + pts.adslATUCSubcarrierInfo_pt->HLOGpsus[index*2] = (pts.adslATUCSubcarrierInfo_pt->HLOGpsus[(index)*2-1] + pts.adslATUCSubcarrierInfo_pt->HLOGpsus[(index)*2+1]) >>1; + } + } +#endif + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_QLNMT)){ + NEAREND_QLNMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 80 Index 1"); +#endif + pts.adslATUCSubcarrierInfo_pt->QLNMTus = 0; + } + else{ + pts.adslATUCSubcarrierInfo_pt->QLNMTus = RxMessage[4]; + } + } + + ///////////////////////////////////////////////////////////////////////// + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_QLNPS)){ + int index=0,size=12; + //printk("NEAREND_QLNPS\n"); + for (index=0;index<32;index+=size) + { + if (index+size>=32) + size = 32-index; + NEAREND_QLNPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 77 Index 0"); +#endif + } + else{ + int msg_idx=0; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + +#if 0 + //memcpy(&pts.adslATUCSubcarrierInfo_pt->QLNpsds[index],&RxMessage[4],size*2); + if (adsl_mode == 0x200 || adsl_mode == 0x800 || adsl_mode ==0x2000 || adsl_mode ==0x4000 || (adsl_mode == 0 && (adsl_mode_extend == 0x4 || adsl_mode_extend == 0x2))//ADSL 2 Annex B(0x200)/J(0x800)/M(0x2000) //ADSL 2+ B,J,M + if (adsl_mode < 0x4000 && adsl_mode_extend==0)//adsl2 mode + { + pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*4+1] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*4+3] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + }else +#endif + { + pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + } + + + } + } +#if 0 + //if (adsl_mode <0x4000)//Annex I/J/L/M + if (adsl_mode == 0x200 || adsl_mode == 0x800 || adsl_mode ==0x2000 || adsl_mode ==0x4000 || (adsl_mode == 0 && (adsl_mode_extend == 0x4 || adsl_mode_extend == 0x2))//ADSL 2 Annex B(0x200)/J(0x800)/M(0x2000) //ADSL 2+ B,J,M + { + pts.adslATUCSubcarrierInfo_pt->QLNpsus[0] = pts.adslATUCSubcarrierInfo_pt->QLNpsus[1]; + for (index=1;index<64;index++) + { + pts.adslATUCSubcarrierInfo_pt->QLNpsus[index*2] = (pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index)*2-1] + pts.adslATUCSubcarrierInfo_pt->QLNpsus[(index)*2+1]) >>1; + } + } +#endif + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_SNRMT)){ + NEAREND_SNRMT_MAKECMV(H2D_CMV_READ); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 80 Index 2"); +#endif + pts.adslATUCSubcarrierInfo_pt->SNRMTus = 0; + } + else{ + pts.adslATUCSubcarrierInfo_pt->SNRMTus = RxMessage[4]; + } + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_SNRPS)){ + int index=0,size=12; + //printk("NEAREND_SNRPS\n"); + for (index=0;index<64;index+=size) + { + if (index+size>=64) + size = 64-index; + NEAREND_SNRPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 78 Index 0"); +#endif + } + else{ + //memcpy(&pts.adslATUCSubcarrierInfo_pt->SNRpsus[index],&RxMessage[4],size*2); + int msg_idx=0; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + pts.adslATUCSubcarrierInfo_pt->SNRpsus[index+msg_idx] = (u16)(RxMessage[4+msg_idx]&0xFF); + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + + } + } + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_BITPS)){ + int index=0,size=12; + //printk("NEAREND_BITPS\n"); + for (index=0;index<32;index+=size) + { + if (index+size>=32) + size = 32-index; + NEAREND_BITPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 22 Index 0"); +#endif + } + else{ + int msg_idx=0; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + pts.adslATUCSubcarrierInfo_pt->BITpsus[(index+msg_idx)*2] = (u16)(RxMessage[4+msg_idx]&0xFF); + pts.adslATUCSubcarrierInfo_pt->BITpsus[(index+msg_idx)*2+1] = (u16)((RxMessage[4+msg_idx]>>8)&0xFF); + //printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } + + } + } + } + if(IS_FLAG_SET((&(pts.adslATUCSubcarrierInfo_pt->flags)), NEAREND_GAINPS)){ + int index=0,size=12; + //printk("NEAREND_GAINPS\n"); + for (index=0;index<64;index+=size) + { + if (index+size>=64) + size = 64-index; + NEAREND_GAINPS_MAKECMV(H2D_CMV_READ,index,size); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group INFO Address 24 Index 0"); +#endif + } + else{ + /* + int msg_idx=0; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + pts.adslATUCSubcarrierInfo_pt->GAINpsds[(index+msg_idx)*2] = RxMessage[4+msg_idx]&0xFF; + pts.adslATUCSubcarrierInfo_pt->GAINpsds[(index+msg_idx)*2+1] = (RxMessage[4+msg_idx]>>8)&0xFF; + + } + */ + memcpy(&pts.adslATUCSubcarrierInfo_pt->GAINpsus[index],&RxMessage[4],size*2); +#if 0 + int msg_idx; + for (msg_idx=0;msg_idx<size;msg_idx++) + { + printk("index:%d ,cmv_result: %04X\n",index+msg_idx,RxMessage[4+msg_idx]); + } +#endif + } + } + } + copy_to_user((char *)lon, (char *)pts.adslATUCSubcarrierInfo_pt, sizeof(adslATUCSubcarrierInfo)); + kfree(pts.adslATUCSubcarrierInfo_pt); + up(&mei_sema); + break; + case GET_ADSL_LINE_INIT_STATS: + copy_to_user((char *)lon, (char *)&AdslInitStatsData, sizeof(AdslInitStatsData)); + break; + + case GET_ADSL_POWER_SPECTRAL_DENSITY: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + i=0; + pts.adslPowerSpectralDensity_pt = (adslPowerSpectralDensity *)kmalloc(sizeof(adslPowerSpectralDensity), GFP_KERNEL); + memset((char *)pts.adslPowerSpectralDensity_pt, 0, sizeof(adslPowerSpectralDensity)); + + //US + NOMPSD_US_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + i=-1; + } + else{ + j=RxMessage[4]; + } + PCB_US_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + i=-1; + } + else{ + temp=RxMessage[4]; + } + RMSGI_US_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + i=-1; + } + else{ + k=(int16_t)RxMessage[4]; + } + if (i==0) + { + pts.adslPowerSpectralDensity_pt->ACTPSDus = ((int )(j*256 - temp*10*256 + k*10)) /256; + } + // DS + i=0; + j=temp=temp2=0; + NOMPSD_DS_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + i=-1; + } + else{ + j=RxMessage[4]; + } + PCB_DS_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + i=-1; + } + else{ + temp=RxMessage[4]; + } + RMSGI_DS_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group PLAM Address 35 Index 0"); +#endif + i=-1; + } + else{ + //temp2=RxMessage[4]; + k=(int16_t)RxMessage[4]; + } + if (i==0) + { + pts.adslPowerSpectralDensity_pt->ACTPSDds = ((int )(j*256 - temp*10*256 + k*10)) /256; + } + copy_to_user((char *)lon, (char *)pts.adslPowerSpectralDensity_pt, sizeof(adslPowerSpectralDensity)); + kfree(pts.adslPowerSpectralDensity_pt); + up(&mei_sema); + break; + case AMAZON_MEI_START: + showtime=0; + loop_diagnostics_completed = 0; +#ifdef ARC_READY_ACK +#ifdef LOCK_RETRY + i=0; +lock_retry: + if(down_trylock(&mei_sema)!=0) + { + reboot_lock = 1; + printk("lock fail\n"); + i++; + if (i <=5) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(10); + goto lock_retry; + }else + { + printk("Force to Reboot ADSL!\n"); + up(&mei_sema); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(1000); + sema_init(&mei_sema, 1); // semaphore initialization, mutex + } + }else + { + reboot_lock = 1; + } +#else + if(down_interruptible(&mei_sema)) //disable CMV access until ARC ready + { + return -ERESTARTSYS; + } +#endif +#endif + //CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON + if(chantype.interleave==1){ + kfree(interleave_mei_net.priv); + unregister_netdev(&interleave_mei_net); + } + else if(chantype.fast==1){ + kfree(fast_mei_net.priv); + unregister_netdev(&fast_mei_net); + } + chantype.interleave=0; + chantype.fast=0; + meiMailboxInterruptsDisable(); //disable all MEI interrupts + if(mei_arc_swap_buff == NULL){ + mei_arc_swap_buff = (u32 *)kmalloc(MAXSWAPSIZE*4, GFP_KERNEL); + if(mei_arc_swap_buff==NULL){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n malloc fail for codeswap buff"); +#endif + meierr=MEI_FAILURE; + } + } + if(meiForceRebootAdslModem() != MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n meiForceRebootAdslModem() error..."); +#endif + meierr=MEI_FAILURE; + } + interruptible_sleep_on(&wait_queue_codeswap); + // reset is called + break; + case AMAZON_MEI_MIB_DAEMON: +#ifdef IFX_SMALL_FOOTPRINT /* [ */ + return -1; +#else /* ][ !IFX_SMALL_FOOTPRINT */ + i=0; + while(1){ + if(i<MIB_INTERVAL) + interruptible_sleep_on_timeout(&wait_queue_mibdaemon, ((MIB_INTERVAL-i)/(1000/HZ))); + i=0; + if(showtime==1){ +// printk("\n\n update mib"); + + do_gettimeofday(&time_now); + if(time_now.tv_sec - current_intvl->start_time.tv_sec>=900){ + if(current_intvl->list.next!=&interval_list){ + current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list); + do_gettimeofday(&(current_intvl->start_time)); + } + else{ + mib_ptr = list_entry(interval_list.next, amazon_mei_mib, list); + list_del(interval_list.next); + memset(mib_ptr, 0, sizeof(amazon_mei_mib)); + list_add_tail(&(mib_ptr->list), &interval_list); + if(current_intvl->list.next==&interval_list) +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nlink list error"); +#endif + current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list); + do_gettimeofday(&(current_intvl->start_time)); + } + } + + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; +/* + ATUC_PERF_LO_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 0 Index 0"); +#endif + } + else{ + if(RxMessage[4]&PLAM_LOS_FailureBit){ + current_intvl->AtucPerfLos++; + ATUC_PERF_LOSS++; + CurrStatus.adslAtucCurrStatus = 2; + } + if(RxMessage[4]&PLAM_LOF_FailureBit){ + current_intvl->AtucPerfLof++; + ATUC_PERF_LOFS++; + CurrStatus.adslAtucCurrStatus = 1; + } + if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit))) + CurrStatus.adslAtucCurrStatus = 0; + } +*/ + ATUC_PERF_ESS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 7 Index 0"); +#endif + } + else{ + temp = RxMessage[4]-mib_pread.ATUC_PERF_ESS; + if(temp>=0){ + current_intvl->AtucPerfEs+=temp; + ATUC_PERF_ESS+=temp; + mib_pread.ATUC_PERF_ESS = RxMessage[4]; + } + else{ + current_intvl->AtucPerfEs+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4]; + ATUC_PERF_ESS+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4]; + mib_pread.ATUC_PERF_ESS = RxMessage[4]; + } + } +/* + ATUR_PERF_LO_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 1 Index 0"); +#endif + } + else{ + if(RxMessage[4]&PLAM_LOS_FailureBit){ + current_intvl->AturPerfLos++; + ATUR_PERF_LOSS++; + CurrStatus.adslAturCurrStatus = 2; + } + if(RxMessage[4]&PLAM_LOF_FailureBit){ + current_intvl->AturPerfLof++; + ATUR_PERF_LOFS++; + CurrStatus.adslAturCurrStatus = 1; + } + if(RxMessage[4]&PLAM_LPR_FailureBit){ + current_intvl->AturPerfLpr++; + ATUR_PERF_LPR++; + CurrStatus.adslAturCurrStatus = 3; + } + if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit|PLAM_LPR_FailureBit))) + CurrStatus.adslAturCurrStatus = 0; + } +*/ + ATUR_PERF_ESS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 33 Index 0"); +#endif + } + else{ + temp = RxMessage[4]-mib_pread.ATUR_PERF_ESS; + if(temp>=0){ + current_intvl->AturPerfEs+=temp; + ATUR_PERF_ESS+=temp; + mib_pread.ATUR_PERF_ESS = RxMessage[4]; + } + else{ + current_intvl->AturPerfEs+=0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4]; + ATUR_PERF_ESS+= 0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4]; + mib_pread.ATUR_PERF_ESS=RxMessage[4]; + } + } + // to update rx/tx blocks + ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_LSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 20 Index 0"); +#endif + } + else{ + temp = RxMessage[4]; + } + ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_MSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 21 Index 0"); +#endif + } + else{ + temp2 = RxMessage[4]; + } + if((temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK)>=0){ + current_intvl->AturChanPerfRxBlk+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK; + ATUR_CHAN_RECV_BLK+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK; + mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16); + } + else{ + current_intvl->AturChanPerfRxBlk+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16)); + ATUR_CHAN_RECV_BLK+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16)); + mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16); + } + current_intvl->AturChanPerfTxBlk = current_intvl->AturChanPerfRxBlk; + ATUR_CHAN_TX_BLK = ATUR_CHAN_RECV_BLK; +/* + ATUR_CHAN_TX_BLK_FLAG_MAKECMV_LSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS) + printk("\n\nCMV fail, Group 7 Address 20 Index 0"); + else{ + if(RxMessage[4]){ + current_intvl->AturChanPerfTxBlk+=RxMessage[4]; + ATUR_CHAN_TX_BLK+=RxMessage[4]; + } + } + ATUR_CHAN_TX_BLK_FLAG_MAKECMV_MSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS) + printk("\n\nCMV fail, Group 7 Address 21 Index 0"); + else{ + if(RxMessage[4]){ + current_intvl->AturChanPerfTxBlk+=(int)((RxMessage[4])<<16); + ATUR_CHAN_TX_BLK+=(int)((RxMessage[4])<<16); + } + } +*/ + if(chantype.interleave == 1){ + ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_INTL; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 3 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_INTL; + if(temp>=0){ + current_intvl->AturChanPerfCorrBlk+=temp; + ATUR_CHAN_CORR_BLK+=temp; + mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4]; + ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4]; + mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4]; + } + } + } + else if(chantype.fast == 1){ + ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_FAST; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 3 Index 1"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_FAST; + if(temp>=0){ + current_intvl->AturChanPerfCorrBlk+=temp; + ATUR_CHAN_CORR_BLK+=temp; + mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4]; + ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4]; + mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4]; + } + } + } + + if(chantype.interleave == 1){ + ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_INTL; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 2 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL; + if(temp>=0){ + current_intvl->AturChanPerfUncorrBlk+=temp; + ATUR_CHAN_UNCORR_BLK+=temp; + mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4]; + ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4]; + mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4]; + } + } + } + else if(chantype.fast == 1){ + ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_FAST; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 2 Index 1"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST; + if(temp>=0){ + current_intvl->AturChanPerfUncorrBlk+=temp; + ATUR_CHAN_UNCORR_BLK+=temp; + mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4]; + ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4]; + mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4]; + } + } + } + + //RFC-3440 + +#ifdef AMAZON_MEI_MIB_RFC3440 + ATUC_PERF_STAT_FASTR_FLAG_MAKECMV; //??? + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 0 Address 0 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FASTR; + if(temp>=0){ + current_intvl->AtucPerfStatFastR+=temp; + ATUC_PERF_STAT_FASTR+=temp; + mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4]; + ATUC_PERF_STAT_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4]; + } + } + ATUC_PERF_STAT_FAILED_FASTR_FLAG_MAKECMV; //??? + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 0 Address 0 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FAILED_FASTR; + if(temp>=0){ + current_intvl->AtucPerfStatFailedFastR+=temp; + ATUC_PERF_STAT_FAILED_FASTR+=temp; + mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatFailedFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4]; + ATUC_PERF_STAT_FAILED_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4]; + } + } + ATUC_PERF_STAT_SESL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 8 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_SESL; + if(temp>=0){ + current_intvl->AtucPerfStatSesL+=temp; + ATUC_PERF_STAT_SESL+=temp; + mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatSesL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4]; + ATUC_PERF_STAT_SESL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4]; + } + } + ATUC_PERF_STAT_UASL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 10 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_UASL; + if(temp>=0){ + current_intvl->AtucPerfStatUasL+=temp; + ATUC_PERF_STAT_UASL+=temp; + mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4]; + ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4]; + } + } + ATUR_PERF_STAT_SESL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 34 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_PERF_STAT_SESL; + if(temp>=0){ + current_intvl->AtucPerfStatUasL+=temp; + ATUC_PERF_STAT_UASL+=temp; + mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4]; + ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4]; + mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4]; + } + } + +#endif + up(&mei_sema); + + do_gettimeofday(&time_fini); + i = ((int)((time_fini.tv_sec-time_now.tv_sec)*1000)) + ((int)((time_fini.tv_usec-time_now.tv_usec)/1000)) ; //msec + }//showtime==1 + } + break; +#endif /* ] !IFX_SMALL_FOOTPRINT */ + case AMAZON_MEI_RESET: + case AMAZON_MEI_REBOOT: + case AMAZON_MEI_SHOWTIME: +/* if(mei_arc_swap_buff !=NULL){ + kfree(mei_arc_swap_buff); + mei_arc_swap_buff=NULL; + } + if(image_buffer !=NULL){ +// kfree(image_buffer); + vfree(image_buffer); + image_buffer =NULL; + } +*/ + if(clreoc_command_pkt !=NULL){ + kfree(clreoc_command_pkt); + clreoc_command_pkt =NULL; + } + for(i=0;i<CLREOC_BUFF_SIZE;i++) + clreoc_pkt[i].len=0; //flush all remaining clreoc commands in buffer +/* + memset(mei_mib, 0, (sizeof(amazon_mei_mib)*INTERVAL_NUM)); + INIT_LIST_HEAD(&interval_list); + for(i=0;i<INTERVAL_NUM;i++) + list_add_tail(&(mei_mib[i].list), &interval_list); + current_intvl = list_entry(interval_list.next, amazon_mei_mib, list); + do_gettimeofday(&(current_intvl->start_time)); + ATUC_PERF_LOFS=0; + ATUC_PERF_LOSS=0; + ATUC_PERF_ESS=0; + ATUC_PERF_INITS=0; + ATUR_PERF_LOFS=0; + ATUR_PERF_LOSS=0; + ATUR_PERF_LPR=0; + ATUR_PERF_ESS=0; + ATUR_CHAN_RECV_BLK=0; + ATUR_CHAN_TX_BLK=0; + ATUR_CHAN_CORR_BLK=0; + ATUR_CHAN_UNCORR_BLK=0; + memset((((u8 *)&AlarmConfProfile)+32), 0, 16*4); + AlarmConfProfile.adslLineAlarmConfProfileRowStatus=1; +*/ + PrevTxRate.adslAtucChanPrevTxRate=0; + PrevTxRate.adslAturChanPrevTxRate=0; + CurrStatus.adslAtucCurrStatus=0; + CurrStatus.adslAturCurrStatus=0; + + if((command==AMAZON_MEI_RESET) || (command==AMAZON_MEI_REBOOT)){ +#ifdef AMAZON_CHECK_LINK + if (adsl_link_notify){ + (*adsl_link_notify)(0); + } +#endif + showtime=0; + //CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON + // disconnect net_dev + if(chantype.interleave==1){ + kfree(interleave_mei_net.priv); + unregister_netdev(&interleave_mei_net); +// if(unregister_netdev(&interleave_mei_net)!=0) +// printk("\n unregister interleave fail"); + } + else if(chantype.fast==1){ + kfree(fast_mei_net.priv); + unregister_netdev(&fast_mei_net); +// if(unregister_netdev(&fast_mei_net)!=0) +// printk("\n unregister fast fail"); + } + chantype.interleave=0; + chantype.fast=0; +// 603221:tc.chen start + chantype.bearchannel0 = 0; + chantype.bearchannel1 = 0; + adsl_mode = 0; +// 603221:tc.chen end + + while(1){ + + makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, NULL); //maximum allowed tx message length, in bytes + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ + //printk("AdslInitStatsData.FullInitializationCount++\n"); + AdslInitStatsData.FullInitializationCount++; + //printk("AdslInitStatsData.FailedFullInitializationCount++\n"); + AdslInitStatsData.FailedFullInitializationCount++; + //printk("AdslInitStatsData.LINIT_Errors++\n"); + AdslInitStatsData.LINIT_Errors++; + }else + { + //printk("RxMessage=%X\n",RxMessage[4]); + if ( RxMessage[4]!=0x1) + { + //printk("AdslInitStatsData.FullInitializationCount++\n"); + AdslInitStatsData.FullInitializationCount++; + if ( RxMessage[4] != 0x7) + { + //printk("AdslInitStatsData.LINIT_Errors++\n"); + AdslInitStatsData.LINIT_Errors++; + //printk("AdslInitStatsData.FailedFullInitializationCount++\n"); + AdslInitStatsData.FailedFullInitializationCount++; + + } + } + } + + reboot_flag=0; + wake_up_interruptible(&wait_queue_codeswap); //wake up codeswap daemon + + interruptible_sleep_on_timeout(&wait_queue_reboot, 1*HZ); // sleep until arc ready +#ifdef ARC_READY_ACK + if(reboot_flag!=0) + break; + else + { + up(&mei_sema); + printk("\n reboot retry"); + } +#else + break; +#endif + } + } + else{ //AMAZON_MEI_SHOWTIME + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + // clreoc stuff + makeCMV(H2D_CMV_READ, INFO, 83, 0, 1, data); //maximum allowed tx message length, in bytes + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 83 Index 0"); +#endif + } + else{ + clreoc_max_tx_len = (int)RxMessage[4]; + clreoc_command_pkt = kmalloc((clreoc_max_tx_len*CLREOC_BUFF_SIZE), GFP_KERNEL); + if(clreoc_command_pkt == NULL){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("kmalloc error for clreoc_command_pkt\n\n"); +#endif + up(&mei_sema); + return -1; + } + for(i=0;i<CLREOC_BUFF_SIZE;i++){ + clreoc_pkt[i].command = (u8 *)(((u8 *)clreoc_command_pkt) + (clreoc_max_tx_len*i)); + clreoc_pkt[i].len=0; + } + } + + // decide what channel, then register + makeCMV(H2D_CMV_READ, STAT, 12, 0, 1, data); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 2 Address 12 Index 0"); +#endif + } + else{ + if((RxMessage[4]&0x1)==1){ + if(register_netdev(&interleave_mei_net)!=0){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n Register interleave Device Failed."); +#endif + } + else{ + chantype.interleave = 1; + chantype.fast= 0; +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n channel is interleave"); +#endif + } + } + else if((RxMessage[4]&0x2)==2){ + if(register_netdev(&fast_mei_net)!=0){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n Register fast Device Failed."); +#endif + } + else{ + chantype.fast = 1; + chantype.interleave = 0; +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n channel is fast"); +#endif + } + } + else{ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\nunknown channel type, 0x%8x", RxMessage[4]); +#endif + } +// 603221:tc.chen start + if ( (RxMessage[4]&0x100) == 0x100) + { + chantype.bearchannel0 = 1; + }else if ( (RxMessage[4]&0x100) == 0x200) + { + chantype.bearchannel1 = 1; + } +// 603221:tc.chen end + } +// 603221:tc.chen start + // read adsl mode + makeCMV(H2D_CMV_READ, STAT, 1, 0, 1, data); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 1 Index 0"); +#endif + } + adsl_mode = RxMessage[4]; +// 603221:tc.chen end + makeCMV(H2D_CMV_READ, STAT, 17, 0, 1, data); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group STAT Address 1 Index 0"); +#endif + } + adsl_mode_extend = RxMessage[4]; + + // update previous channel tx rate + ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 1 Index 0"); +#endif + PrevTxRate.adslAtucChanPrevTxRate = 0; + } + else{ + PrevTxRate.adslAtucChanPrevTxRate = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 6 Address 0 Index 0"); +#endif + PrevTxRate.adslAturChanPrevTxRate = 0; + } + else{ + PrevTxRate.adslAturChanPrevTxRate = (u32)(RxMessage[4]) + (((u32)(RxMessage[5]))<<16); + } + +// up(&mei_sema); + +// showtime=1; + //SET_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO OFF +//dying gasp -start +#ifdef IFX_DYING_GASP + lop_debugwr.buffer[0]=0xffffffff; //dying gasp + lop_debugwr.iCount=1; //dying gasp + makeCMV(H2D_CMV_READ, INFO, 66, 4, 1, NULL); + //mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &RxMessage); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 66 Index 4"); + } +#endif + lop_debugwr.iAddress=(u32)RxMessage[4]; + makeCMV(H2D_CMV_READ, INFO, 66, 5, 1, NULL); + //mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &RxMessage); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 3 Address 66 Index 5"); + } +#endif + lop_debugwr.iAddress+=((u32)RxMessage[4])<<16; + +//dying gasp -end +#endif // IFX_DYING_GASP + +//joelin 04/16/2005-start + makeCMV(H2D_CMV_WRITE, PLAM, 10, 0, 1, &unavailable_seconds); + //mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &RxMessage); + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 10 Index 0"); + +#endif + } + + +//joelin 04/16/2005-end + showtime=1; + up(&mei_sema); +#ifdef AMAZON_CHECK_LINK + if (adsl_link_notify){ + (*adsl_link_notify)(1); + } +#endif + + + } + break; +/* + case AMAZON_MEI_REPLY: + copy_from_user((char *)buff, (char *)lon, MSG_LENGTH * 2); + if(meiCMV(buff, YES_REPLY) != MEI_SUCCESS){ + printk("\n\n meiCMV no reply back"); + meierr=MEI_FAILURE; + } + else + copy_to_user((char *)lon, (char *)RxMessage, MSG_LENGTH * 2); + break; + case AMAZON_MEI_NOREPLY: + copy_from_user((char *)buff, (char *)lon, MSG_LENGTH * 2); + if(meiCMV(buff, NO_REPLY) != MEI_SUCCESS){ + printk("\n\n meiCMV Host to DSP failed"); + meierr=MEI_FAILURE; + } + break; +*/ + + case AMAZON_MEI_HALT: + meiHaltArc(); + break; + case AMAZON_MEI_CMV_WINHOST: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + + if (!from_kernel ) + copy_from_user((char *)TxMessage, (char *)lon, MSG_LENGTH*2);//joelin + else + memcpy(TxMessage,(char *)lon,MSG_LENGTH*2); + +#if 0 +// if((TxMessage[0]&0xff0)==0x0a0){ + for(i=0;i<16;i++){ + printk("\nTxMessage[%i]=%8x", i, TxMessage[i]); + } +// } +#endif + + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON +// printk("\n\n WINHOST CMV fail "); + printk("\n\nWINHOST CMV fail :TxMessage:%X %X %X %X, RxMessage:%X %X %X %X %X\n",TxMessage[0],TxMessage[1],TxMessage[2],TxMessage[3],RxMessage[0],RxMessage[1],RxMessage[2],RxMessage[3],RxMessage[4]); +#endif + meierr = MEI_FAILURE; + } + else + { + if (!from_kernel ) //joelin + copy_to_user((char *)lon, (char *)RxMessage, MSG_LENGTH*2); + else + memcpy((char *)lon,(char *)RxMessage,MSG_LENGTH*2); + } + + up(&mei_sema); + break; +#ifdef AMAZON_MEI_CMV_EXTRA + case AMAZON_MEI_CMV_READ: + copy_from_user((char *)(®rdwr), (char *)lon, sizeof(meireg)); + meiLongwordRead(regrdwr.iAddress, &(regrdwr.iData)); + { +// printk("\n\n iAddress = %8x",regrdwr.iAddress); + } + copy_to_user((char *)lon, (char *)(®rdwr), sizeof(meireg)); + { +// printk("\n\n iData readback = %8x", regrdwr.iData); + } + break; +#endif + +#ifdef AMAZON_MEI_CMV_EXTRA + case AMAZON_MEI_CMV_WRITE: + copy_from_user((char *)(®rdwr), (char *)lon, sizeof(meireg)); + { +// printk("\n\n iAddress = %8x",regrdwr.iAddress); +// printk("\n\n iData = %8x",regrdwr.iData); + } + meiLongwordWrite(regrdwr.iAddress, regrdwr.iData); + break; +#endif + +#ifdef AMAZON_MEI_CMV_EXTRA + case AMAZON_MEI_REMOTE: + copy_from_user((char *)(&i), (char *)lon, sizeof(int)); + if(i==0){ + meiMailboxInterruptsEnable(); + + up(&mei_sema); + } + else if(i==1){ + meiMailboxInterruptsDisable(); + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; + } + else{ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n AMAZON_MEI_REMOTE argument error"); +#endif + meierr=MEI_FAILURE; + } + break; +#endif + +#ifdef AMAZON_MEI_CMV_EXTRA + case AMAZON_MEI_READDEBUG: + case AMAZON_MEI_WRITEDEBUG: + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; +#ifdef IFX_DYING_GASP + if (!from_kernel) copy_from_user((char *)(&debugrdwr), (char *)lon, sizeof(debugrdwr));//dying gasp + else memcpy((char *)(&debugrdwr), (char *)lon, sizeof(debugrdwr)); +#else //IFX_DYING_GASP + copy_from_user((char *)(&debugrdwr), (char *)lon, sizeof(debugrdwr)); + +#endif //IFX_DYING_GASP +#if 0 + printk("\nIN iAddress: %8x, iCount:%8x\n", debugrdwr.iAddress, debugrdwr.iCount); +#endif + + if(command==AMAZON_MEI_READDEBUG) + meiDebugRead(debugrdwr.iAddress, debugrdwr.buffer, debugrdwr.iCount); + else + meiDebugWrite(debugrdwr.iAddress, debugrdwr.buffer, debugrdwr.iCount); + +#ifdef IFX_DYING_GASP + if (!from_kernel) copy_to_user((char *)lon, (char*)(&debugrdwr), sizeof(debugrdwr));//dying gasp +#else //IFX_DYING_GASP + copy_to_user((char *)lon, (char*)(&debugrdwr), sizeof(debugrdwr)); +#endif //IFX_DYING_GASP + up(&mei_sema); + +#if 0 + printk("\nOUT iAddress: %8x, iCount:%8x\n", debugrdwr.iAddress, debugrdwr.iCount); + for(i=0;i<debugrdwr.iCount;i++) + printk("\n %8x",debugrdwr.buffer[i]); +#endif + break; +#endif + + case AMAZON_MEI_LOP: + //GPIO31 :dying gasp event indication + // (1) logic high: dying gasp event is false (default) + // (2) logic low: dying gasp event is true +#ifdef IFX_DYING_GASP + break; +#else + CLEAR_BIT((*((volatile u32 *)0xB0100B48)), 0x8000); + CLEAR_BIT((*((volatile u32 *)0xB0100B4C)), 0x8000); + CLEAR_BIT((*((volatile u32 *)0xB0100B50)), 0x8000); + SET_BIT((*((volatile u32 *)0xB0100B54)), 0x8000); + asm("SYNC"); + if(((*((volatile u32 *)0xB0100B44))&0x8000)==0x0) + meierr=MEI_FAILURE; //return - to indicate loss of power + break; +#endif //#ifdef IFX_DYING_GASP + + //for PCM + case AMAZON_MEI_PCM_SETUP: + //gpio + + *AMAZON_GPIO_P0_DIR |=1<<15; + *AMAZON_GPIO_P0_ALTSEL0 |=1<<15; + *AMAZON_GPIO_P0_ALTSEL1 &=~(1<<15); + *AMAZON_GPIO_P0_OD |=1<<15; + + /*GPIO 16 TDM_DI*/ + *AMAZON_GPIO_P1_DIR &=~1; + *AMAZON_GPIO_P1_ALTSEL0 |=1; + *AMAZON_GPIO_P1_ALTSEL1 &=~1; + + /*GPIO 17 TDM_DCL */ + *AMAZON_GPIO_P1_DIR|=0x02; + *AMAZON_GPIO_P1_ALTSEL0|=0x02; + *AMAZON_GPIO_P1_ALTSEL1 &=(u32)~0x02; + *AMAZON_GPIO_P1_OD|=0x02; + + /*GPIO 18 TDM FSC*/ + *AMAZON_GPIO_P1_DIR|=0x04; + *AMAZON_GPIO_P1_ALTSEL0|=0x04; + *AMAZON_GPIO_P1_ALTSEL1 &=(u32)~0x04; + *AMAZON_GPIO_P1_OD|=0x04; + + for(i=0;i<2;i++){ + for(j=0;j<256;j++) + sampledata[i*256+j]=j; + } + + pcm_start_addr = lon; + + printk("\n\n pcm_start_addr is %8x", lon); + + for(i=0;i<PCM_CHANNEL_NUM;i++){ +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16((pcm_start_addr+i*16), (u32*)(pcm_data+i), 4); +#else + meiDMARead_16((pcm_start_addr+i*16), (u32*)(pcm_data+i), 4); +#endif + if((pcm_data[i].S!=8)||(pcm_data[i].len<1)||(pcm_data[i].rdindex!=0)||(pcm_data[i].wrindex!=0)||(pcm_data[i].flow!=0)) + printk("\n\n pcm_data fill in wrongly\n\n"); + printk("\npcm_data %d",i); + printk("\n S = %d", pcm_data[i].S); + printk("\n LSW = %4x", pcm_data[i].LSW); + printk("\n MSW = %4x", pcm_data[i].MSW); + printk("\n len = %d", pcm_data[i].len); + printk("\n rdindex = %d", pcm_data[i].rdindex); + printk("\n wrindex = %d", pcm_data[i].wrindex); + printk("\n flow = %d", pcm_data[i].flow); + pcm_data[i].finish=0; + if(i%2==0){//tx channel + for(j=0;j<PCM_BUFF_SIZE/256;j++){ + for(k=0;k<256;k++){ + pcm_data[i].buff[j*256+k]=k; + /* if(k%2==0) + pcm_data[i].buff[j*256+k]=0xaa; + else + pcm_data[i].buff[j*256+k]=0x55;*/ + } + } +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16)), (u32*)(pcm_data[i].buff),((pcm_data[i].len/4)/2));//fill half first +// meiDebugWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16)), (u32*)(pcm_data[i].buff),2);//fill half first +#else + meiDMAWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16)), (u32*)(pcm_data[i].buff),((pcm_data[i].len/4)/2));//fill half first +// meiDMAWrite_8((((u32)(pcm_data[i].LSW))+(((u32)(pcm_data[i].MSW))<<16)), (u32*)(pcm_data[i].buff),2);//fill half first +#endif + pcm_data[i].point=(pcm_data[i].len)/2; +// pcm_data[i].point=8; +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16(pcm_start_addr+i*16+12, &temp, 1); +#else + meiDMARead_16(pcm_start_addr+i*16+12, &temp, 1); +#endif + temp = (temp &0xffff) + (((u32)(pcm_data[i].point))<<16); +#ifdef PCM_ACCESS_DEBUG + meiDebugWrite_16(pcm_start_addr+i*16+12,&temp, 1);//update wrindex +#else + meiDMAWrite_16(pcm_start_addr+i*16+12,&temp, 1);//update wrindex +#endif + } + else{// rx channel + pcm_data[i].point=0; + } + } + break; + case AMAZON_MEI_PCM_START_TIMER: + /* GPTU timer 6 */ + /* enable the timer in the PMU */ + *(AMAZON_PMU_PWDCR) = (*(AMAZON_PMU_PWDCR))| AMAZON_PMU_PWDCR_GPT|AMAZON_PMU_PWDCR_FPI; + /* setup the GPTU for timer tick f_fpi == f_gptu*/ + *(AMAZON_GPTU_CLC) = 0x100; + //reload value = fpi/(HZ * P), timer mode, Prescaler = 4 ( T6I = 000, T6BPS2 = 0) + *(AMAZON_GPTU_CAPREL) = (int)(117500000/(lon*4)); + *(AMAZON_GPTU_T6CON) = 0x80C0; + + if (request_irq(AMAZON_TIMER6_INT, amazon_timer6_interrupt_MEI,0, "hrt", NULL)!=0){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n unable to register irq for hrt!!!"); +#endif + return -1; + } + enable_irq(AMAZON_TIMER6_INT); + break; + case AMAZON_MEI_PCM_STOP_TIMER: + disable_irq(AMAZON_TIMER6_INT); + free_irq(AMAZON_TIMER6_INT, NULL); + break; + case AMAZON_MEI_PCM_CHECK: + for(i=0;i<PCM_CHANNEL_NUM;i++){ + if(pcm_data[i].finish!=1) + return 0; + } + for(i=0;i<PCM_CHANNEL_NUM/2;i++){ + j=0; + while(1){ + if((pcm_data[i*2+1].buff[j]==0x0) && (pcm_data[i*2+1].buff[j+1]==0x1)&& (pcm_data[i*2+1].buff[j+2]==0x2)) + break; + else + j++; + } + printk("\n j=%d", j); + temp=0; + for(k=0;k<((PCM_BUFF_SIZE-j)/4);k++){ + if(memcmp(pcm_data[i*2].buff+k*4, pcm_data[i*2+1].buff+j+k*4, 4)!=0){ + temp++; + printk("\n\n%2x %2x %2x %2x %2x %2x %2x %2x\n\n", *((u8*)(pcm_data[i*2].buff+k*4)), *((u8*)(pcm_data[i*2].buff+k*4+1)),*((u8*)(pcm_data[i*2].buff+k*4+2)),*((u8*)(pcm_data[i*2].buff+k*4+3)),*((u8*)(pcm_data[i*2+1].buff+j+k*4)),*((u8*)(pcm_data[i*2+1].buff+j+k*4+1)),*((u8*)(pcm_data[i*2+1].buff+j+k*4+2)),*((u8*)(pcm_data[i*2+1].buff+j+k*4+3))); + break; + } + } + if(temp!=0) + printk("\n\n Channel pair %d not match: err32 %d\n\n", i, temp); + else + printk("\n\n Channel pair %d match\n\n", i); + } + for(i=0;i<PCM_CHANNEL_NUM;i++){ + if(i%2==1){//rx channel +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16(pcm_start_addr+i*16+12, &temp, 1); +#else + meiDMARead_16(pcm_start_addr+i*16+12, &temp, 1); +#endif + printk("\n\nRx channel %d: Overflow Bytes %d", i, (temp&0xffff)); + } + else{//tx channel +#ifdef PCM_ACCESS_DEBUG + meiDebugRead_16(pcm_start_addr+i*16, &temp, 1); +#else + meiDMARead_16(pcm_start_addr+i*16, &temp, 1); +#endif + printk("\n\nElectra Err: %d",(temp&0xffff)); + } + } + //check electra overflow + + meierr=1; + break; + case AMAZON_MEI_PCM_GETDATA: + copy_to_user(lon, pcm_data[1].buff, PCM_BUFF_SIZE); + break; + case AMAZON_MEI_PCM_GPIO: + //gpio + + *AMAZON_GPIO_P0_DIR |=1<<15; + *AMAZON_GPIO_P0_ALTSEL0 |=1<<15; + *AMAZON_GPIO_P0_ALTSEL1 &=~(1<<15); + *AMAZON_GPIO_P0_OD |=1<<15; + + /*GPIO 16 TDM_DI*/ + *AMAZON_GPIO_P1_DIR &=~1; + *AMAZON_GPIO_P1_ALTSEL0 |=1; + *AMAZON_GPIO_P1_ALTSEL1 &=~1; + + /*GPIO 17 TDM_DCL */ + *AMAZON_GPIO_P1_DIR|=0x02; + *AMAZON_GPIO_P1_ALTSEL0|=0x02; + *AMAZON_GPIO_P1_ALTSEL1 &=(u32)~0x02; + *AMAZON_GPIO_P1_OD|=0x02; + + /*GPIO 18 TDM FSC*/ + *AMAZON_GPIO_P1_DIR|=0x04; + *AMAZON_GPIO_P1_ALTSEL0|=0x04; + *AMAZON_GPIO_P1_ALTSEL1 &=(u32)~0x04; + *AMAZON_GPIO_P1_OD|=0x04; + break; + + + + //for clearEoC +#ifdef AMAZON_CLEAR_EOC + case AMAZON_MEI_GET_EOC_LEN: + while(1){ + current_clreoc = list_entry(clreoc_list.next, amazon_clreoc_pkt, list); + if((current_clreoc->len)>0){ + copy_to_user((char *)lon, (char*)(&(current_clreoc->len)), 4); + break; + } + else//wait for eoc data from higher layer + interruptible_sleep_on(&wait_queue_clreoc); + } + break; + case AMAZON_MEI_GET_EOC_DATA: + current_clreoc = list_entry(clreoc_list.next, amazon_clreoc_pkt, list); + if((current_clreoc->len)>0){ + copy_to_user((char*)lon, (char*)(current_clreoc->command), current_clreoc->len); + meierr=1; + list_del(clreoc_list.next); //remove and add to end of list + current_clreoc->len = 0; + list_add_tail(&(current_clreoc->list), &clreoc_list); + } + else + meierr=-1; + break; + case AMAZON_MEI_EOC_SEND: + copy_from_user((char *)(&debugrdwr), (char *)lon, sizeof(debugrdwr)); + eoc_skb = dev_alloc_skb(debugrdwr.iCount*4); + if(eoc_skb==NULL){ + printk("\n\nskb alloc fail"); + break; + } + + eoc_skb->len=debugrdwr.iCount*4; + memcpy(skb_put(eoc_skb, debugrdwr.iCount*4), (char *)debugrdwr.buffer, debugrdwr.iCount*4); + + ifx_push_eoc(eoc_skb); //pass data to higher layer + break; +#endif //#ifdef AMAZON_CLEAR_EOC + case AMAZON_MIB_LO_ATUC: + do_gettimeofday(&time_now); + if(lon&0x1){ + if((time_now.tv_sec-(mib_pflagtime.ATUC_PERF_LOSS_PTIME).tv_sec)>2){ + current_intvl->AtucPerfLos++; + ATUC_PERF_LOSS++; + CurrStatus.adslAtucCurrStatus = 2; + } + (mib_pflagtime.ATUC_PERF_LOSS_PTIME).tv_sec = time_now.tv_sec; + } + if(lon&0x2){ + if((time_now.tv_sec-(mib_pflagtime.ATUC_PERF_LOFS_PTIME).tv_sec)>2){ + current_intvl->AtucPerfLof++; + ATUC_PERF_LOFS++; + CurrStatus.adslAtucCurrStatus = 1; + } + (mib_pflagtime.ATUC_PERF_LOFS_PTIME).tv_sec = time_now.tv_sec; + } + if(!(lon&0x3)) + CurrStatus.adslAtucCurrStatus = 0; + break; + case AMAZON_MIB_LO_ATUR: + do_gettimeofday(&time_now); + if(lon&0x1){ + if((time_now.tv_sec-(mib_pflagtime.ATUR_PERF_LOSS_PTIME).tv_sec)>2){ + current_intvl->AturPerfLos++; + ATUR_PERF_LOSS++; + CurrStatus.adslAturCurrStatus = 2; + } + (mib_pflagtime.ATUR_PERF_LOSS_PTIME).tv_sec = time_now.tv_sec; + } + if(lon&0x2){ + if((time_now.tv_sec-(mib_pflagtime.ATUR_PERF_LOFS_PTIME).tv_sec)>2){ + current_intvl->AturPerfLof++; + ATUR_PERF_LOFS++; + CurrStatus.adslAturCurrStatus = 1; + } + (mib_pflagtime.ATUR_PERF_LOFS_PTIME).tv_sec = time_now.tv_sec; + } + if(lon&0x4){ + if((time_now.tv_sec-(mib_pflagtime.ATUR_PERF_LPR_PTIME).tv_sec)>2){ + current_intvl->AturPerfLpr++; + ATUR_PERF_LPR++; + CurrStatus.adslAturCurrStatus = 3; + } + (mib_pflagtime.ATUR_PERF_LPR_PTIME).tv_sec = time_now.tv_sec; + } + if(!(lon&0x7)) + CurrStatus.adslAturCurrStatus = 0; + break; + case AMAZON_MEI_DOWNLOAD: + // DMA the boot code page(s) +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n start download pages"); +#endif + for( boot_loop = 0; boot_loop < img_hdr->count; boot_loop++){ + if( img_hdr->page[boot_loop].p_size & BOOT_FLAG){ + page_size = meiGetPage( boot_loop, GET_PROG, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( page_size > 0){ + meiDMAWrite(dest_addr, mei_arc_swap_buff, page_size); + } + } + if( img_hdr->page[boot_loop].d_size & BOOT_FLAG){ + page_size = meiGetPage( boot_loop, GET_DATA, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( page_size > 0){ + meiDMAWrite( dest_addr, mei_arc_swap_buff, page_size); + } + } + } +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n pages downloaded"); +#endif + break; + //509221:tc.chen start + case AMAZON_MEI_DEBUG_MODE: + mei_debug_mode = lon; + break; + //509221:tc.chen end + } + return meierr; +} + + +////////////////////// Interrupt handler ///////////////////////////////////////////////////// +static void mei_interrupt_arcmsgav(int,void *,struct pt_regs *); +static void mei_interrupt_arcmsgav(int int1, void * void0, struct pt_regs * regs) +{ + u32 scratch; + u32 fetchpage; + u32 size; + u32 dest_addr; + u32 temp; + int i; + + meiDebugRead(ARC_MEI_MAILBOXR, &scratch, 1); + if(scratch & OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK) + { + if(showtime==1){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n Code Swap Request After ShowTime !!!"); +#endif + } + else{ +#ifdef AMAZON_MEI_DEBUG_ON +// printk("\n\n Code Swap Request"); +#endif + fetchpage = scratch & ~OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK; + size = meiGetPage( fetchpage, GET_PROG, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( size > 0) + { +#ifdef AMAZON_MEI_DEBUG_ON +// printk(" : prom page num %d",fetchpage); +#endif + meiDMAWrite( dest_addr, mei_arc_swap_buff, size); + } + + size = meiGetPage( fetchpage, GET_DATA, MAXSWAPSIZE, mei_arc_swap_buff, &dest_addr); + if( size > 0) + { +#ifdef AMAZON_MEI_DEBUG_ON +// printk(" : data page num %d",fetchpage); +#endif + meiDMAWrite( dest_addr, mei_arc_swap_buff, size); + } + } + // Notify arc that mailbox read complete + meiLongwordWrite(ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV); + + // Tell ARC Codeswap is done + meiLongwordWrite(MEI_TO_ARC_INT, MEI_TO_ARC_CS_DONE); + asm("SYNC"); + i=0; + while(i<WHILE_DELAY){ + meiLongwordRead(MEI_TO_ARC_INT, &temp); + if((temp & MEI_TO_ARC_CS_DONE) ==0){ +#ifdef AMAZON_MEI_DEBUG_ON +// printk("\n\n Code Swap Done"); +#endif + break; + } + i++; + if(i==WHILE_DELAY){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n MEI_TO_ARC_CS_DONE not cleared by ARC"); + //509221:tc.chen start + if (!mei_debug_mode) + { + //printk("Reset Arc!\n"); + //printk("AdslInitStatsData.FullInitializationCount++\n"); + AdslInitStatsData.FullInitializationCount++; + if (!showtime) + { + //printk("AdslInitStatsData.FailedFullInitializationCount++\n"); + AdslInitStatsData.FailedFullInitializationCount++; + //printk("AdslInitStatsData.LINIT_Errors++\n"); + AdslInitStatsData.LINIT_Errors++; + } + + wake_up_interruptible(&wait_queue_codeswap); // wait up ioctl reboot + } + //509221:tc.chen end +#endif + } + } + } + else{ // normal message +// printk("\n\n interrupt"); + meiMailboxRead(RxMessage, MSG_LENGTH); + if(cmv_waiting==1){ + arcmsgav=1; + cmv_waiting=0; + wake_up_interruptible(&wait_queue_arcmsgav); + } + else{ + indicator_count++; + memcpy((char *)Recent_indicator, (char *)RxMessage, MSG_LENGTH *2); +#ifdef ARC_READY_ACK + if(((RxMessage[0]&0xff0)>>4)==D2H_AUTONOMOUS_MODEM_READY_MSG){ //check ARC ready message + +#ifdef LOCK_RETRY + if (reboot_lock) + { + reboot_lock = 0; + up(&mei_sema); // allow cmv access + } +#else + up(&mei_sema); // allow cmv access +#endif + reboot_flag=1; +//#ifdef ADSL_LED_SUPPORT +#if 0 + led_support_check=1;//adsl led for 1.1.2.7.1.1 + adsl_led_flash();//adsl led for 1.1.2.7.1.1 +#endif + wake_up_interruptible(&wait_queue_reboot); // wait up ioctl reboot + } +#endif + } + } +// meiLongwordWrite(ARC_TO_MEI_INT, ARC_TO_MEI_MSGAV); + mask_and_ack_amazon_irq(AMAZON_MEI_INT); + return; +} + +// 603221:tc.chen start +////////////////////////hdlc //////////////// + +// get hdlc status +static unsigned int ifx_me_hdlc_status(void) +{ + u16 CMVMSG[MSG_LENGTH]; + int ret; + + if (showtime!=1) + return -ENETRESET; + + makeCMV_local(H2D_CMV_READ, STAT, 14, 0, 1, NULL,CMVMSG); //Get HDLC status + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + return CMVMSG[4]&0x0F; +} + +int ifx_me_is_resloved(int status) +{ + u16 CMVMSG[MSG_LENGTH]; + int ret; + + if (status == ME_HDLC_MSG_QUEUED || status == ME_HDLC_MSG_SENT) + return ME_HDLC_UNRESOLVED; + if (status == ME_HDLC_IDLE) + { + makeCMV_local(H2D_CMV_READ, CNTL, 2, 0, 1, NULL,CMVMSG); //Get ME-HDLC Control + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return IFX_POP_EOC_FAIL; + } + if (CMVMSG[4]&(1<<0)) + { + return ME_HDLC_UNRESOLVED; + } + + } + return ME_HDLC_RESOLVED; +} + +int _ifx_me_hdlc_send(unsigned char *hdlc_pkt,int len,int max_length) +{ + int ret; + u16 CMVMSG[MSG_LENGTH]; + u16 data=0; + u16 pkt_len=len; + if (pkt_len > max_length) + { + printk("Exceed maximum eoc message length\n"); + return -ENOBUFS; + } + //while(pkt_len > 0) + { + makeCMV_local(H2D_CMV_WRITE, INFO, 81, 0, (pkt_len+1)/2,(u16 *)hdlc_pkt,CMVMSG); //Write clear eoc message to ARC + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + + makeCMV_local(H2D_CMV_WRITE, INFO, 83, 2, 1,&pkt_len,CMVMSG); //Update tx message length + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + + data = (1<<0); + makeCMV_local(H2D_CMV_WRITE, CNTL, 2, 0, 1,&data,CMVMSG); //Start to send + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + return 0; + } +} + +static int ifx_me_hdlc_send(unsigned char *hdlc_pkt,int hdlc_pkt_len) +{ + int hdlc_status=0; + u16 CMVMSG[MSG_LENGTH]; + int max_hdlc_tx_length=0,ret=0,retry=0; + + while(retry<10) + { + hdlc_status = ifx_me_hdlc_status(); + if (ifx_me_is_resloved(hdlc_status)==ME_HDLC_RESOLVED) // arc ready to send HDLC message + { + makeCMV_local(H2D_CMV_READ, INFO, 83, 0, 1, NULL,CMVMSG); //Get Maximum Allowed HDLC Tx Message Length + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + max_hdlc_tx_length = CMVMSG[4]; + ret = _ifx_me_hdlc_send(hdlc_pkt,hdlc_pkt_len,max_hdlc_tx_length); + return ret; + } + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(10); + } + return -EBUSY; +} + +int ifx_mei_hdlc_read(char *hdlc_pkt,int max_hdlc_pkt_len) +{ + u16 CMVMSG[MSG_LENGTH]; + int msg_read_len,ret=0,pkt_len=0,retry = 0; + + while(retry<10) + { + ret = ifx_me_hdlc_status(); + if (ret == ME_HDLC_RESP_RCVD) + { + int current_size=0; + makeCMV_local(H2D_CMV_READ, INFO, 83, 3, 1, NULL,CMVMSG); //Get EoC packet length + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + return -EIO; + } + + pkt_len = CMVMSG[4]; + if (pkt_len > max_hdlc_pkt_len) + { + ret = -ENOMEM; + goto error; + } + while( current_size < pkt_len) + { + if (pkt_len - current_size >(MSG_LENGTH*2-8)) + msg_read_len = (MSG_LENGTH*2-8); + else + msg_read_len = pkt_len - (current_size); + makeCMV_local(H2D_CMV_READ, INFO, 82, 0 + (current_size/2), (msg_read_len+1)/2, NULL,CMVMSG); //Get hdlc packet + ret = mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + if (ret != 0) + { + goto error; + } + memcpy(hdlc_pkt+current_size,&CMVMSG[4],msg_read_len); + current_size +=msg_read_len; + } + ret = current_size; + break; + }else + { + ret = -ENODATA; + } + + retry++; + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(10); + + } + return ret; +error: + + return ret; +} + +////////////////////////hdlc //////////////// +// 603221:tc.chen end + +/////////////////////// clearEoC, int ifx_pop_eoc(sk_buff * pkt) ////////// +int ifx_pop_eoc(struct sk_buff * pkt); +int ifx_pop_eoc(struct sk_buff * pkt) +{ + amazon_clreoc_pkt * current; + if(showtime!=1){ + dev_kfree_skb(pkt); + return IFX_POP_EOC_FAIL; + } + if((pkt->len)>clreoc_max_tx_len){ + dev_kfree_skb(pkt); + return IFX_POP_EOC_FAIL; + } + current = list_entry(clreoc_list.next, amazon_clreoc_pkt, list); + while(1){ + if(current->len==0){ + memcpy(current->command, pkt->data, pkt->len); + current->len=pkt->len; + break; + } + else{ + if((current->list).next==&clreoc_list){ + dev_kfree_skb(pkt); + return IFX_POP_EOC_FAIL; //buffer full + } + current = list_entry((current->list).next,amazon_clreoc_pkt, list); + } + } + wake_up_interruptible(&wait_queue_clreoc); + + dev_kfree_skb(pkt); + return IFX_POP_EOC_DONE; +} +/* this is used in circular fifo mode */ +/* +int ifx_pop_eoc(sk_buff * pkt); +int ifx_pop_eoc(sk_buff * pkt) +{ + int buff_space,i; + if(showtime!=1) + return IFX_POP_EOC_FAIL; + + if(clreoc_wr>=clreoc_rd) + buff_space = (MEI_CLREOC_BUFF_SIZE-1)-(clreoc_wr - clreoc_rd); + else + buff_space = clreoc_rd - clreoc_wr - 1; + if((pkt->len)>buff_space) + return IFX_POP_EOC_FAIL; + + if((clreoc_wr+pkt->len)>MEI_CLREOC_BUFF_SIZE){ + memcpy((clreoc+clreoc_wr), pkt->data, ((clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE+1)); + memcpy(clreoc, (pkt->data)+((clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE+1), (pkt->len)-((clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE+1)); + clreoc_wr=(clreoc_wr+pkt->len)-MEI_CLREOC_BUFF_SIZE; + } + else{ + memcpy((clreoc+clreoc_wr), pkt->data, pkt->len); + if((clreoc_wr+pkt->len)=MEI_CLREOC_BUFF_SIZE) + clreoc_wr=0; + else + clreoc_wr+=pkt->len; + } + wake_up_interruptible(&wait_queue_clreoc); + return IFX_POP_EOC_DONE; +} +*/ + + +//////////////////////////////////////////////////////////////////////////// +//int amazon_mei_init_module (void); +//void amazon_mei_cleanup_module (void); +//int __init init_module (void); +//void __exit cleanup_module (void); + +int __init amazon_mei_init_module(void) +//int __init init_module(void) +{ + struct proc_dir_entry *entry; + int i; + +//dying gasp-start +#ifdef IFX_DYING_GASP + +//000003:fchang Start +#ifdef CONFIG_CPU_AMAZON_E + //GPIO31 :dying gasp event indication + // (1) logic high: dying gasp event is false (default) + // (2) logic low: dying gasp event is true + CLEAR_BIT((*((volatile u32 *)0xB0100B18)), 0x4); + CLEAR_BIT((*((volatile u32 *)0xB0100B1c)), 0x4); + CLEAR_BIT((*((volatile u32 *)0xB0100B20)), 0x4); + SET_BIT((*((volatile u32 *)0xB0100B24)), 0x4); + asm("SYNC"); +#else //000003:fchang End + + //GPIO31 :dying gasp event indication + // (1) logic high: dying gasp event is false (default) + // (2) logic low: dying gasp event is true + CLEAR_BIT((*((volatile u32 *)0xB0100B48)), 0x8000); + CLEAR_BIT((*((volatile u32 *)0xB0100B4C)), 0x8000); + CLEAR_BIT((*((volatile u32 *)0xB0100B50)), 0x8000); + SET_BIT((*((volatile u32 *)0xB0100B54)), 0x8000); +#if 0 +//warning-led-start +//GPIO 22 + SET_BIT ((*((volatile u32 *)0xB0100B48)), 0x40); + CLEAR_BIT((*((volatile u32 *)0xB0100B4C)), 0x40); + CLEAR_BIT((*((volatile u32 *)0xB0100B50)), 0x40); + SET_BIT((*((volatile u32 *)0xB0100B54)), 0x40); + CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //GPIO ON + printk("LED ON ON ON ON ON ON....."); +//warning-led-end +#endif + asm("SYNC"); +#endif //000003:fchang + +#endif //IFX_DYING_GASP +//dying gasp -end + + + reg_entry_t regs_temp[PROC_ITEMS] = // Items being debugged + { + /* { flag, name, description } */ + { &arcmsgav, "arcmsgav", "arc to mei message ", 0 }, + { &cmv_reply, "cmv_reply", "cmv needs reply", 0}, + { &cmv_waiting, "cmv_waiting", "waiting for cmv reply from arc", 0}, + { &indicator_count, "indicator_count", "ARC to MEI indicator count", 0}, + { &cmv_count, "cmv_count", "MEI to ARC CMVs", 0}, + { &reply_count, "reply_count", "ARC to MEI Reply", 0}, + { (int *)Recent_indicator, "Recent_indicator", "most recent indicator", 0}, + { (int *)8, "version", "version of firmware", 0}, + }; + memcpy((char *)regs, (char *)regs_temp, sizeof(regs_temp)); + + + //sema_init(&mei_sema, 0); // semaphore initialization, mutex + sema_init(&mei_sema, 1); // semaphore initialization, mutex + + init_waitqueue_head(&wait_queue_arcmsgav); // for ARCMSGAV + init_waitqueue_head(&wait_queue_codeswap); // for codeswap daemon + init_waitqueue_head(&wait_queue_mibdaemon); // for mib daemon + init_waitqueue_head(&wait_queue_reboot); // for ioctl reboot + init_waitqueue_head(&wait_queue_clreoc); // for clreoc_wr function + init_waitqueue_head(&wait_queue_loop_diagnostic); // for loop diagnostic function +#ifdef ADSL_LED_SUPPORT + init_waitqueue_head(&wait_queue_led); // adsl led for led function + init_waitqueue_head(&wait_queue_led_polling); // adsl led for led function + led_task.routine = adsl_led_flash_task; // adsl led for led function + led_poll_init(); // adsl led for led function +#endif //ADSL_LED_SUPPORT +#ifdef IFX_DYING_GASP + init_waitqueue_head(&wait_queue_dying_gasp); // IFX_DYING_GASP + lop_poll_init(); // IFX_DYING_GASP +#endif //IFX_DYING_GASP + + init_waitqueue_head(&wait_queue_uas_poll);//joelin 04/16/2005 + unavailable_seconds_poll_init();//joelin 04/16/2005 + memset(&mib_pflagtime, 0, (sizeof(mib_flags_pretime))); + + // initialize link list for intervals + mei_mib = (amazon_mei_mib *)kmalloc((sizeof(amazon_mei_mib)*INTERVAL_NUM), GFP_KERNEL); + if(mei_mib == NULL){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("kmalloc error for amazon_mei_mib\n\n"); +#endif + return -1; + } + memset(mei_mib, 0, (sizeof(amazon_mei_mib)*INTERVAL_NUM)); + INIT_LIST_HEAD(&interval_list); + for(i=0;i<INTERVAL_NUM;i++) + list_add_tail(&(mei_mib[i].list), &interval_list); + current_intvl = list_entry(interval_list.next, amazon_mei_mib, list); + do_gettimeofday(&(current_intvl->start_time)); + // initialize clreoc list + clreoc_pkt = (amazon_clreoc_pkt *)kmalloc((sizeof(amazon_clreoc_pkt)*CLREOC_BUFF_SIZE), GFP_KERNEL); + if(clreoc_pkt == NULL){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("kmalloc error for clreoc_pkt\n\n"); +#endif + return -1; + } + memset(clreoc_pkt, 0, (sizeof(amazon_clreoc_pkt)*CLREOC_BUFF_SIZE)); + INIT_LIST_HEAD(&clreoc_list); + for(i=0;i<CLREOC_BUFF_SIZE;i++) + list_add_tail(&(clreoc_pkt[i].list), &clreoc_list); + + memset(&AdslInitStatsData, 0, sizeof(AdslInitStatsData)); + if (register_chrdev(major, "amazon_mei", &mei_operations)!=0) { +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n unable to register major for amazon_mei!!!"); +#endif + return -1; + } + if (request_irq(AMAZON_MEI_INT, mei_interrupt_arcmsgav,0, "amazon_mei_arcmsgav", NULL)!=0){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n unable to register irq for amazon_mei!!!"); +#endif + return -1; + } +// disable_irq(AMAZON_MEI_INT); + enable_irq(AMAZON_MEI_INT); + // procfs + meidir=proc_mkdir(MEI_DIRNAME, &proc_root); + if ( meidir == NULL) { +#ifdef AMAZON_MEI_DEBUG_ON + printk(KERN_ERR ": can't create /proc/" MEI_DIRNAME "\n\n"); +#endif + return(-ENOMEM); + } + + for(i=0;i<NUM_OF_REG_ENTRY;i++) { + entry = create_proc_entry(regs[i].name, + S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, + meidir); + if(entry) { + regs[i].low_ino = entry->low_ino; + entry->proc_fops = &proc_operations; + } else { +#ifdef AMAZON_MEI_DEBUG_ON + printk( KERN_ERR + ": can't create /proc/" MEI_DIRNAME + "/%s\n\n", regs[i].name); +#endif + return(-ENOMEM); + } + } + ///////////////////////////////// register net device //////////////////////////// + if(register_netdev(&phy_mei_net)!=0){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\n Register phy Device Failed."); +#endif + return -1; + } +/* + if(register_netdev(&interleave_mei_net)!=0){ + printk("\n\n Register interleave Device Failed."); + return -1; + } + if(register_netdev(&fast_mei_net)!=0){ + printk("\n\n Register fast Device Failed."); + return -1; + } +*/ +#ifdef DFE_LOOPBACK + mei_arc_swap_buff = (u32 *)kmalloc(MAXSWAPSIZE*4, GFP_KERNEL); + if (mei_arc_swap_buff){ +#ifdef ARC_READY_ACK + if(down_interruptible(&mei_sema)) //disable CMV access until ARC ready + { + return -ERESTARTSYS; + } +#ifdef LOCK_RETRY + reboot_lock = 1; +#endif +#endif + meiForceRebootAdslModem(); + kfree(mei_arc_swap_buff); + }else{ +#ifdef AMAZON_MEI_DEBUG_ON + printk("cannot load image: no memory\n\n"); +#endif + } +#endif +#ifdef IFX_SMALL_FOOTPRINT + mib_poll_init(); +#endif + return 0; +} + +void __exit amazon_mei_cleanup_module(void) +//void __exit cleanup_module(void) +{ + int i; +#ifdef ADSL_LED_SUPPORT + stop_led_module=1; //wake up and clean led module + led_support_check=0;//joelin , clear task + showtime=0;//joelin,clear task + //CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON + firmware_support_led=0;//joelin ,clear task + wake_up_interruptible(&wait_queue_led); //wake up and clean led module + wake_up_interruptible(&wait_queue_led_polling); //wake up and clean led module +#endif + for(i=0;i<NUM_OF_REG_ENTRY;i++) + remove_proc_entry(regs[i].name, meidir); + remove_proc_entry(MEI_DIRNAME, &proc_root); + + disable_irq(AMAZON_MEI_INT); + free_irq(AMAZON_MEI_INT, NULL); + unregister_chrdev(major, "amazon_mei"); + + kfree(mei_mib); + kfree(clreoc_pkt); + + kfree(phy_mei_net.priv); + unregister_netdev(&phy_mei_net); + + return; +} +#ifdef IFX_SMALL_FOOTPRINT + + +int adsl_mib_poll(void *unused) +{ + struct task_struct *tsk = current; + int i=0; + struct timeval time_now; + struct timeval time_fini; + u32 temp,temp2; + + amazon_mei_mib * mib_ptr; +// u16 buff[MSG_LENGTH]__attribute__ ((aligned(4))); + u16 * data=NULL; //used in makeCMV, to pass in payload when CMV set, ignored when CMV read. + + daemonize(); + strcpy(tsk->comm, "kmibpoll"); + sigfillset(&tsk->blocked); + + printk("Inside mib poll loop ...\n"); + i=0; + while(1){ + if(i<MIB_INTERVAL) + interruptible_sleep_on_timeout(&wait_queue_mibdaemon, ((MIB_INTERVAL-i)/(1000/HZ))); + i=0; + if(showtime==1){ +// printk("\n\n update mib"); + + do_gettimeofday(&time_now); + if(time_now.tv_sec - current_intvl->start_time.tv_sec>=900){ + if(current_intvl->list.next!=&interval_list){ + current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list); + do_gettimeofday(&(current_intvl->start_time)); + } + else{ + mib_ptr = list_entry(interval_list.next, amazon_mei_mib, list); + list_del(interval_list.next); + memset(mib_ptr, 0, sizeof(amazon_mei_mib)); + list_add_tail(&(mib_ptr->list), &interval_list); + if(current_intvl->list.next==&interval_list) +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nlink list error"); +#endif + current_intvl = list_entry(current_intvl->list.next, amazon_mei_mib, list); + do_gettimeofday(&(current_intvl->start_time)); + } + } + + if(down_interruptible(&mei_sema)) + return -ERESTARTSYS; +/* + ATUC_PERF_LO_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 0 Index 0"); +#endif + } + else{ + if(RxMessage[4]&PLAM_LOS_FailureBit){ + current_intvl->AtucPerfLos++; + ATUC_PERF_LOSS++; + CurrStatus.adslAtucCurrStatus = 2; + } + if(RxMessage[4]&PLAM_LOF_FailureBit){ + current_intvl->AtucPerfLof++; + ATUC_PERF_LOFS++; + CurrStatus.adslAtucCurrStatus = 1; + } + if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit))) + CurrStatus.adslAtucCurrStatus = 0; + } +*/ + + if(showtime!=1) + goto mib_poll_end; + ATUC_PERF_ESS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 7 Index 0"); +#endif + } + else{ + temp = RxMessage[4]-mib_pread.ATUC_PERF_ESS; + if(temp>=0){ + current_intvl->AtucPerfEs+=temp; + ATUC_PERF_ESS+=temp; + mib_pread.ATUC_PERF_ESS = RxMessage[4]; + } + else{ + current_intvl->AtucPerfEs+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4]; + ATUC_PERF_ESS+=0xffff-mib_pread.ATUC_PERF_ESS+RxMessage[4]; + mib_pread.ATUC_PERF_ESS = RxMessage[4]; + } + } +/* + ATUR_PERF_LO_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 1 Index 0"); +#endif + } + else{ + if(RxMessage[4]&PLAM_LOS_FailureBit){ + current_intvl->AturPerfLos++; + ATUR_PERF_LOSS++; + CurrStatus.adslAturCurrStatus = 2; + } + if(RxMessage[4]&PLAM_LOF_FailureBit){ + current_intvl->AturPerfLof++; + ATUR_PERF_LOFS++; + CurrStatus.adslAturCurrStatus = 1; + } + if(RxMessage[4]&PLAM_LPR_FailureBit){ + current_intvl->AturPerfLpr++; + ATUR_PERF_LPR++; + CurrStatus.adslAturCurrStatus = 3; + } + if(!(RxMessage[4]&(PLAM_LOS_FailureBit|PLAM_LOF_FailureBit|PLAM_LPR_FailureBit))) + CurrStatus.adslAturCurrStatus = 0; + } +*/ + if(showtime!=1) + goto mib_poll_end; + ATUR_PERF_ESS_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 33 Index 0"); +#endif + } + else{ + temp = RxMessage[4]-mib_pread.ATUR_PERF_ESS; + if(temp>=0){ + current_intvl->AturPerfEs+=temp; + ATUR_PERF_ESS+=temp; + mib_pread.ATUR_PERF_ESS = RxMessage[4]; + } + else{ + current_intvl->AturPerfEs+=0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4]; + ATUR_PERF_ESS+= 0xffff-mib_pread.ATUR_PERF_ESS+RxMessage[4]; + mib_pread.ATUR_PERF_ESS=RxMessage[4]; + } + } + if(showtime!=1) + goto mib_poll_end; + // to update rx/tx blocks + ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_LSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 20 Index 0"); +#endif + } + else{ + temp = RxMessage[4]; + } + if(showtime!=1) + goto mib_poll_end; + ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_MSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 21 Index 0"); +#endif + } + else{ + temp2 = RxMessage[4]; + } + if((temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK)>=0){ + current_intvl->AturChanPerfRxBlk+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK; + ATUR_CHAN_RECV_BLK+=temp + (temp2<<16) - mib_pread.ATUR_CHAN_RECV_BLK; + mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16); + } + else{ + current_intvl->AturChanPerfRxBlk+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16)); + ATUR_CHAN_RECV_BLK+=0xffffffff - mib_pread.ATUR_CHAN_RECV_BLK +(temp + (temp2<<16)); + mib_pread.ATUR_CHAN_RECV_BLK = temp + (temp2<<16); + } + current_intvl->AturChanPerfTxBlk = current_intvl->AturChanPerfRxBlk; + ATUR_CHAN_TX_BLK = ATUR_CHAN_RECV_BLK; +/* + ATUR_CHAN_TX_BLK_FLAG_MAKECMV_LSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS) + printk("\n\nCMV fail, Group 7 Address 20 Index 0"); + else{ + if(RxMessage[4]){ + current_intvl->AturChanPerfTxBlk+=RxMessage[4]; + ATUR_CHAN_TX_BLK+=RxMessage[4]; + } + } + ATUR_CHAN_TX_BLK_FLAG_MAKECMV_MSW; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS) + printk("\n\nCMV fail, Group 7 Address 21 Index 0"); + else{ + if(RxMessage[4]){ + current_intvl->AturChanPerfTxBlk+=(int)((RxMessage[4])<<16); + ATUR_CHAN_TX_BLK+=(int)((RxMessage[4])<<16); + } + } +*/ + if(chantype.interleave == 1){ + if(showtime!=1) + goto mib_poll_end; + ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_INTL; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 3 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_INTL; + if(temp>=0){ + current_intvl->AturChanPerfCorrBlk+=temp; + ATUR_CHAN_CORR_BLK+=temp; + mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4]; + ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_INTL +RxMessage[4]; + mib_pread.ATUR_CHAN_CORR_BLK_INTL = RxMessage[4]; + } + } + } + else if(chantype.fast == 1){ + if(showtime!=1) + goto mib_poll_end; + ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_FAST; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 3 Index 1"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_CORR_BLK_FAST; + if(temp>=0){ + current_intvl->AturChanPerfCorrBlk+=temp; + ATUR_CHAN_CORR_BLK+=temp; + mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfCorrBlk+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4]; + ATUR_CHAN_CORR_BLK+=0xffff - mib_pread.ATUR_CHAN_CORR_BLK_FAST + RxMessage[4]; + mib_pread.ATUR_CHAN_CORR_BLK_FAST = RxMessage[4]; + } + } + } + + if(chantype.interleave == 1){ + if(showtime!=1) + goto mib_poll_end; + ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_INTL; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 2 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL; + if(temp>=0){ + current_intvl->AturChanPerfUncorrBlk+=temp; + ATUR_CHAN_UNCORR_BLK+=temp; + mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4]; + ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_INTL + RxMessage[4]; + mib_pread.ATUR_CHAN_UNCORR_BLK_INTL = RxMessage[4]; + } + } + } + else if(chantype.fast == 1){ + if(showtime!=1) + goto mib_poll_end; + ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_FAST; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 2 Index 1"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST; + if(temp>=0){ + current_intvl->AturChanPerfUncorrBlk+=temp; + ATUR_CHAN_UNCORR_BLK+=temp; + mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4]; + } + else{ + current_intvl->AturChanPerfUncorrBlk+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4]; + ATUR_CHAN_UNCORR_BLK+=0xffff - mib_pread.ATUR_CHAN_UNCORR_BLK_FAST + RxMessage[4]; + mib_pread.ATUR_CHAN_UNCORR_BLK_FAST = RxMessage[4]; + } + } + } + + //RFC-3440 + +#ifdef AMAZON_MEI_MIB_RFC3440 + if(showtime!=1) + goto mib_poll_end; + ATUC_PERF_STAT_FASTR_FLAG_MAKECMV; //??? + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 0 Address 0 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FASTR; + if(temp>=0){ + current_intvl->AtucPerfStatFastR+=temp; + ATUC_PERF_STAT_FASTR+=temp; + mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4]; + ATUC_PERF_STAT_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FASTR + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_FASTR = RxMessage[4]; + } + } + if(showtime!=1) + goto mib_poll_end; + ATUC_PERF_STAT_FAILED_FASTR_FLAG_MAKECMV; //??? + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 0 Address 0 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_FAILED_FASTR; + if(temp>=0){ + current_intvl->AtucPerfStatFailedFastR+=temp; + ATUC_PERF_STAT_FAILED_FASTR+=temp; + mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatFailedFastR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4]; + ATUC_PERF_STAT_FAILED_FASTR+=0xffff - mib_pread.ATUC_PERF_STAT_FAILED_FASTR + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_FAILED_FASTR = RxMessage[4]; + } + } + if(showtime!=1) + goto mib_poll_end; + ATUC_PERF_STAT_SESL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 8 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_SESL; + if(temp>=0){ + current_intvl->AtucPerfStatSesL+=temp; + ATUC_PERF_STAT_SESL+=temp; + mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatSesL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4]; + ATUC_PERF_STAT_SESL+=0xffff - mib_pread.ATUC_PERF_STAT_SESL + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_SESL = RxMessage[4]; + } + } + if(showtime!=1) + goto mib_poll_end; + ATUC_PERF_STAT_UASL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 10 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUC_PERF_STAT_UASL; + if(temp>=0){ + current_intvl->AtucPerfStatUasL+=temp; + ATUC_PERF_STAT_UASL+=temp; + mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4]; + ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUC_PERF_STAT_UASL + RxMessage[4]; + mib_pread.ATUC_PERF_STAT_UASL = RxMessage[4]; + } + } + if(showtime!=1) + goto mib_poll_end; + ATUR_PERF_STAT_SESL_FLAG_MAKECMV; + if(meiCMV(TxMessage, YES_REPLY)!=MEI_SUCCESS){ +#ifdef AMAZON_MEI_DEBUG_ON + printk("\n\nCMV fail, Group 7 Address 34 Index 0"); +#endif + } + else{ + temp = RxMessage[4] - mib_pread.ATUR_PERF_STAT_SESL; + if(temp>=0){ + current_intvl->AtucPerfStatUasL+=temp; + ATUC_PERF_STAT_UASL+=temp; + mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4]; + } + else{ + current_intvl->AtucPerfStatUasL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4]; + ATUC_PERF_STAT_UASL+=0xffff - mib_pread.ATUR_PERF_STAT_SESL + RxMessage[4]; + mib_pread.ATUR_PERF_STAT_SESL = RxMessage[4]; + } + } + +#endif +mib_poll_end: + up(&mei_sema); + + do_gettimeofday(&time_fini); + i = ((int)((time_fini.tv_sec-time_now.tv_sec)*1000)) + ((int)((time_fini.tv_usec-time_now.tv_usec)/1000)) ; //msec + }//showtime==1 + } + +} +int mib_poll_init(void) +{ + printk("Starting mib_poll...\n"); + + kernel_thread(adsl_mib_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); + return 0; +} +#endif //IFX_SMALL_FOOTPRINT +//EXPORT_NO_SYMBOLS; + +#ifdef ADSL_LED_SUPPORT +// adsl led -start +int led_status_on=0,led_need_to_flash=0; +int led_current_flashing=0; +unsigned long led_delay=0; +static int led_poll(void *unused) +{ + stop_led_module=0; //begin polling ... + while(!stop_led_module){ + if ((!led_status_on)&&(!led_need_to_flash)) interruptible_sleep_on_timeout (&wait_queue_led_polling,1000); //10 seconds timeout for waiting wakeup +// else printk("direct running task, no waiting"); + run_task_queue(&tq_ifx_led);//joelin task +// printk("led and LOP polling...\n"); + } + return 0; +} +static int led_poll_init(void) +{ +// printk("Starting adsl led polling...\n"); + +//warning-led-start +// CLEAR_BIT((*((volatile u32 *)0xB0100B40)), 0x40); //Warning LED GPIO ON +//warning-led-end + + kernel_thread(led_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); + return 0; +} + +int adsl_led_flash(void) +{ + int i; + if (!firmware_support_led) return 0; //joelin version check + + if (led_status_on == 0 && led_need_to_flash == 0) + { + queue_task(&led_task, &tq_ifx_led);//joelin task + wake_up_interruptible(&wait_queue_led_polling); //wake up and clean led module +// printk("queue Task 1...\n"); //joelin test + } + led_need_to_flash=1;//asking to flash led + + return 0; +} + +int adsl_led_flash_task(void *ptr) +{ + + u16 one=1; + u16 zero=0; + u16 data=0x0600; + int kernel_use=1; + u16 CMVMSG[MSG_LENGTH]; +//adsl-led-start for >v1.1.2.7.1.1 +// printk("Task Running...\n"); //joelin test + if ((firmware_support_led==2)&&(led_support_check)) + { + led_support_check=0; + data=0x0600; + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 0, 1, &data,CMVMSG); //configure GPIO9 GPIO10 as outputs + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 2, 1, &data,CMVMSG); //enable writing to bit 9 and bit10 + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + + data=0x0a01; + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 4, 1, &data,CMVMSG); //use GPIO10 for TR68 .Enable and don't invert. + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + +#ifdef DATA_LED_ON_MODE + data=0x0903;//tecom //use GPIO9 for TR68 data led .turn on. +#else + data=0x0900; +#endif + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 5, 1, &data,CMVMSG); //use GPIO9 for TR68 data led .turn off. + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, CMVMSG); + + } + if (!showtime) {led_need_to_flash=0; return 0;} +//adsl-led-end for >v1.1.2.7.1.1 + + if (led_status_on == 0 || led_need_to_flash == 1) + { + + if (led_current_flashing==0) + { + if (firmware_support_led==1){//>1.1.2.3.1.1 + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 0, 1, &one,CMVMSG); //flash + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG); + } + else if (firmware_support_led==2){//>1.1.2.7.1.1 + data=0x0901;//flash + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 5, 1, &data,CMVMSG); //use GPIO9 for TR68 data led .flash. + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG); + + }//(firmware_support_led==2) + led_current_flashing = 1;//turn on led + } + led_status_on=1; + + do{//do nothing , waiting untill no data traffic + led_need_to_flash=0; + interruptible_sleep_on_timeout(&wait_queue_led, 25); //the time for LED Off , if no data traffic + }while(led_need_to_flash==1); + + }else if (led_status_on == 1 && led_need_to_flash==0) + { + if (led_current_flashing==1) + {//turn off led + if (firmware_support_led==1){//>1.1.2.3.1.1 + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 0, 1, &zero,CMVMSG);//off + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG); + } //>1.1.2.3.1.1 + else if (firmware_support_led==2){//>1.1.2.7.1.1 +#ifdef DATA_LED_ON_MODE + data=0x0903;//tecom //use GPIO9 for TR68 data led .turn on. +#else + data=0x0900;//off +#endif + makeCMV_local(H2D_CMV_WRITE, INFO, 91, 5, 1, &data,CMVMSG); //use GPIO9 for TR68 data led .off. + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_CMV_WINHOST, &CMVMSG); + + }//(firmware_support_led==2) + led_status_on=0; + led_current_flashing = 0; + } + } + + if (led_status_on == 1 || led_need_to_flash) + {//led flash job on going or led need to flash + queue_task(&led_task, &tq_ifx_led); //joelin task +// printk("queue Task 2...\n"); //joelin test + } + return 0; +} +//joelin adsl led-end +#else +int adsl_led_flash(void) +{ + return 0; +} +#endif //ADSL_LED_SUPPORT +#ifdef IFX_DYING_GASP +static int lop_poll(void *unused) +{ + + while(1) + { + interruptible_sleep_on_timeout(&wait_queue_dying_gasp, 1); +#ifdef CONFIG_CPU_AMAZON_E //000003:fchang + if(showtime&&((*((volatile u32 *)0xB0100B14))&0x4)==0x0) {//000003:fchang +#else //000003:fchang + if(showtime&&((*((volatile u32 *)0xB0100B44))&0x8000)==0x0) { +#endif //CONFIG_CPU_AMAZON_E + mei_ioctl((struct inode *)0,NULL, AMAZON_MEI_WRITEDEBUG, &lop_debugwr); + printk("send dying gasp..\n");} + + } + return 0; + } +static int lop_poll_init(void) +{ +// printk("Starting LOP polling...\n"); + kernel_thread(lop_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); + return 0; +} + +#endif //IFX_DYING_GASP + +//joelin 04/16/2005-satrt +static int unavailable_seconds_poll(void *unused) +{ + while(1){ + interruptible_sleep_on_timeout (&wait_queue_uas_poll,100); //1 second timeout for waiting wakeup + if (!showtime) unavailable_seconds++; + } + return 0; +} +static int unavailable_seconds_poll_init(void) +{ + + kernel_thread(unavailable_seconds_poll, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); + return 0; +} + + +//joelin 04/16/2005-end +EXPORT_SYMBOL(meiDebugWrite); +EXPORT_SYMBOL(ifx_pop_eoc); + +MODULE_LICENSE("GPL"); + +module_init(amazon_mei_init_module); +module_exit(amazon_mei_cleanup_module); + diff --git a/target/linux/amazon/files/drivers/char/ifx_ssc.c b/target/linux/amazon/files/drivers/char/ifx_ssc.c new file mode 100644 index 0000000000..ea01659a94 --- /dev/null +++ b/target/linux/amazon/files/drivers/char/ifx_ssc.c @@ -0,0 +1,2121 @@ +/************************************************** + * + * drivers/ifx/serial/ifx_ssc.c + * + * Driver for IFX_SSC serial ports + * + * Copyright (C) 2004 Infineon Technologies AG + * Author Michael Schoenenborn (IFX COM TI BT) + * + */ +#define IFX_SSC_DRV_VERSION "0.2.1" +/* + ************************************************** + * + * This driver was originally based on the INCA-IP driver, but due to + * fundamental conceptual drawbacks there has been changed a lot. + * + * Based on INCA-IP driver Copyright (c) 2003 Gary Jennejohn <gj@denx.de> + * Based on the VxWorks drivers Copyright (c) 2002, Infineon Technologies. + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +// ### TO DO: general issues: +// - power management +// - interrupt handling (direct/indirect) +// - pin/mux-handling (just overall concept due to project dependency) +// - multiple instances capability +// - slave functionality + +/* + * Include section + */ +#ifndef EXPORT_SYMTAB +#define EXPORT_SYMTAB +#endif + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/timer.h> +#include <linux/interrupt.h> +#include <linux/major.h> +#include <linux/string.h> +#include <linux/fs.h> +#include <linux/proc_fs.h> +#include <linux/fcntl.h> +#include <linux/ptrace.h> +#include <linux/mm.h> +#include <linux/ioport.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/spinlock.h> +#include <linux/slab.h> +//#include <linux/poll.h> + +#include <asm/system.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/uaccess.h> +#include <asm/bitops.h> + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/version.h> + +#include <asm/amazon/amazon.h> +#include <asm/amazon/irq.h> +#include <asm/amazon/ifx_ssc_defines.h> +#include <asm/amazon/ifx_ssc.h> + +#ifdef SSC_FRAME_INT_ENABLE +#undef SSC_FRAME_INT_ENABLE +#endif + +#define not_yet + +#define SPI_VINETIC + +/* + * Deal with CONFIG_MODVERSIONS + */ +#if CONFIG_MODVERSIONS==1 +# include <linux/modversions.h> +#endif + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Michael Schoenenborn"); +MODULE_DESCRIPTION("IFX SSC driver"); +MODULE_SUPPORTED_DEVICE("ifx_ssc"); +MODULE_PARM(maj, "i"); +MODULE_PARM_DESC(maj, "Major device number"); + +/* allow the user to set the major device number */ +static int maj = 0; + + +/* + * This is the per-channel data structure containing pointers, flags + * and variables for the port. This driver supports a maximum of PORT_CNT. + * isp is allocated in ifx_ssc_init() based on the chip version. + */ +static struct ifx_ssc_port *isp; + +/* prototypes for fops */ +static ssize_t ifx_ssc_read(struct file *, char *, size_t, loff_t *); +static ssize_t ifx_ssc_write(struct file *, const char *, size_t, loff_t *); +//static unsigned int ifx_ssc_poll(struct file *, struct poll_table_struct *); +int ifx_ssc_ioctl(struct inode *, struct file *, unsigned int, unsigned long); +int ifx_ssc_open(struct inode *, struct file *); +int ifx_ssc_close(struct inode *, struct file *); + +/* other forward declarations */ +static unsigned int ifx_ssc_get_kernel_clk(struct ifx_ssc_port *info); +static void ifx_ssc_rx_int(int, void *, struct pt_regs *); +static void ifx_ssc_tx_int(int, void *, struct pt_regs *); +static void ifx_ssc_err_int(int, void *, struct pt_regs *); +#ifdef SSC_FRAME_INT_ENABLE +static void ifx_ssc_frm_int(int, void *, struct pt_regs *); +#endif +static void tx_int(struct ifx_ssc_port *); +static int ifx_ssc1_read_proc(char *, char **, off_t, int, int *, void *); +static void ifx_gpio_init(void); +/************************************************************************ + * Function declaration + ************************************************************************/ +//interrupt.c +extern unsigned int amazon_get_fpi_hz(void); +extern void disable_amazon_irq(unsigned int irq_nr); +extern void enable_amazon_irq(unsigned int irq_nr); +extern void mask_and_ack_amazon_irq(unsigned int irq_nr); + + +/*****************************************************************/ +typedef struct { + int (*request)(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char * devname, + void *dev_id); + void (*free)(unsigned int irq, void *dev_id); + void (*enable)(unsigned int irq); + void (*disable)(unsigned int irq); + void (*clear)(unsigned int irq); +} ifx_int_wrapper_t; + +static ifx_int_wrapper_t ifx_int_wrapper = { + request: request_irq, // IM action: enable int + free: free_irq, // IM action: disable int + enable: enable_amazon_irq, + disable: disable_amazon_irq, + clear: mask_and_ack_amazon_irq, + //end: +}; + +/* Fops-struct */ +static struct file_operations ifx_ssc_fops = { + owner: THIS_MODULE, + read: ifx_ssc_read, /* read */ + write: ifx_ssc_write, /* write */ +// poll: ifx_ssc_poll, /* poll */ + ioctl: ifx_ssc_ioctl, /* ioctl */ + open: ifx_ssc_open, /* open */ + release: ifx_ssc_close, /* release */ +}; + + +static inline unsigned int ifx_ssc_get_kernel_clk(struct ifx_ssc_port *info) +{ // ATTENTION: This function assumes that the CLC register is set with the + // appropriate value for RMC. + unsigned int rmc; + + rmc = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CLC) & + IFX_CLC_RUN_DIVIDER_MASK) >> IFX_CLC_RUN_DIVIDER_OFFSET; + if (rmc == 0){ + printk("ifx_ssc_get_kernel_clk rmc==0 \n"); + return (0); + } + return (amazon_get_fpi_hz() / rmc); +} + +#ifndef not_yet +#ifdef IFX_SSC_INT_USE_BH +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver + * (also known as the "bottom half"). This can be called any + * number of times for any channel without harm. + */ +static inline void +ifx_ssc_sched_event(struct ifx_ssc_port *info, int event) +{ + info->event |= 1 << event; /* remember what kind of event and who */ + queue_task(&info->tqueue, &tq_cyclades); /* it belongs to */ + mark_bh(CYCLADES_BH); /* then trigger event */ +} /* ifx_ssc_sched_event */ + + +/* + * This routine is used to handle the "bottom half" processing for the + * serial driver, known also the "software interrupt" processing. + * This processing is done at the kernel interrupt level, after the + * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This + * is where time-consuming activities which can not be done in the + * interrupt driver proper are done; the interrupt driver schedules + * them using ifx_ssc_sched_event(), and they get done here. + * + * This is done through one level of indirection--the task queue. + * When a hardware interrupt service routine wants service by the + * driver's bottom half, it enqueues the appropriate tq_struct (one + * per port) to the tq_cyclades work queue and sets a request flag + * via mark_bh for processing that queue. When the time is right, + * do_ifx_ssc_bh is called (because of the mark_bh) and it requests + * that the work queue be processed. + * + * Although this may seem unwieldy, it gives the system a way to + * pass an argument (in this case the pointer to the ifx_ssc_port + * structure) to the bottom half of the driver. Previous kernels + * had to poll every port to see if that port needed servicing. + */ +static void +do_ifx_ssc_bh(void) +{ + run_task_queue(&tq_cyclades); +} /* do_ifx_ssc_bh */ + +static void +do_softint(void *private_) +{ + struct ifx_ssc_port *info = (struct ifx_ssc_port *) private_; + + if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { + wake_up_interruptible(&info->open_wait); + info->flags &= ~(ASYNC_NORMAL_ACTIVE| + ASYNC_CALLOUT_ACTIVE); + } + if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) { + wake_up_interruptible(&info->open_wait); + } + if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) { + wake_up_interruptible(&info->delta_msr_wait); + } + if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { + wake_up_interruptible(&tty->write_wait); + } +#ifdef Z_WAKE + if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) { + wake_up_interruptible(&info->shutdown_wait); + } +#endif +} /* do_softint */ +#endif /* IFX_SSC_INT_USE_BH */ +#endif // not_yet + +inline static void +rx_int(struct ifx_ssc_port *info) +{ + int fifo_fill_lev, bytes_in_buf, i; + unsigned long tmp_val; + unsigned long *tmp_ptr; + unsigned int rx_valid_cnt; + /* number of words waiting in the RX FIFO */ + fifo_fill_lev = (READ_PERIPHERAL_REGISTER(info->mapbase + + IFX_SSC_FSTAT) & + IFX_SSC_FSTAT_RECEIVED_WORDS_MASK) >> + IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET; + // Note: There are always 32 bits in a fifo-entry except for the last + // word of a contigous transfer block and except for not in rx-only + // mode and CON.ENBV set. But for this case it should be a convention + // in software which helps: + // In tx or rx/tx mode all transfers from the buffer to the FIFO are + // 32-bit wide, except for the last three bytes, which could be a + // combination of 16- and 8-bit access. + // => The whole block is received as 32-bit words as a contigous stream, + // even if there was a gap in tx which has the fifo run out of data! + // Just the last fifo entry *may* be partially filled (0, 1, 2 or 3 bytes)! + + /* free space in the RX buffer */ + bytes_in_buf = info->rxbuf_end - info->rxbuf_ptr; + // transfer with 32 bits per entry + while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0)) { + tmp_ptr = (unsigned long *)info->rxbuf_ptr; + *tmp_ptr = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RB); + info->rxbuf_ptr += 4; + info->stats.rxBytes += 4; + fifo_fill_lev --; + bytes_in_buf -= 4; + } // while ((bytes_in_buf >= 4) && (fifo_fill_lev > 0)) + // now do the rest as mentioned in STATE.RXBV + while ((bytes_in_buf > 0) && (fifo_fill_lev > 0)) { + rx_valid_cnt = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & + IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> + IFX_SSC_STATE_RX_BYTE_VALID_OFFSET; + if (rx_valid_cnt == 0) break; + if (rx_valid_cnt > bytes_in_buf) { + // ### TO DO: warning message: not block aligned data, other data + // in this entry will be lost + rx_valid_cnt = bytes_in_buf; + } + tmp_val = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RB); + + for (i=0; i<rx_valid_cnt; i++) { + *info->rxbuf_ptr = (tmp_val >> ( 8 * (rx_valid_cnt - i-1))) & 0xff; +/* + *info->rxbuf_ptr = tmp_val & 0xff; + tmp_val >>= 8; +*/ + bytes_in_buf--; + + + info->rxbuf_ptr++; + } + info->stats.rxBytes += rx_valid_cnt; + } // while ((bytes_in_buf > 0) && (fifo_fill_lev > 0)) + + // check if transfer is complete + if (info->rxbuf_ptr >= info->rxbuf_end) { + ifx_int_wrapper.disable(info->rxirq); + /* wakeup any processes waiting in read() */ + wake_up_interruptible(&info->rwait); + /* and in poll() */ + //wake_up_interruptible(&info->pwait); + } else if ((info->opts.modeRxTx == IFX_SSC_MODE_RX) && + (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) == 0)) { + // if buffer not filled completely and rx request done initiate new transfer +/* + if (info->rxbuf_end - info->rxbuf_ptr < 65536) +*/ + if (info->rxbuf_end - info->rxbuf_ptr < IFX_SSC_RXREQ_BLOCK_SIZE) + WRITE_PERIPHERAL_REGISTER((info->rxbuf_end - info->rxbuf_ptr) << + IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + else + WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + } +} // rx_int + +inline static void +tx_int(struct ifx_ssc_port *info) +{ + + int fifo_space, fill, i; + fifo_space = ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_ID) & + IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET) - + ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_FSTAT) & + IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK) >> + IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET); + + if (fifo_space == 0) + return; + + fill = info->txbuf_end - info->txbuf_ptr; + + if (fill > fifo_space * 4) + fill = fifo_space * 4; + + for (i = 0; i < fill / 4; i++) { + // at first 32 bit access + WRITE_PERIPHERAL_REGISTER(*(UINT32 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB); + info->txbuf_ptr += 4; + } + + fifo_space -= fill / 4; + info->stats.txBytes += fill & ~0x3; + fill &= 0x3; + if ((fifo_space > 0) & (fill > 1)) { + // trailing 16 bit access + WRITE_PERIPHERAL_REGISTER_16(*(UINT16 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB); + info->txbuf_ptr += 2; + info->stats.txBytes += 2; + fifo_space --; +/* added by bingtao */ + fill -=2; + } + if ((fifo_space > 0) & (fill > 0)) { + // trailing 8 bit access + WRITE_PERIPHERAL_REGISTER_8(*(UINT8 *)info->txbuf_ptr, info->mapbase + IFX_SSC_TB); + info->txbuf_ptr ++; + info->stats.txBytes ++; +/* + fifo_space --; +*/ + } + + // check if transmission complete + if (info->txbuf_ptr >= info->txbuf_end) { + ifx_int_wrapper.disable(info->txirq); + kfree(info->txbuf); + info->txbuf = NULL; + /* wake up any process waiting in poll() */ + //wake_up_interruptible(&info->pwait); + } + +} // tx_int + +static void +ifx_ssc_rx_int(int irq, void *dev_id, struct pt_regs *regs) +{ + struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id; + //WRITE_PERIPHERAL_REGISTER(IFX_SSC_R_BIT, info->mapbase + IFX_SSC_IRN_CR); + rx_int(info); +} + +static void +ifx_ssc_tx_int(int irq, void *dev_id, struct pt_regs *regs) +{ + struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id; + //WRITE_PERIPHERAL_REGISTER(IFX_SSC_T_BIT, info->mapbase + IFX_SSC_IRN_CR); + tx_int(info); +} + +static void +ifx_ssc_err_int(int irq, void *dev_id, struct pt_regs *regs) +{ + struct ifx_ssc_port *info = (struct ifx_ssc_port *)dev_id; + unsigned int state; + unsigned int write_back = 0; + unsigned long flags; + + + local_irq_save(flags); + state = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE); + + if ((state & IFX_SSC_STATE_RX_UFL) != 0) { + info->stats.rxUnErr++; + write_back |= IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR; + } + if ((state & IFX_SSC_STATE_RX_OFL) != 0) { + info->stats.rxOvErr++; + write_back |= IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR; + } + if ((state & IFX_SSC_STATE_TX_OFL) != 0) { + info->stats.txOvErr++; + write_back |= IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR; + } + if ((state & IFX_SSC_STATE_TX_UFL) != 0) { + info->stats.txUnErr++; + write_back |= IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR; + } +// if ((state & IFX_SSC_STATE_ABORT_ERR) != 0) { +// info->stats.abortErr++; +// write_back |= IFX_SSC_WHBSTATE_CLR_ABORT_ERROR; +// } + if ((state & IFX_SSC_STATE_MODE_ERR) != 0) { + info->stats.modeErr++; + write_back |= IFX_SSC_WHBSTATE_CLR_MODE_ERROR; + } + + if (write_back) + WRITE_PERIPHERAL_REGISTER(write_back, + info->mapbase + IFX_SSC_WHBSTATE); + + local_irq_restore(flags); +} + +#ifdef SSC_FRAME_INT_ENABLE +static void +ifx_ssc_frm_int(int irq, void *dev_id, struct pt_regs *regs) +{ + // ### TO DO: wake up framing wait-queue in conjunction with batch execution +} +#endif + +static void +ifx_ssc_abort(struct ifx_ssc_port *info) +{ + unsigned long flags; + bool enabled; + + local_irq_save(flags); + + // disable all int's + ifx_int_wrapper.disable(info->rxirq); + ifx_int_wrapper.disable(info->txirq); + ifx_int_wrapper.disable(info->errirq); +/* + ifx_int_wrapper.disable(info->frmirq); +*/ + local_irq_restore(flags); + + // disable SSC (also aborts a receive request!) + // ### TO DO: Perhaps it's better to abort after the receiption of a + // complete word. The disable cuts the transmission immediatly and + // releases the chip selects. This could result in unpredictable + // behavior of connected external devices! + enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) + & IFX_SSC_STATE_IS_ENABLED) != 0; + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + + // flush fifos + WRITE_PERIPHERAL_REGISTER(IFX_SSC_XFCON_FIFO_FLUSH, + info->mapbase + IFX_SSC_TXFCON); + WRITE_PERIPHERAL_REGISTER(IFX_SSC_XFCON_FIFO_FLUSH, + info->mapbase + IFX_SSC_RXFCON); + + // free txbuf + if (info->txbuf != NULL) { + kfree(info->txbuf); + info->txbuf = NULL; + } + + // wakeup read process + if (info->rxbuf != NULL) + wake_up_interruptible(&info->rwait); + + // clear pending int's + ifx_int_wrapper.clear(info->rxirq); + ifx_int_wrapper.clear(info->txirq); + ifx_int_wrapper.clear(info->errirq); +/* + ifx_int_wrapper.clear(info->frmirq); +*/ + + // clear error flags + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, + info->mapbase + IFX_SSC_WHBSTATE); + + //printk("IFX SSC%d: Transmission aborted\n", info->port_nr); + // enable SSC + if (enabled) + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + +} // ifx_ssc_abort + + +/* + * This routine is called whenever a port is opened. It enforces + * exclusive opening of a port and enables interrupts, etc. + */ +int +ifx_ssc_open(struct inode *inode, struct file * filp) +{ + struct ifx_ssc_port *info; + int line; + int from_kernel = 0; + + if ((inode == (struct inode *)0) || (inode == (struct inode *)1)) { + from_kernel = 1; + line = (int)inode; + } + else { + line = MINOR(filp->f_dentry->d_inode->i_rdev); + filp->f_op = &ifx_ssc_fops; + } + + /* don't open more minor devices than we can support */ + if (line < 0 || line >= PORT_CNT) + return -ENXIO; + + info = &isp[line]; + + /* exclusive open */ + if (info->port_is_open != 0) + return -EBUSY; + info->port_is_open++; + + ifx_int_wrapper.disable(info->rxirq); + ifx_int_wrapper.disable(info->txirq); + ifx_int_wrapper.disable(info->errirq); +/* + ifx_int_wrapper.disable(info->frmirq); +*/ + + /* Flush and enable TX/RX FIFO */ + WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_TXFIFO_FL << + IFX_SSC_XFCON_ITL_OFFSET) | + IFX_SSC_XFCON_FIFO_FLUSH | + IFX_SSC_XFCON_FIFO_ENABLE, + info->mapbase + IFX_SSC_TXFCON); + WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_RXFIFO_FL << + IFX_SSC_XFCON_ITL_OFFSET) | + IFX_SSC_XFCON_FIFO_FLUSH | + IFX_SSC_XFCON_FIFO_ENABLE, + info->mapbase + IFX_SSC_RXFCON); + + + /* logically flush the software FIFOs */ + info->rxbuf_ptr = 0; + info->txbuf_ptr = 0; + + /* clear all error bits */ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ALL_ERROR, + info->mapbase + IFX_SSC_WHBSTATE); + + // clear pending interrupts + ifx_int_wrapper.clear(info->rxirq); + ifx_int_wrapper.clear(info->txirq); + ifx_int_wrapper.clear(info->errirq); +/* + ifx_int_wrapper.clear(info->frmirq); +*/ + + // enable SSC + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + MOD_INC_USE_COUNT; + + return 0; +} /* ifx_ssc_open */ +EXPORT_SYMBOL(ifx_ssc_open); + +/* + * This routine is called when a particular device is closed. + */ +int +ifx_ssc_close(struct inode *inode, struct file *filp) +{ + struct ifx_ssc_port *info; + int idx; + + if ((inode == (struct inode *)0) || (inode == (struct inode *)1)) + idx = (int)inode; + else + idx = MINOR(filp->f_dentry->d_inode->i_rdev); + + if (idx < 0 || idx >= PORT_CNT) + return -ENXIO; + + info = &isp[idx]; + if (!info) + return -ENXIO; + + // disable SSC + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + // call abort function to disable int's, flush fifos... + ifx_ssc_abort(info); + + info->port_is_open --; + MOD_DEC_USE_COUNT; + + return 0; +} /* ifx_ssc_close */ +EXPORT_SYMBOL(ifx_ssc_close); + +/* added by bingtao */ +/* helper routine to handle reads from the kernel or user-space */ +/* info->rxbuf : never kfree and contains valid data */ +/* should be points to NULL after copying data !!! */ +static ssize_t +ifx_ssc_read_helper_poll(struct ifx_ssc_port *info, char *buf, size_t len, + int from_kernel) +{ + ssize_t ret_val; + unsigned long flags; + + if (info->opts.modeRxTx == IFX_SSC_MODE_TX) + return -EFAULT; + local_irq_save(flags); + info->rxbuf_ptr = info->rxbuf; + info->rxbuf_end = info->rxbuf + len; + local_irq_restore(flags); +/* Vinetic driver always works in IFX_SSC_MODE_RXTX */ +/* TXRX in poll mode */ + while (info->rxbuf_ptr < info->rxbuf_end){ +/* This is the key point, if you don't check this condition + kfree (NULL) will happen + because tx only need write into FIFO, it's much fast than rx + So when rx still waiting , tx already finish and release buf +*/ + if (info->txbuf_ptr < info->txbuf_end) { + tx_int(info); + } + + rx_int(info); + }; + + ret_val = info->rxbuf_ptr - info->rxbuf; + return (ret_val); +} // ifx_ssc_read_helper_poll + +/* helper routine to handle reads from the kernel or user-space */ +/* info->rx_buf : never kfree and contains valid data */ +/* should be points to NULL after copying data !!! */ +static ssize_t +ifx_ssc_read_helper(struct ifx_ssc_port *info, char *buf, size_t len, + int from_kernel) +{ + ssize_t ret_val; + unsigned long flags; + DECLARE_WAITQUEUE(wait, current); + + if (info->opts.modeRxTx == IFX_SSC_MODE_TX) + return -EFAULT; + local_irq_save(flags); + info->rxbuf_ptr = info->rxbuf; + info->rxbuf_end = info->rxbuf + len; + if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) { + if ((info->txbuf == NULL) || + (info->txbuf != info->txbuf_ptr) || + (info->txbuf_end != len + info->txbuf)) { + local_irq_restore(flags); + printk("IFX SSC - %s: write must be called before calling " + "read in combined RX/TX!\n", __FUNCTION__); + return -EFAULT; + } + local_irq_restore(flags); + /* should enable tx, right?*/ + tx_int(info); + if (info->txbuf_ptr < info->txbuf_end){ + ifx_int_wrapper.enable(info->txirq); + } + + ifx_int_wrapper.enable(info->rxirq); + } else { // rx mode + local_irq_restore(flags); + if (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) & + IFX_SSC_RXCNT_TODO_MASK) + return -EBUSY; + ifx_int_wrapper.enable(info->rxirq); + // rx request limited to ' bytes +/* + if (len < 65536) +*/ + if (len < IFX_SSC_RXREQ_BLOCK_SIZE) + WRITE_PERIPHERAL_REGISTER(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + else + WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + } + + __add_wait_queue(&info->rwait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + // wakeup done in rx_int + + do { + local_irq_save(flags); + if (info->rxbuf_ptr >= info->rxbuf_end) + break; + local_irq_restore(flags); + +// if (filp->f_flags & O_NONBLOCK) +// { +// N = -EAGAIN; +// goto out; +// } + if (signal_pending(current)) { + ret_val = -ERESTARTSYS; + goto out; + } + schedule(); + } while (1); + + ret_val = info->rxbuf_ptr - info->rxbuf; // should be equal to len + local_irq_restore(flags); + + out: + current->state = TASK_RUNNING; + __remove_wait_queue(&info->rwait, &wait); + return (ret_val); +} // ifx_ssc_read_helper + + +#if 0 +/* helper routine to handle reads from the kernel or user-space */ +/* appropriate in interrupt context */ +static ssize_t +ifx_ssc_read_helper(struct ifx_ssc_port *info, char *buf, size_t len, + int from_kernel) +{ + ssize_t ret_val; + unsigned long flags; + DECLARE_WAITQUEUE(wait, current); + + if (info->opts.modeRxTx == IFX_SSC_MODE_TX) + return -EFAULT; + local_irq_save(flags); + info->rxbuf_ptr = info->rxbuf; + info->rxbuf_end = info->rxbuf + len; + if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) { + if ((info->txbuf == NULL) || + (info->txbuf != info->txbuf_ptr) || + (info->txbuf_end != len + info->txbuf)) { + local_irq_restore(flags); + printk("IFX SSC - %s: write must be called before calling " + "read in combined RX/TX!\n", __FUNCTION__); + return -EFAULT; + } + local_irq_restore(flags); + /* should enable tx, right?*/ + tx_int(info); + if (!in_irq()){ + if (info->txbuf_ptr < info->txbuf_end){ + ifx_int_wrapper.enable(info->txirq); + } + ifx_int_wrapper.enable(info->rxirq); + } + } else { // rx mode + local_irq_restore(flags); + if (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) & + IFX_SSC_RXCNT_TODO_MASK) + return -EBUSY; + if (!in_irq()){ + ifx_int_wrapper.enable(info->rxirq); + } + + if (len < IFX_SSC_RXREQ_BLOCK_SIZE) + WRITE_PERIPHERAL_REGISTER(len << IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + else + WRITE_PERIPHERAL_REGISTER(IFX_SSC_RXREQ_BLOCK_SIZE << IFX_SSC_RXREQ_RXCOUNT_OFFSET, + info->mapbase + IFX_SSC_RXREQ); + } + if (in_irq()){ + do { + rx_int(info); + if (info->opts.modeRxTx == IFX_SSC_MODE_RXTX) { + tx_int(info); + } + + if (info->rxbuf_ptr >= info->rxbuf_end) + break; + } while (1); + ret_val = info->rxbuf_ptr - info->rxbuf; + }else{ + __add_wait_queue(&info->rwait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + // wakeup done in rx_int + + do { + local_irq_save(flags); + if (info->rxbuf_ptr >= info->rxbuf_end) + break; + local_irq_restore(flags); + + if (signal_pending(current)) { + ret_val = -ERESTARTSYS; + goto out; + } + schedule(); + } while (1); + + ret_val = info->rxbuf_ptr - info->rxbuf; // should be equal to len + local_irq_restore(flags); + + out: + current->state = TASK_RUNNING; + __remove_wait_queue(&info->rwait, &wait); + } + return (ret_val); +} // ifx_ssc_read_helper +#endif + +/* helper routine to handle writes to the kernel or user-space */ +/* info->txbuf has two cases: + * 1) return value < 0 (-EFAULT), not touched at all + * 2) kfree and points to NULL in interrupt routine (but maybe later ) + */ +static ssize_t +ifx_ssc_write_helper(struct ifx_ssc_port *info, const char *buf, + size_t len, int from_kernel) +{ + // check if in tx or tx/rx mode + if (info->opts.modeRxTx == IFX_SSC_MODE_RX) + return -EFAULT; + + info->txbuf_ptr = info->txbuf; + info->txbuf_end = len + info->txbuf; + /* start the transmission (not in rx/tx, see read helper) */ + if (info->opts.modeRxTx == IFX_SSC_MODE_TX) { + tx_int(info); + if (info->txbuf_ptr < info->txbuf_end){ + ifx_int_wrapper.enable(info->txirq); + } + } + //local_irq_restore(flags); + return len; +} + +/* + * kernel interfaces for read and write. + * The caller must set port to: n for SSC<m> with n=m-1 (e.g. n=0 for SSC1) + */ +ssize_t +ifx_ssc_kread(int port, char *kbuf, size_t len) +{ + struct ifx_ssc_port *info; + ssize_t ret_val; + + if (port < 0 || port >= PORT_CNT) + return -ENXIO; + + if (len == 0) + return 0; + + info = &isp[port]; + + // check if reception in progress + if (info->rxbuf != NULL){ + printk("SSC device busy\n"); + return -EBUSY; + } + + info->rxbuf = kbuf; + if (info->rxbuf == NULL){ + printk("SSC device error\n"); + return -EINVAL; + } + +/* changed by bingtao */ + /* change by TaiCheng */ + //if (!in_irq()){ + if (0){ + ret_val = ifx_ssc_read_helper(info, kbuf, len, 1); + }else{ + ret_val = ifx_ssc_read_helper_poll(info, kbuf, len, 1); + }; + info->rxbuf = NULL; + + // ### TO DO: perhaps warn if ret_val != len + ifx_int_wrapper.disable(info->rxirq); + + return (ret_val); +} // ifx_ssc_kread +EXPORT_SYMBOL(ifx_ssc_kread); + +ssize_t +ifx_ssc_kwrite(int port, const char *kbuf, size_t len) +{ + struct ifx_ssc_port *info; + ssize_t ret_val; + + if (port < 0 || port >= PORT_CNT) + return -ENXIO; + + if (len == 0) + return 0; + + info = &isp[port]; + + // check if transmission in progress + if (info->txbuf != NULL) + return -EBUSY; + info->txbuf = (char *)kbuf; + + ret_val = ifx_ssc_write_helper(info, info->txbuf, len, 1); + if (ret_val < 0){ + info->txbuf = NULL; + } + return ret_val; +} +EXPORT_SYMBOL(ifx_ssc_kwrite); + + +/* + * user interfaces to read and write + */ +static ssize_t +ifx_ssc_read(struct file *filp, char *ubuf, size_t len, loff_t *off) +{ + ssize_t ret_val; + int idx; + struct ifx_ssc_port *info; + +/* + if (len == 0) + return (0); +*/ + idx = MINOR(filp->f_dentry->d_inode->i_rdev); + info = &isp[idx]; + + // check if reception in progress + if (info->rxbuf != NULL) + return -EBUSY; + + info->rxbuf = kmalloc(len+ 3, GFP_KERNEL); + if (info->rxbuf == NULL) + return -ENOMEM; + + ret_val = ifx_ssc_read_helper(info, info->rxbuf, len, 0); + // ### TO DO: perhaps warn if ret_val != len + if (copy_to_user((void*)ubuf, info->rxbuf, ret_val) != 0) + ret_val = -EFAULT; + + ifx_int_wrapper.disable(info->rxirq); + + kfree(info->rxbuf); + info->rxbuf = NULL; + return (ret_val); +} // ifx_ssc_read + +/* + * As many bytes as we have free space for are copied from the user + * into txbuf and the actual byte count is returned. The transmission is + * always kicked off by calling the appropriate TX routine. + */ +static ssize_t +ifx_ssc_write(struct file *filp, const char *ubuf, size_t len, loff_t *off) +{ + int idx; + struct ifx_ssc_port *info; + int ret_val; + + if (len == 0) + return (0); + + idx = MINOR(filp->f_dentry->d_inode->i_rdev); + info = &isp[idx]; + + // check if transmission in progress + if (info->txbuf != NULL) + return -EBUSY; + + info->txbuf = kmalloc(len+ 3, GFP_KERNEL); + if (info->txbuf == NULL) + return -ENOMEM; + + ret_val = copy_from_user(info->txbuf, ubuf, len); + if (ret_val == 0) + ret_val = ifx_ssc_write_helper(info, info->txbuf, len, 0); + else + ret_val = -EFAULT; + if (ret_val < 0) { + kfree(info->txbuf); // otherwise will be done in ISR + info->txbuf = NULL; + } + return (ret_val); +} /* ifx_ssc_write */ + + +/* + * ------------------------------------------------------------ + * ifx_ssc_ioctl() and friends + * ------------------------------------------------------------ + */ + +/*----------------------------------------------------------------------------- + FUNC-NAME : ifx_ssc_frm_status_get + LONG-NAME : framing status get + PURPOSE : Get the actual status of the framing. + + PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. + + RESULT : pointer to a structure ifx_ssc_frm_status which holds busy and + count values. + + REMARKS : Returns a register value independent of framing is enabled or + not! Changes structure inside of info, so the return value isn't + needed at all, but could be used for simple access. +-----------------------------------------------------------------------------*/ +static struct ifx_ssc_frm_status * +ifx_ssc_frm_status_get(struct ifx_ssc_port *info) +{ + unsigned long tmp; + + tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFSTAT); + info->frm_status.DataBusy = (tmp & IFX_SSC_SFSTAT_IN_DATA) > 0; + info->frm_status.PauseBusy = (tmp & IFX_SSC_SFSTAT_IN_PAUSE) > 0; + info->frm_status.DataCount = (tmp & IFX_SSC_SFSTAT_DATA_COUNT_MASK) + >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET; + info->frm_status.PauseCount = (tmp & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) + >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET; + tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON); + info->frm_status.EnIntAfterData = + (tmp & IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE) > 0; + info->frm_status.EnIntAfterPause = + (tmp & IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE) > 0; + return (&info->frm_status); +} // ifx_ssc_frm_status_get + + +/*----------------------------------------------------------------------------- + FUNC-NAME : ifx_ssc_frm_control_get + LONG-NAME : framing control get + PURPOSE : Get the actual control values of the framing. + + PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. + + RESULT : pointer to a structure ifx_ssc_frm_opts which holds control bits + and count reload values. + + REMARKS : Changes structure inside of info, so the return value isn't + needed at all, but could be used for simple access. +-----------------------------------------------------------------------------*/ +static struct ifx_ssc_frm_opts * +ifx_ssc_frm_control_get(struct ifx_ssc_port *info) +{ + unsigned long tmp; + + tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON); + info->frm_opts.FrameEnable = (tmp & IFX_SSC_SFCON_SF_ENABLE) > 0; + info->frm_opts.DataLength = (tmp & IFX_SSC_SFCON_DATA_LENGTH_MASK) + >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET; + info->frm_opts.PauseLength = (tmp & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) + >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET; + info->frm_opts.IdleData = (tmp & IFX_SSC_SFCON_PAUSE_DATA_MASK) + >> IFX_SSC_SFCON_PAUSE_DATA_OFFSET; + info->frm_opts.IdleClock = (tmp & IFX_SSC_SFCON_PAUSE_CLOCK_MASK) + >> IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET; + info->frm_opts.StopAfterPause = + (tmp & IFX_SSC_SFCON_STOP_AFTER_PAUSE) > 0; + return (&info->frm_opts); +} // ifx_ssc_frm_control_get + + +/*----------------------------------------------------------------------------- + FUNC-NAME : ifx_ssc_frm_control_set + LONG-NAME : framing control set + PURPOSE : Set the actual control values of the framing. + + PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. + + RESULT : pointer to a structure ifx_ssc_frm_opts which holds control bits + and count reload values. + + REMARKS : +-----------------------------------------------------------------------------*/ +static int +ifx_ssc_frm_control_set(struct ifx_ssc_port *info) +{ + unsigned long tmp; + + // check parameters + if ((info->frm_opts.DataLength > IFX_SSC_SFCON_DATA_LENGTH_MAX) || + (info->frm_opts.DataLength < 1) || + (info->frm_opts.PauseLength > IFX_SSC_SFCON_PAUSE_LENGTH_MAX) || + (info->frm_opts.PauseLength < 1) || + ((info->frm_opts.IdleData & ~(IFX_SSC_SFCON_PAUSE_DATA_MASK >> + IFX_SSC_SFCON_PAUSE_DATA_OFFSET)) != 0 ) || + ((info->frm_opts.IdleClock & ~(IFX_SSC_SFCON_PAUSE_CLOCK_MASK >> + IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET)) != 0 )) + return -EINVAL; + + // read interrupt bits (they're not changed here) + tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_SFCON) & + (IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE | + IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE); + + // set all values with respect to it's bit position (for data and pause + // length set N-1) + tmp = (info->frm_opts.DataLength - 1) << IFX_SSC_SFCON_DATA_LENGTH_OFFSET; + tmp |= (info->frm_opts.PauseLength - 1) << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET; + tmp |= info->frm_opts.IdleData << IFX_SSC_SFCON_PAUSE_DATA_OFFSET; + tmp |= info->frm_opts.IdleClock << IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET; + tmp |= info->frm_opts.FrameEnable * IFX_SSC_SFCON_SF_ENABLE; + tmp |= info->frm_opts.StopAfterPause * IFX_SSC_SFCON_STOP_AFTER_PAUSE; + + WRITE_PERIPHERAL_REGISTER(tmp, info->mapbase + IFX_SSC_SFCON); + + return 0; +} // ifx_ssc_frm_control_set + + +/*----------------------------------------------------------------------------- + FUNC-NAME : ifx_ssc_rxtx_mode_set + LONG-NAME : rxtx mode set + PURPOSE : Set the transmission mode. + + PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. + + RESULT : Returns error code + + REMARKS : Assumes that SSC not used (SSC disabled, device not opened yet + or just closed) +-----------------------------------------------------------------------------*/ +static int +ifx_ssc_rxtx_mode_set(struct ifx_ssc_port *info, unsigned int val) +{ + unsigned long tmp; + + // check parameters + if (!(info) || (val & ~(IFX_SSC_MODE_MASK))) + return -EINVAL; + /*check BUSY and RXCNT*/ + if ( READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & IFX_SSC_STATE_BUSY + ||READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_RXCNT) & IFX_SSC_RXCNT_TODO_MASK) + return -EBUSY; + // modify + tmp = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CON) & + ~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF)) | (val); + WRITE_PERIPHERAL_REGISTER(tmp, info->mapbase + IFX_SSC_CON); + info->opts.modeRxTx = val; +/* + printk(KERN_DEBUG "IFX SSC%d: Setting mode to %s%s\n", + info->port_nr, + ((val & IFX_SSC_CON_RX_OFF) == 0) ? "rx ":"", + ((val & IFX_SSC_CON_TX_OFF) == 0) ? "tx":""); +*/ + return 0; +} // ifx_ssc_rxtx_mode_set + +void ifx_gpio_init(void) +{ + u32 temp; +/* set gpio pin p0.10(SPI_DIN) p0.11(SPI_DOUT) p0.12(SPI_CLK) p0.13(SPI_CS2) direction */ + temp = *(AMAZON_GPIO_P0_DIR) ; + temp &= 0xFFFFFBFF; + temp |= 0x3800; + *(AMAZON_GPIO_P0_DIR) = temp; +/* set port 0 alternate select register 0 */ + temp = *(AMAZON_GPIO_P0_ALTSEL0) ; + temp &= 0xFFFFC3FF; + temp |= 0x00001c00; + *(AMAZON_GPIO_P0_ALTSEL0) = temp; + +/* set port 0 alternate select register 1 */ + temp = *(AMAZON_GPIO_P0_ALTSEL1) ; + temp &= 0xFFFFC3FF; + temp |= 0x00002000; + *(AMAZON_GPIO_P0_ALTSEL1) = temp; + +/* set port 0 open drain mode register */ + temp = *(AMAZON_GPIO_P0_OD); + temp |= 0x00003800; /* set output pin normal mode */ + *(AMAZON_GPIO_P0_OD)= temp; +} + +/* + * This routine intializes the SSC appropriately depending + * on slave/master and full-/half-duplex mode. + * It assumes that the SSC is disabled and the fifo's and buffers + * are flushes later on. + */ +static int +ifx_ssc_sethwopts(struct ifx_ssc_port *info) +{ + unsigned long flags, bits; + struct ifx_ssc_hwopts *opts = &info->opts; + + /* sanity checks */ + if ((opts->dataWidth < IFX_SSC_MIN_DATA_WIDTH) || + (opts->dataWidth > IFX_SSC_MAX_DATA_WIDTH)) { + printk("%s: sanity check failed\n", __FUNCTION__); + return -EINVAL; + } + bits = (opts->dataWidth - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET; + bits |= IFX_SSC_CON_ENABLE_BYTE_VALID; +// if (opts->abortErrDetect) +// bits |= IFX_SSC_CON_ABORT_ERR_CHECK; + if (opts->rxOvErrDetect) + bits |= IFX_SSC_CON_RX_OFL_CHECK; + if (opts->rxUndErrDetect) + bits |= IFX_SSC_CON_RX_UFL_CHECK; + if (opts->txOvErrDetect) + bits |= IFX_SSC_CON_TX_OFL_CHECK; + if (opts->txUndErrDetect) + bits |= IFX_SSC_CON_TX_UFL_CHECK; + if (opts->loopBack) + bits |= IFX_SSC_CON_LOOPBACK_MODE; + if (opts->echoMode) + bits |= IFX_SSC_CON_ECHO_MODE_ON; + if (opts->headingControl) + bits |= IFX_SSC_CON_MSB_FIRST; + if (opts->clockPhase) + bits |= IFX_SSC_CON_LATCH_THEN_SHIFT; + if (opts->clockPolarity) + bits |= IFX_SSC_CON_CLOCK_FALL; + switch (opts->modeRxTx) { + case IFX_SSC_MODE_TX: + bits |= IFX_SSC_CON_RX_OFF; + break; + case IFX_SSC_MODE_RX: + bits |= IFX_SSC_CON_TX_OFF; + break; + } // switch (opts->modeRxT) + local_irq_save(flags); + WRITE_PERIPHERAL_REGISTER(bits, info->mapbase + IFX_SSC_CON); + WRITE_PERIPHERAL_REGISTER((info->opts.gpoCs << IFX_SSC_GPOCON_ISCSB0_POS) | + (info->opts.gpoInv << IFX_SSC_GPOCON_INVOUT0_POS), + info->mapbase + IFX_SSC_GPOCON); + //master mode + if (opts->masterSelect){ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_MASTER_SELECT,info->mapbase + IFX_SSC_WHBSTATE); + }else{ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_MASTER_SELECT,info->mapbase + IFX_SSC_WHBSTATE); + } + // init serial framing + WRITE_PERIPHERAL_REGISTER(0, info->mapbase + IFX_SSC_SFCON); + /* set up the port pins */ + //check for general requirements to switch (external) pad/pin characteristics + ifx_gpio_init(); + local_irq_restore(flags); + + return 0; +} // ifx_ssc_sethwopts + +static int +ifx_ssc_set_baud(struct ifx_ssc_port *info, unsigned int baud) +{ + unsigned int ifx_ssc_clock; + unsigned int br; + unsigned long flags; + bool enabled; + + ifx_ssc_clock = ifx_ssc_get_kernel_clk(info); + if (ifx_ssc_clock ==0) + return -EINVAL; + + local_irq_save(flags); + /* have to disable the SSC to set the baudrate */ + enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) + & IFX_SSC_STATE_IS_ENABLED) != 0; + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + // compute divider + br = ((ifx_ssc_clock >> 1)/baud) - 1; + asm("SYNC"); + if (br > 0xffff || + ((br == 0) && + ((READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) & + IFX_SSC_STATE_IS_MASTER) == 0))){ + local_irq_restore(flags); + printk("%s: illegal baudrate %u\n", __FUNCTION__, baud); + return -EINVAL; + } + WRITE_PERIPHERAL_REGISTER(br, info->mapbase + IFX_SSC_BR); + if (enabled) + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + local_irq_restore(flags); + return 0; +} // ifx_ssc_set_baud + +static int +ifx_ssc_hwinit(struct ifx_ssc_port *info) +{ + unsigned long flags; + bool enabled; + + /* have to disable the SSC */ + enabled = (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) + & IFX_SSC_STATE_IS_ENABLED) != 0; + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + + if (ifx_ssc_sethwopts(info) < 0) + { + printk("%s: setting the hardware options failed\n", + __FUNCTION__); + return -EINVAL; + } + + if (ifx_ssc_set_baud(info, info->baud) < 0) { + printk("%s: setting the baud rate failed\n", __FUNCTION__); + return -EINVAL; + } + local_irq_save(flags); + /* TX FIFO */ + WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_TXFIFO_FL << + IFX_SSC_XFCON_ITL_OFFSET) | + IFX_SSC_XFCON_FIFO_ENABLE, + info->mapbase + IFX_SSC_TXFCON); + /* RX FIFO */ + WRITE_PERIPHERAL_REGISTER((IFX_SSC_DEF_RXFIFO_FL << + IFX_SSC_XFCON_ITL_OFFSET) | + IFX_SSC_XFCON_FIFO_ENABLE, + info->mapbase + IFX_SSC_RXFCON); + local_irq_restore(flags); + if (enabled) + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_SET_ENABLE, + info->mapbase + IFX_SSC_WHBSTATE); + return 0; +} // ifx_ssc_hwinit + +/*----------------------------------------------------------------------------- + FUNC-NAME : ifx_ssc_batch_exec + LONG-NAME : + PURPOSE : + + PARAMETER : *info pointer to the port-specific structure ifx_ssc_port. + + RESULT : Returns error code + + REMARKS : +-----------------------------------------------------------------------------*/ +static int +ifx_ssc_batch_exec(struct ifx_ssc_port *info, struct ifx_ssc_batch_list *batch_anchor) +{ + // ### TO DO: implement user space batch execution + // first, copy the whole linked list from user to kernel space + // save some hardware options + // execute list + // restore hardware options if selected + return -EFAULT; +} // ifx_ssc_batch_exec + + +/* + * This routine allows the driver to implement device- + * specific ioctl's. If the ioctl number passed in cmd is + * not recognized by the driver, it should return ENOIOCTLCMD. + */ +int +ifx_ssc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long data) +{ + struct ifx_ssc_port *info; + int line, ret_val = 0; + unsigned long flags; + unsigned long tmp; + int from_kernel = 0; + + if ((inode == (struct inode *)0) || (inode == (struct inode *)1)) + { + from_kernel = 1; + line = (int)inode; + } + else + line = MINOR(filp->f_dentry->d_inode->i_rdev); + + /* don't use more minor devices than we can support */ + if (line < 0 || line >= PORT_CNT) + return -ENXIO; + + info = &isp[line]; + + switch (cmd) { + case IFX_SSC_STATS_READ: + /* data must be a pointer to a struct ifx_ssc_statistics */ + if (from_kernel) + memcpy((void *)data, (void *)&info->stats, + sizeof(struct ifx_ssc_statistics)); + else + if (copy_to_user((void *)data, + (void *)&info->stats, + sizeof(struct ifx_ssc_statistics))) + ret_val = -EFAULT; + break; + case IFX_SSC_STATS_RESET: + /* just resets the statistics counters */ + memset((void *)&info->stats, 0, sizeof(struct ifx_ssc_statistics)); + break; + case IFX_SSC_BAUD_SET: + /* if the buffers are not empty then the port is */ + /* busy and we shouldn't change things on-the-fly! */ + if (!info->txbuf || !info->rxbuf || + (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) + & IFX_SSC_STATE_BUSY)) { + ret_val = -EBUSY; + break; + } + /* misuse flags */ + if (from_kernel) + flags = *((unsigned long *)data); + else + if (copy_from_user((void *)&flags, + (void *)data, sizeof(flags))) + { + ret_val = -EFAULT; + break; + } + if (flags == 0) + { + ret_val = -EINVAL; + break; + } + if (ifx_ssc_set_baud(info, flags) < 0) + { + ret_val = -EINVAL; + break; + } + info->baud = flags; + break; + case IFX_SSC_BAUD_GET: + if (from_kernel) + *((unsigned int *)data) = info->baud; + else + if (copy_to_user((void *)data, + (void *)&info->baud, + sizeof(unsigned long))) + ret_val = -EFAULT; + break; + case IFX_SSC_RXTX_MODE_SET: + if (from_kernel) + tmp = *((unsigned long *)data); + else + if (copy_from_user((void *)&tmp, + (void *)data, sizeof(tmp))) { + ret_val = -EFAULT; + break; + } + ret_val = ifx_ssc_rxtx_mode_set(info, tmp); + break; + case IFX_SSC_RXTX_MODE_GET: + tmp = READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_CON) & + (~(IFX_SSC_CON_RX_OFF | IFX_SSC_CON_TX_OFF)); + if (from_kernel) + *((unsigned int *)data) = tmp; + else + if (copy_to_user((void *)data, + (void *)&tmp, + sizeof(tmp))) + ret_val = -EFAULT; + break; + + case IFX_SSC_ABORT: + ifx_ssc_abort(info); + break; + + case IFX_SSC_GPO_OUT_SET: + if (from_kernel) + tmp = *((unsigned long *)data); + else + if (copy_from_user((void *)&tmp, + (void *)data, sizeof(tmp))) { + ret_val = -EFAULT; + break; + } + if (tmp > IFX_SSC_MAX_GPO_OUT) + ret_val = -EINVAL; + else + WRITE_PERIPHERAL_REGISTER + (1<<(tmp + IFX_SSC_WHBGPOSTAT_SETOUT0_POS), + info->mapbase + IFX_SSC_WHBGPOSTAT); + break; + case IFX_SSC_GPO_OUT_CLR: + if (from_kernel) + tmp = *((unsigned long *)data); + else + if (copy_from_user((void *)&tmp, + (void *)data, sizeof(tmp))) { + ret_val = -EFAULT; + break; + } + if (tmp > IFX_SSC_MAX_GPO_OUT) + ret_val = -EINVAL; + else { + WRITE_PERIPHERAL_REGISTER + (1<<(tmp + IFX_SSC_WHBGPOSTAT_CLROUT0_POS), + info->mapbase + IFX_SSC_WHBGPOSTAT); + } + break; + case IFX_SSC_GPO_OUT_GET: + tmp = READ_PERIPHERAL_REGISTER + (info->mapbase + IFX_SSC_GPOSTAT); + if (from_kernel) + *((unsigned int *)data) = tmp; + else + if (copy_to_user((void *)data, + (void *)&tmp, + sizeof(tmp))) + ret_val = -EFAULT; + break; + case IFX_SSC_FRM_STATUS_GET: + ifx_ssc_frm_status_get(info); + if (from_kernel) + memcpy((void *)data, (void *)&info->frm_status, + sizeof(struct ifx_ssc_frm_status)); + else + if (copy_to_user((void *)data, + (void *)&info->frm_status, + sizeof(struct ifx_ssc_frm_status))) + ret_val = -EFAULT; + break; + case IFX_SSC_FRM_CONTROL_GET: + ifx_ssc_frm_control_get(info); + if (from_kernel) + memcpy((void *)data, (void *)&info->frm_opts, + sizeof(struct ifx_ssc_frm_opts)); + else + if (copy_to_user((void *)data, + (void *)&info->frm_opts, + sizeof(struct ifx_ssc_frm_opts))) + ret_val = -EFAULT; + break; + case IFX_SSC_FRM_CONTROL_SET: + if (from_kernel) + memcpy((void *)&info->frm_opts, (void *)data, + sizeof(struct ifx_ssc_frm_opts)); + else + if (copy_to_user((void *)&info->frm_opts, + (void *)data, + sizeof(struct ifx_ssc_frm_opts))){ + ret_val = -EFAULT; + break; + } + ret_val = ifx_ssc_frm_control_set(info); + break; + case IFX_SSC_HWOPTS_SET: + /* data must be a pointer to a struct ifx_ssc_hwopts */ + /* if the buffers are not empty then the port is */ + /* busy and we shouldn't change things on-the-fly! */ + if (!info->txbuf || !info->rxbuf || + (READ_PERIPHERAL_REGISTER(info->mapbase + IFX_SSC_STATE) + & IFX_SSC_STATE_BUSY)) { + ret_val = -EBUSY; + break; + } + if (from_kernel) + memcpy((void *)&info->opts, (void *)data, + sizeof(struct ifx_ssc_hwopts)); + else + if (copy_from_user((void *)&info->opts, + (void *)data, + sizeof(struct ifx_ssc_hwopts))) + { + ret_val = -EFAULT; + break; + } + if (ifx_ssc_hwinit(info) < 0) + { + ret_val = -EIO; + } + break; + case IFX_SSC_HWOPTS_GET: + /* data must be a pointer to a struct ifx_ssc_hwopts */ + if (from_kernel) + memcpy((void *)data, (void *)&info->opts, + sizeof(struct ifx_ssc_hwopts)); + else + if (copy_to_user((void *)data, + (void *)&info->opts, + sizeof(struct ifx_ssc_hwopts))) + ret_val = -EFAULT; + break; + default: + ret_val = -ENOIOCTLCMD; + } + + return ret_val; +} /* ifx_ssc_ioctl */ +EXPORT_SYMBOL(ifx_ssc_ioctl); + +///* the poll routine */ +//static unsigned int +//ifx_ssc_poll(struct file *filp, struct poll_table_struct *pts) +//{ +// int unit = MINOR(filp->f_dentry->d_inode->i_rdev); +// struct ifx_ssc_port *info; +// unsigned int mask = 0; +// int spc; +// +// info = &isp[unit]; +// +// /* add event to the wait queues */ +// /* DO NOT FORGET TO DO A WAKEUP ON THESE !!!! */ +// poll_wait(filp, &info->pwait, pts); +// +// /* are there bytes in the RX SW-FIFO? */ +// if (info->rxrp != info->rxwp) +// mask |= POLLIN | POLLRDNORM; +// +// /* free space in the TX SW-FIFO */ +// spc = info->txrp - info->txwp - 1; +// if (spc < 0) +// spc += TX_BUFSIZE; +//#ifdef IFX_SSC_USEDMA +// /* writing always works, except in the DMA case when all descriptors */ +// /* are used up */ +// if (unit == 1 && info->dma_freecnt == 0) +// spc = 0; +//#endif +// if (spc > 0) +// mask |= POLLOUT | POLLWRNORM; +// +// return (mask); +//} + +static int +ifx_ssc1_read_proc(char *page, char **start, off_t offset, int count, int *eof, void *data) +{ + int off = 0; + unsigned long flags; + + /* don't want any interrupts here */ + save_flags(flags); + cli(); + + + /* print statistics */ + off += sprintf(page+off, "Statistics for Infineon Synchronous Serial Controller SSC1\n"); + off += sprintf(page+off, "RX overflow errors %d\n", isp[0].stats.rxOvErr); + off += sprintf(page+off, "RX underflow errors %d\n", isp[0].stats.rxUnErr); + off += sprintf(page+off, "TX overflow errors %d\n", isp[0].stats.txOvErr); + off += sprintf(page+off, "TX underflow errors %d\n", isp[0].stats.txUnErr); + off += sprintf(page+off, "Abort errors %d\n", isp[0].stats.abortErr); + off += sprintf(page+off, "Mode errors %d\n", isp[0].stats.modeErr); + off += sprintf(page+off, "RX Bytes %d\n", isp[0].stats.rxBytes); + off += sprintf(page+off, "TX Bytes %d\n", isp[0].stats.txBytes); + + restore_flags (flags); /* XXXXX */ + *eof = 1; + return (off); +} + + +/* + * This routine prints out the appropriate serial driver version number + */ +static inline void +show_version(void) +{ +#if 0 + printk("Infineon Technologies Synchronous Serial Controller (SSC) driver\n" + " version %s - built %s %s\n", IFX_SSC_DRV_VERSION, __DATE__, __TIME__); +#endif +} /* show_version */ + + +/* + * Due to the fact that a port can be dynamically switched between slave + * and master mode using an IOCTL the hardware is not initialized here, + * but in ifx_ssc_hwinit() as a result of an IOCTL. + */ +int __init +ifx_ssc_init(void) +{ + struct ifx_ssc_port *info; + int i, nbytes; + unsigned long flags; + int ret_val; + + // ### TO DO: dynamic port count evaluation due to pin multiplexing + + ret_val = -ENOMEM; + nbytes = PORT_CNT * sizeof(struct ifx_ssc_port); + isp = (struct ifx_ssc_port *)kmalloc(nbytes, GFP_KERNEL); + if (isp == NULL) + { + printk("%s: no memory for isp\n", __FUNCTION__); + return (ret_val); + } + memset(isp, 0, nbytes); + + show_version(); + + /* register the device */ + ret_val = -ENXIO; +/* + i = maj; +*/ + if ((i = register_chrdev(maj, "ssc", &ifx_ssc_fops)) < 0) + { + printk("Unable to register major %d for the Infineon SSC\n", maj); + if (maj == 0){ + goto errout; + } + else{ + maj = 0; + if ((i = register_chrdev(maj, "ssc", &ifx_ssc_fops)) < 0) + { + printk("Unable to register major %d for the Infineon SSC\n", maj); + goto errout; + } + } + } + if (maj == 0) maj = i; + //printk("registered major %d for Infineon SSC\n", maj); + + /* set default values in ifx_ssc_port */ + for (i = 0; i < PORT_CNT; i++) { + info = &isp[i]; + info->port_nr = i; + /* default values for the HwOpts */ + info->opts.AbortErrDetect = IFX_SSC_DEF_ABRT_ERR_DETECT; + info->opts.rxOvErrDetect = IFX_SSC_DEF_RO_ERR_DETECT; + info->opts.rxUndErrDetect = IFX_SSC_DEF_RU_ERR_DETECT; + info->opts.txOvErrDetect = IFX_SSC_DEF_TO_ERR_DETECT; + info->opts.txUndErrDetect = IFX_SSC_DEF_TU_ERR_DETECT; + info->opts.loopBack = IFX_SSC_DEF_LOOP_BACK; + info->opts.echoMode = IFX_SSC_DEF_ECHO_MODE; + info->opts.idleValue = IFX_SSC_DEF_IDLE_DATA; + info->opts.clockPolarity = IFX_SSC_DEF_CLOCK_POLARITY; + info->opts.clockPhase = IFX_SSC_DEF_CLOCK_PHASE; + info->opts.headingControl = IFX_SSC_DEF_HEADING_CONTROL; + info->opts.dataWidth = IFX_SSC_DEF_DATA_WIDTH; + info->opts.modeRxTx = IFX_SSC_DEF_MODE_RXTX; + info->opts.gpoCs = IFX_SSC_DEF_GPO_CS; + info->opts.gpoInv = IFX_SSC_DEF_GPO_INV; + info->opts.masterSelect = IFX_SSC_DEF_MASTERSLAVE; + info->baud = IFX_SSC_DEF_BAUDRATE; + info->rxbuf = NULL; + info->txbuf = NULL; + /* values specific to SSC1 */ + if (i == 0) { + info->mapbase = AMAZON_SSC_BASE_ADD_0; + // ### TO DO: power management + + // setting interrupt vectors + info->txirq = IFX_SSC_TIR; + info->rxirq = IFX_SSC_RIR; + info->errirq = IFX_SSC_EIR; +/* + info->frmirq = IFX_SSC_FIR; +*/ + } + /* activate SSC */ + /* CLC.DISS = 0 */ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_RMC << IFX_CLC_RUN_DIVIDER_OFFSET, info->mapbase + IFX_SSC_CLC); + +// ### TO DO: multiple instances + + init_waitqueue_head(&info->rwait); + //init_waitqueue_head(&info->pwait); + + local_irq_save(flags); + + // init serial framing register + WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_SFCON, info->mapbase + IFX_SSC_SFCON); + + /* try to get the interrupts */ + // ### TO DO: interrupt handling with multiple instances + ret_val = ifx_int_wrapper.request(info->txirq, ifx_ssc_tx_int, + 0, "ifx_ssc_tx", info); + if (ret_val){ + printk("%s: unable to get irq %d\n", __FUNCTION__, + info->txirq); + local_irq_restore(flags); + goto errout; + } + ret_val = ifx_int_wrapper.request(info->rxirq, ifx_ssc_rx_int, + 0, "ifx_ssc_rx", info); + if (ret_val){ + printk("%s: unable to get irq %d\n", __FUNCTION__, + info->rxirq); + local_irq_restore(flags); + goto irqerr; + } + ret_val = ifx_int_wrapper.request(info->errirq, ifx_ssc_err_int, + 0, "ifx_ssc_err", info); + if (ret_val){ + printk("%s: unable to get irq %d\n", __FUNCTION__, + info->errirq); + local_irq_restore(flags); + goto irqerr; + } +/* + ret_val = ifx_int_wrapper.request(info->frmirq, ifx_ssc_frm_int, + 0, "ifx_ssc_frm", info); + if (ret_val){ + printk("%s: unable to get irq %d\n", __FUNCTION__, + info->frmirq); + local_irq_restore(flags); + goto irqerr; + } + +*/ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_DEF_IRNEN, info->mapbase + IFX_SSC_IRN_EN); + + local_irq_restore(flags); + } // for (i = 0; i < PORT_CNT; i++) + + /* init the SSCs with default values */ + for (i = 0; i < PORT_CNT; i++) + { + info = &isp[i]; + if (ifx_ssc_hwinit(info) < 0) + { + printk("%s: hardware init failed for port %d\n", + __FUNCTION__, i); + goto irqerr; + } + } + + /* register /proc read handler */ + // ### TO DO: multiple instances + /* for SSC1, which is always present */ + create_proc_read_entry("driver/ssc1", 0, NULL, ifx_ssc1_read_proc, NULL); + return 0; + +irqerr: + // ### TO DO: multiple instances + ifx_int_wrapper.free(isp[0].txirq,&isp[0]); + ifx_int_wrapper.free(isp[0].rxirq,&isp[0]); + ifx_int_wrapper.free(isp[0].errirq,&isp[0]); +/* + ifx_int_wrapper.free(isp[0].frmirq, &isp[0]); +*/ +errout: + /* free up any allocated memory in the error case */ + kfree(isp); + return (ret_val); +} /* ifx_ssc_init */ + + +void +ifx_ssc_cleanup_module(void) +{ + int i; + + /* free up any allocated memory */ + for (i = 0; i < PORT_CNT; i++) + { + /* disable the SSC */ + WRITE_PERIPHERAL_REGISTER(IFX_SSC_WHBSTATE_CLR_ENABLE,isp[i].mapbase + IFX_SSC_WHBSTATE); + /* free the interrupts */ + ifx_int_wrapper.free(isp[i].txirq, &isp[i]); + ifx_int_wrapper.free(isp[i].rxirq, &isp[i]); + ifx_int_wrapper.free(isp[i].errirq, &isp[i]); +/* + ifx_int_wrapper.free(isp[i].frmirq, &isp[i]); + + if (isp[i].rxbuf != NULL) + kfree(isp[i].rxbuf); + if (isp[i].txbuf != NULL) + kfree(isp[i].txbuf); +*/ + } + kfree(isp); + /* unregister the device */ + if (unregister_chrdev(maj, "ssc")) + { + printk("Unable to unregister major %d for the SSC\n", maj); + } + /* delete /proc read handler */ + remove_proc_entry("driver/ssc1", NULL); + remove_proc_entry("driver/ssc2", NULL); +} /* ifx_ssc_cleanup_module */ + +module_exit(ifx_ssc_cleanup_module); + +/* Module entry-points */ +module_init(ifx_ssc_init); + +#ifndef MODULE +static int __init +ifx_ssc_set_maj(char *str) +{ + maj = simple_strtol(str, NULL, 0); + return 1; +} +__setup("ssc_maj=", ifx_ssc_set_maj); +#endif /* !MODULE */ + +#define AMAZON_SSC_EMSG(fmt,arg...) printk("%s: "fmt,__FUNCTION__, ##arg) +/* Brief: chip select enable + */ +inline int amazon_ssc_cs_low(u32 pin) +{ + int ret=0; + if ((ret=ifx_ssc_ioctl((struct inode *)0, NULL,IFX_SSC_GPO_OUT_CLR, (unsigned long)&pin))){ + AMAZON_SSC_EMSG("clear CS %d fails\n",pin); + } + wmb(); + return ret; +} +EXPORT_SYMBOL(amazon_ssc_cs_low); +/* Brief: chip select disable + */ +inline int amazon_ssc_cs_high(u32 pin) +{ + int ret=0; + if ((ret=ifx_ssc_ioctl((struct inode *)0, NULL,IFX_SSC_GPO_OUT_SET, (unsigned long)&pin))){ + AMAZON_SSC_EMSG("set CS %d fails\n", pin); + } + wmb(); + return ret; +} +EXPORT_SYMBOL(amazon_ssc_cs_high); +/* Brief: one SSC session + * Parameter: + * tx_buf + * tx_len + * rx_buf + * rx_len + * session_mode: IFX_SSC_MODE_RXTX or IFX_SSC_MODE_TX + * Return: >=0 number of bytes received (if rx_buf != 0) or transmitted + * <0 error code + * Description: + * 0. copy data to internal buffer + * 1. Write command + * 2a. If SSC_SESSION_MODE_TXONLY, read tx_len data + * 2b. If not Read back (tx_len + rx_len) data + * 3. copy internal buffer to rx buf if necessary + */ +static int ssc_session(char * tx_buf, u32 tx_len, char * rx_buf, u32 rx_len) +{ + int ret=0; + + char * ssc_tx_buf=NULL; + char * ssc_rx_buf=NULL; + +// volatile char ssc_tx_buf[128]={0}; +// volatile char ssc_rx_buf[128]={0}; + + int eff_size=0; + u8 mode=0; + + if (tx_buf == NULL && tx_len ==0 && rx_buf == NULL && rx_len == 0){ + AMAZON_SSC_EMSG("invalid parameters\n"); + ret=-EINVAL; + goto ssc_session_exit; + }else if (tx_buf == NULL || tx_len == 0){ + if (rx_buf != NULL && rx_len != 0){ + mode = IFX_SSC_MODE_RX; + }else{ + AMAZON_SSC_EMSG("invalid parameters\n"); + ret=-EINVAL; + goto ssc_session_exit; + } + }else if (rx_buf == NULL || rx_len ==0){ + if (tx_buf != NULL && tx_len != 0){ + mode = IFX_SSC_MODE_TX; + }else{ + AMAZON_SSC_EMSG("invalid parameters\n"); + ret=-EINVAL; + goto ssc_session_exit; + } + }else{ + mode = IFX_SSC_MODE_RXTX; + } + + if (mode == IFX_SSC_MODE_RXTX){ + eff_size = tx_len + rx_len; + }else if (mode == IFX_SSC_MODE_RX){ + eff_size = rx_len; + }else{ + eff_size = tx_len; + } + + //4 bytes alignment, required by driver + /* change by TaiCheng */ + //if (in_irq()){ + if (1){ + ssc_tx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_ATOMIC); + ssc_rx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_ATOMIC); + }else{ + ssc_tx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_KERNEL); + ssc_rx_buf = (char*) kmalloc(sizeof(char) * ((eff_size + 3) & (~3)), GFP_KERNEL); + } + if (ssc_tx_buf == NULL || ssc_rx_buf == NULL){ + AMAZON_SSC_EMSG("no memory for size of %d\n", eff_size); + ret = -ENOMEM; + goto ssc_session_exit; + } + memset((void*)ssc_tx_buf, 0, eff_size); + memset((void*)ssc_rx_buf, 0, eff_size); + + if (tx_len>0){ + memcpy(ssc_tx_buf, tx_buf, tx_len); + } + + ret=ifx_ssc_kwrite(0, ssc_tx_buf, eff_size); + + if (ret > 0) { + ssc_tx_buf = NULL; //should be freed by ifx_ssc_kwrite + } + + if ( ret != eff_size ){ + AMAZON_SSC_EMSG("ifx_ssc_write return %d\n",ret); + goto ssc_session_exit; + } + ret=ifx_ssc_kread(0, ssc_rx_buf,eff_size); + if ( ret != eff_size ){ + AMAZON_SSC_EMSG("ifx_ssc_read return %d\n",ret); + goto ssc_session_exit; + } + + memcpy(rx_buf, ssc_rx_buf+tx_len, rx_len); + + if (mode == IFX_SSC_MODE_TX) { + ret = tx_len; + }else{ + ret = rx_len; + } +ssc_session_exit: + + if (ssc_tx_buf != NULL) kfree(ssc_tx_buf); + if (ssc_rx_buf != NULL) kfree(ssc_rx_buf); + + if (ret<0) { + printk("ssc session fails\n"); + } + return ret; +} +/* Brief: TX-RX session + * Parameter: + * tx_buf + * tx_len + * rx_buf + * rx_len + * Return: >=0 number of bytes received + * <0 error code + * Description: + * 1. TX session + * 2. RX session + */ +int amazon_ssc_txrx(char * tx_buf, u32 tx_len, char * rx_buf, u32 rx_len) +{ + return ssc_session(tx_buf,tx_len,rx_buf,rx_len); +} +EXPORT_SYMBOL(amazon_ssc_txrx); +/* Brief: TX only session + * Parameter: + * tx_buf + * tx_len + * Return: >=0 number of bytes transmitted + * <0 error code + */ +int amazon_ssc_tx(char * tx_buf, u32 tx_len) +{ + return ssc_session(tx_buf,tx_len,NULL,0); +} +EXPORT_SYMBOL(amazon_ssc_tx); +/* Brief: RX only session + * Parameter: + * rx_buf + * rx_len + * Return: >=0 number of bytes received + * <0 error code + */ +int amazon_ssc_rx(char * rx_buf, u32 rx_len) +{ + return ssc_session(NULL,0,rx_buf,rx_len); +} +EXPORT_SYMBOL(amazon_ssc_rx); + diff --git a/target/linux/amazon/files/drivers/char/watchdog/amazon_wdt.c b/target/linux/amazon/files/drivers/char/watchdog/amazon_wdt.c new file mode 100644 index 0000000000..3c58d2fea8 --- /dev/null +++ b/target/linux/amazon/files/drivers/char/watchdog/amazon_wdt.c @@ -0,0 +1,246 @@ +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Copyright 2004 Wu Qi Ming <gokimi@msn.com> + * Copyright (C) 2007 John Crispin <blogic@openwrt.org> + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/fs.h> +#include <linux/errno.h> +#include <linux/proc_fs.h> +#include <linux/stat.h> +#include <linux/tty.h> +#include <linux/selection.h> +#include <linux/kmod.h> +#include <linux/vmalloc.h> +#include <linux/kdev_t.h> +#include <linux/ioctl.h> +#include <asm/uaccess.h> +#include <asm/system.h> +#include <asm/amazon/amazon.h> +#include <asm/amazon/amazon_wdt.h> + +#define DRV_NAME "AMAZON WDT:" + +#undef AMAZON_WDT_DEBUG + +extern unsigned int amazon_get_fpi_hz(void); +static int amazon_wdt_isopen = 0; + +#ifdef AMAZON_WDT_DEBUG +static struct proc_dir_entry* amazon_wdt_dir; +#endif + +int wdt_enable(int timeout) +{ + u32 hard_psw, ffpi; + int reload_value, divider = 1; + + ffpi = amazon_get_fpi_hz(); + + reload_value = 65536 - timeout * ffpi / 256; + + if (reload_value < 0) { + divider = 0; + reload_value = 65536 - timeout * ffpi / 16384; + } + + if (reload_value < 0){ + printk(KERN_INFO DRV_NAME "timeout too large %d\n", timeout); + return -EINVAL; + } + + printk(KERN_INFO DRV_NAME "timeout:%d reload_value: %8x\n", timeout, reload_value); + + hard_psw = (amazon_readl(AMAZON_WDT_CON0) & 0xffffff01) + + (amazon_readl(AMAZON_WDT_CON1) & 0xc) + 0xf0; + amazon_writel(hard_psw, AMAZON_WDT_CON0); + wmb(); + + amazon_writel((hard_psw & 0xff00) + (reload_value << 16) + 0xf2, AMAZON_WDT_CON0); + wmb(); + + amazon_writel(divider << 2, AMAZON_WDT_CON1); + wmb(); + + hard_psw = (amazon_readl(AMAZON_WDT_CON0) & 0xffffff01) + + (amazon_readl(AMAZON_WDT_CON1) & 0xc) + 0xf0; + amazon_writel(hard_psw, AMAZON_WDT_CON0); + wmb(); + + amazon_writel_masked(AMAZON_WDT_CON0, 0xff, 0xf3); + wmb(); + return 0; +} + +void wdt_disable(void) +{ + u32 hard_psw = 0; + + hard_psw = (amazon_readl(AMAZON_WDT_CON0) & 0xffffff01) + + (amazon_readl(AMAZON_WDT_CON1) & 0xc) + 0xf0; + amazon_writel(hard_psw, AMAZON_WDT_CON0); + wmb(); + + amazon_writel_masked(AMAZON_WDT_CON0, 0xff, 0xf2); + wmb(); + + amazon_writel_masked(AMAZON_WDT_CON1, 0x8, 0x8); + wmb(); + + hard_psw=(amazon_readl(AMAZON_WDT_CON0) & 0xffffff01) + + (amazon_readl(AMAZON_WDT_CON1) & 0xc) + 0xf0; + amazon_writel(hard_psw, AMAZON_WDT_CON0); + wmb(); + + amazon_writel_masked(AMAZON_WDT_CON0, 0xff, 0xf3); + wmb(); + + return; +} + +static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + int result=0; + static int timeout=-1; + + switch(cmd){ + case AMAZON_WDT_IOC_START: + printk(KERN_INFO DRV_NAME "enable watch dog timer!\n"); + if (copy_from_user((void*)&timeout, (void*)arg, sizeof (int))) { + printk(KERN_INFO DRV_NAME "invalid argument\n"); + result=-EINVAL; + } else if ((result = wdt_enable(timeout)) < 0) { + timeout = -1; + } + break; + + case AMAZON_WDT_IOC_STOP: + printk(KERN_INFO DRV_NAME "disable watch dog timer\n"); + timeout = -1; + wdt_disable(); + break; + + case AMAZON_WDT_IOC_PING: + if (timeout < 0) { + result = -EIO; + } else { + result = wdt_enable(timeout); + } + break; + + default: + result=-EINVAL; + break; + } + return result; +} + +static ssize_t wdt_read(struct file *file, char *buf, size_t count, loff_t *offset) +{ + return 0; +} + +static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_t *offset) +{ + return count; +} + +static int wdt_open(struct inode *inode, struct file *file) +{ + if (amazon_wdt_isopen == 1) + return -EBUSY; + + amazon_wdt_isopen = 1; + printk(KERN_INFO DRV_NAME "opened\n"); + return 0; +} + +static int wdt_release(struct inode *inode, struct file *file) +{ + amazon_wdt_isopen = 0; + printk(KERN_INFO DRV_NAME "closed\n"); + return 0; +} + +#ifdef AMAZON_WDT_DEBUG +int wdt_register_proc_read(char *buf, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len=0; + len+=sprintf(buf+len,"NMISR: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_NMISR)); + len+=sprintf(buf+len,"RST_REQ: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_RST_REQ)); + len+=sprintf(buf+len,"RST_SR: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_RST_SR)); + len+=sprintf(buf+len,"WDT_CON0: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_CON0)); + len+=sprintf(buf+len,"WDT_CON1: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_CON1)); + len+=sprintf(buf+len,"WDT_SR: 0x%08x\n",AMAZON_WDT_REG32(AMAZON_WDT_SR)); + *eof = 1; + return len; +} +#endif + +static struct file_operations wdt_fops = { + read: wdt_read, + write: wdt_write, + ioctl: wdt_ioctl, + open: wdt_open, + release: wdt_release, +}; + +int __init amazon_wdt_init_module(void) +{ + int result = result = register_chrdev(0, "watchdog", &wdt_fops); + + if (result < 0) { + printk(KERN_INFO DRV_NAME "cannot register device\n"); + return result; + } + +#ifdef AMAZON_WDT_DEBUG + amazon_wdt_dir=proc_mkdir("amazon_wdt",NULL); + create_proc_read_entry("wdt_register", 0, amazon_wdt_dir, + wdt_register_proc_read, NULL); +#endif + + amazon_wdt_isopen=0; + printk(KERN_INFO DRV_NAME "driver loaded but inactive"); + return 0; +} + +void amazon_wdt_cleanup_module(void) +{ + unregister_chrdev(0, "watchdog"); +#ifdef AMAZON_WDT_DEBUG + remove_proc_entry("wdt_register", amazon_wdt_dir); + remove_proc_entry("amazon_wdt", NULL); +#endif + printk(KERN_INFO DRV_NAME "unregistered"); + return; +} + +MODULE_LICENSE ("GPL"); +MODULE_AUTHOR("Infineon / John Crispin <blogic@openwrt.org>"); +MODULE_DESCRIPTION("AMAZON WDT driver"); + +module_init(amazon_wdt_init_module); +module_exit(amazon_wdt_cleanup_module); + diff --git a/target/linux/amazon/files/drivers/mtd/maps/amazon.c b/target/linux/amazon/files/drivers/mtd/maps/amazon.c new file mode 100644 index 0000000000..3e7dc4f583 --- /dev/null +++ b/target/linux/amazon/files/drivers/mtd/maps/amazon.c @@ -0,0 +1,166 @@ +/* + * Handle mapping of the flash memory access routines + * on Amazon based devices. + * + * Copyright(C) 2004 peng.liu@infineon.com + * + * This code is GPLed + * + */ +// 000005:fchang 2005/6/2 Modified by Bingtao to double check if the EBU is enabled/disabled +// 506231:tc.chen 2005/06/23 increase firmware partition size form 192KB to 256KB +// 050701:linmars 2005/07/01 fix flash size wrong alignment after increase firmware partition +// 165001:henryhsu 2005/8/18 Remove the support for Intel flash because of 2.1 not enough rootfs partition size +// 165001:henryhsu 2005/9/7 Rolback to support INtel flash +// 509071:tc.chen 2005/09/07 Reduced flash writing time +// 511046:linmars 2005/11/04 change bootloader size from 128 into 64 +// 511241:linmars 2005/11/24 merge TaiChen's IRM patch + +// copyright 2005 infineon + +// copyright 2007 john crispin <blogic@openwrt.org> +// copyright 2007 felix fietkau <nbd@openwrt.org> + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <asm/io.h> + +#include <linux/init.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/map.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/cfi.h> +#include <linux/mutex.h> +#include <asm/amazon/amazon.h> + +#define AMAZON_PCI_ARB_CTL_ALT 0xb100205c +#define AMAZON_MTD_REG32( addr ) (*(volatile u32 *)(addr)) + + +static struct map_info amazon_map = { + .name = "AMAZON_FLASH", + .bankwidth = 2, + .size = 0x400000, +}; + +static map_word amazon_read16(struct map_info * map, unsigned long ofs) +{ + map_word temp; + ofs ^= 2; + temp.x[0] = *((__u16 *) (map->virt + ofs)); + return temp; +} + +static void amazon_write16(struct map_info *map, map_word d, unsigned long adr) +{ + adr ^= 2; + *((__u16 *) (map->virt + adr)) = d.x[0]; +} + +void amazon_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +{ + u8 *p; + u8 *to_8; + ssize_t l = len; + from = (unsigned long) (from + map->virt); + p = (u8 *) from; + to_8 = (u8 *) to; + while(len--){ + *to_8++ = *p++; + } +} + +void amazon_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +{ + u8 *p = (u8*) from; + u8 *to_8; + to += (unsigned long) map->virt; + to_8 = (u8*)to; + while(len--){ + *p++ = *to_8++; + } +} + +#define UBOOT_SIZE 0x40000 + +static struct mtd_partition amazon_partitions[3] = { + { + name:"U-Boot", /* U-Boot firmware */ + offset:0x00000000, + size:UBOOT_SIZE , /* 128k */ + }, + { + name:"kernel", /* firmware */ + offset:UBOOT_SIZE, + size:0x00100000, /* 192K */ + }, + { + name:"rootfs", /* default partition */ + offset:0x00200000, + size:0x00200000, + }, +}; + + +unsigned long flash_start = 0x13000000; +unsigned long flash_size = 0x800000; +unsigned long uImage_size = 0x10000d; + +int find_uImage_size(unsigned long start_offset){ + unsigned long temp; + + printk("trying to find uImage and its size\n"); + amazon_copy_from(&amazon_map, &temp, start_offset + 12, 4); + printk("kernel size is %d \n", temp + 0x40); + return temp + 0x40; +} + +int __init init_amazon_mtd(void) +{ + int ret = 0; + struct mtd_info *mymtd = NULL; + struct mtd_partition *parts = NULL; + + *AMAZON_EBU_BUSCON0 = 0x1d7ff; + + amazon_map.read = amazon_read16; + amazon_map.write = amazon_write16; + amazon_map.copy_from = amazon_copy_from; + amazon_map.copy_to = amazon_copy_to; + + amazon_map.phys = flash_start; + amazon_map.virt = ioremap_nocache(flash_start, flash_size); + + if (!amazon_map.virt) { + printk(KERN_WARNING "Failed to ioremap!\n"); + return -EIO; + } + + mymtd = (struct mtd_info *) do_map_probe("cfi_probe", &amazon_map); + if (!mymtd) { + iounmap(amazon_map.virt); + printk("probing failed\n"); + return -ENXIO; + } + + mymtd->owner = THIS_MODULE; + parts = &amazon_partitions[0]; + amazon_partitions[2].offset = UBOOT_SIZE + find_uImage_size(amazon_partitions[1].offset); + amazon_partitions[1].size = mymtd->size - amazon_partitions[1].offset - (2 * mymtd->erasesize); + amazon_partitions[2].size = mymtd->size - amazon_partitions[2].offset - (2 * mymtd->erasesize); + add_mtd_partitions(mymtd, parts, 3); + return 0; +} + +static void __exit cleanup_amazon_mtd(void) +{ + /* FIXME! */ +} + +module_init(init_amazon_mtd); +module_exit(cleanup_amazon_mtd); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("john crispin blogic@openwrt.org"); +MODULE_DESCRIPTION("MTD map driver for AMAZON boards"); diff --git a/target/linux/amazon/files/drivers/net/amazon_sw.c b/target/linux/amazon/files/drivers/net/amazon_sw.c new file mode 100644 index 0000000000..d19db6e36d --- /dev/null +++ b/target/linux/amazon/files/drivers/net/amazon_sw.c @@ -0,0 +1,876 @@ +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +//----------------------------------------------------------------------- +/* + * Description: + * Driver for Infineon Amazon 3 port switch + */ +//----------------------------------------------------------------------- +/* Author: Wu Qi Ming[Qi-Ming.Wu@infineon.com] + * Created: 7-April-2004 + */ +//----------------------------------------------------------------------- +/* History + * Changed on: Jun 28, 2004 + * Changed by: peng.liu@infineon.com + * Reason: add hardware flow control (HFC) (CONFIG_NET_HW_FLOWCONTROL) + * + * Changed on: Apr 6, 2005 + * Changed by: mars.lin@infineon.com + * Reason : supoort port identification + */ + + +// copyright 2004-2005 infineon.com + +// copyright 2007 john crispin <blogic@openwrt.org> +// copyright 2007 felix fietkau <nbd@openwrt.org> + + +// TODO +// port vlan code from bcrm target... the tawainese code was scrapped due to crappyness +// check all the mmi reg settings and possibly document them better +// verify the ethtool code +// remove the while(1) stuff +// further clean up and rework ... but it works for now +// check the mode[]=bridge stuff +// verify that the ethaddr can be set from u-boot + + +#ifndef __KERNEL__ +#define __KERNEL__ +#endif + + +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) +#define MODVERSIONS +#endif + +#if defined(MODVERSIONS) && !defined(__GENKSYMS__) +#include <linux/modversions.h> +#endif + +#include <linux/module.h> +#include <linux/string.h> +#include <linux/sched.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/errno.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/mii.h> +#include <asm/uaccess.h> +#include <linux/in.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/ip.h> +#include <linux/tcp.h> +#include <linux/skbuff.h> +#include <linux/in6.h> +#include <linux/proc_fs.h> +#include <linux/mm.h> +#include <linux/ethtool.h> +#include <asm/checksum.h> +#include <linux/init.h> + +#include <asm/amazon/amazon.h> +#include <asm/amazon/amazon_dma.h> +#include <asm/amazon/amazon_sw.h> + +// how many mii ports are there ? +#define AMAZON_SW_INT_NO 2 + +#define ETHERNET_PACKET_DMA_BUFFER_SIZE 1536 + +/***************************************** Module Parameters *************************************/ +char mode[] = "bridge"; +module_param_array(mode, charp, NULL, 0); + +static int timeout = 1 * HZ; +module_param(timeout, int, 0); + +int switch_init(struct net_device *dev); +void switch_tx_timeout(struct net_device *dev); + +struct net_device switch_devs[2] = { + {init:switch_init,}, + {init:switch_init,} +}; + +int add_mac_table_entry(u64 entry_value) +{ + int i; + u32 data1, data2; + + AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) = ~7; + + for (i = 0; i < 32; i++) { + AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0x80000000 | 0x20 | i; + while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {}; + data1 = AMAZON_SW_REG32(AMAZON_SW_DATA1); + data2 = AMAZON_SW_REG32(AMAZON_SW_DATA2); + if ((data1 & (0x00700000)) != 0x00700000) + continue; + AMAZON_SW_REG32(AMAZON_SW_DATA1) = (u32) (entry_value >> 32); + AMAZON_SW_REG32(AMAZON_SW_DATA2) = (u32) entry_value & 0xffffffff; + AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0xc0000020 | i; + while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {}; + break; + } + AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) |= 7; + if (i >= 32) + return -1; + return OK; +} + +u64 read_mac_table_entry(int index) +{ + u32 data1, data2; + u64 value; + AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0x80000000 | 0x20 | index; + while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {}; + data1 = AMAZON_SW_REG32(AMAZON_SW_DATA1) & 0xffffff; + data2 = AMAZON_SW_REG32(AMAZON_SW_DATA2); + value = (u64) data1 << 32 | (u64) data2; + return value; +} + +int write_mac_table_entry(int index, u64 value) +{ + u32 data1, data2; + data1 = (u32) (value >> 32); + data2 = (u32) value & 0xffffffff; + AMAZON_SW_REG32(AMAZON_SW_DATA1) = data1; + AMAZON_SW_REG32(AMAZON_SW_DATA2) = data2; + AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) = 0xc0000020 | index; + while (AMAZON_SW_REG32(AMAZON_SW_CPU_ACTL) & (0x80000000)) {}; + return OK; +} + +u32 get_mdio_reg(int phy_addr, int reg_num) +{ + u32 value; + AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = (3 << 30) | ((phy_addr & 0x1f) << 21) | ((reg_num & 0x1f) << 16); + while (AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & (1 << 31)) {}; + value = AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & 0xffff; + return value; +} + +int set_mdio_reg(int phy_addr, int reg_num, u32 value) +{ + AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = (2 << 30) | ((phy_addr & 0x1f) << 21) | ((reg_num & 0x1f) << 16) | (value & 0xffff); + while (AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) & (1 << 31)) {}; + return OK; +} + +int auto_negotiate(int phy_addr) +{ + u32 value = 0; + value = get_mdio_reg(phy_addr, MDIO_BASE_CONTROL_REG); + set_mdio_reg(phy_addr, MDIO_BASE_CONTROL_REG, (value | RESTART_AUTO_NEGOTIATION | AUTO_NEGOTIATION_ENABLE | PHY_RESET)); + return OK; +} + +/* + In this version of switch driver, we split the dma channels for the switch. + 2 for port0 and 2 for port1. So that we can do internal bridging if necessary. + In switch mode, packets coming in from port0 or port1 is able to do Destination + address lookup. Packets coming from port0 with destination address of port1 should + not go to pmac again. The switch hardware should be able to do the switch in the hard + ware level. Packets coming from the pmac should not do the DA look up in that the + desination is already known for the kernel. It only needs to go to the correct NIC to + find its way out. + */ +int amazon_sw_chip_init(void) +{ + u32 tmp1; + int i = 0; + + /* Aging tick select: 5mins */ + tmp1 = 0xa0; + if (strcmp(mode, "bridge") == 0) { + // bridge mode, set militarised mode to 1, no learning! + tmp1 |= 0xC00; + } else { + // enable learning for P0 and P1, + tmp1 |= 3; + } + + /* unknown broadcast/multicast/unicast to all ports */ + AMAZON_SW_REG32(AMAZON_SW_UN_DEST) = 0x1ff; + + AMAZON_SW_REG32(AMAZON_SW_ARL_CTL) = tmp1; + + /* OCS:1 set OCS bit, split the two NIC in rx direction EDL:1 (enable DA lookup) */ +#if defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT) || defined(CONFIG_IFX_NFEXT_AMAZON_SWITCH_PHYPORT_MODULE) + AMAZON_SW_REG32(AMAZON_SW_P2_PCTL) = 0x700; +#else + AMAZON_SW_REG32(AMAZON_SW_P2_PCTL) = 0x401; +#endif + + /* EPC: 1 split the two NIC in tx direction CRC is generated */ + AMAZON_SW_REG32(AMAZON_SW_P2_CTL) = 0x6; + + // for bi-directional + AMAZON_SW_REG32(AMAZON_SW_P0_WM) = 0x14141412; + AMAZON_SW_REG32(AMAZON_SW_P1_WM) = 0x14141412; + AMAZON_SW_REG32(AMAZON_SW_P2_WM) = 0x28282826; + AMAZON_SW_REG32(AMAZON_SW_GBL_WM) = 0x0; + + AMAZON_SW_REG32(AMAZON_CGU_PLL0SR) = (AMAZON_SW_REG32(AMAZON_CGU_PLL0SR)) | 0x58000000; + // clock for PHY + AMAZON_SW_REG32(AMAZON_CGU_IFCCR) = (AMAZON_SW_REG32(AMAZON_CGU_IFCCR)) | 0x80000004; + // enable power for PHY + AMAZON_SW_REG32(AMAZON_PMU_PWDCR) = (AMAZON_SW_REG32(AMAZON_PMU_PWDCR)) | AMAZON_PMU_PWDCR_EPHY; + // set reverse MII, enable MDIO statemachine + AMAZON_SW_REG32(AMAZON_SW_MDIO_CFG) = 0x800027bf; + while (1) + if (((AMAZON_SW_REG32(AMAZON_SW_MDIO_CFG)) & 0x80000000) == 0) + break; + AMAZON_SW_REG32(AMAZON_SW_EPHY) = 0xff; + + // auto negotiation + AMAZON_SW_REG32(AMAZON_SW_MDIO_ACC) = 0x83e08000; + auto_negotiate(0x1f); + + /* enable all ports */ + AMAZON_SW_REG32(AMAZON_SW_PS_CTL) = 0x7; + for (i = 0; i < 32; i++) + write_mac_table_entry(i, 1 << 50); + return 0; +} + +static unsigned char my_ethaddr[MAX_ADDR_LEN]; +/* need to get the ether addr from u-boot */ +static int __init ethaddr_setup(char *line) +{ + char *ep; + int i; + + memset(my_ethaddr, 0, MAX_ADDR_LEN); + for (i = 0; i < 6; i++) { + my_ethaddr[i] = line ? simple_strtoul(line, &ep, 16) : 0; + if (line) + line = (*ep) ? ep + 1 : ep; + } + printk("mac address %2x-%2x-%2x-%2x-%2x-%2x \n", my_ethaddr[0], my_ethaddr[1], my_ethaddr[2], my_ethaddr[3], my_ethaddr[4], my_ethaddr[5]); + return 0; +} + +__setup("ethaddr=", ethaddr_setup); + +static void open_rx_dma(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) dev->priv; + struct dma_device_info *dma_dev = priv->dma_device; + int i; + + for (i = 0; i < dma_dev->num_rx_chan; i++) + dma_dev->rx_chan[i].control = 1; + dma_device_update_rx(dma_dev); +} + +#ifdef CONFIG_NET_HW_FLOWCONTROL +static void close_rx_dma(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) dev->priv; + struct dma_device_info *dma_dev = priv->dma_device; + int i; + + for (i = 0; i < dma_dev->num_rx_chan; i++) + dma_dev->rx_chan[i].control = 0; + dma_device_update_rx(dma_dev); +} + +void amazon_xon(struct net_device *dev) +{ + unsigned long flag; + local_irq_save(flag); + open_rx_dma(dev); + local_irq_restore(flag); +} +#endif + +int switch_open(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) dev->priv; + if (!strcmp(dev->name, "eth1")) { + priv->mdio_phy_addr = PHY0_ADDR; + } + open_rx_dma(dev); + +#ifdef CONFIG_NET_HW_FLOWCONTROL + if ((priv->fc_bit = netdev_register_fc(dev, amazon_xon)) == 0) { + printk("Hardware Flow Control register fails\n"); + } +#endif + + netif_start_queue(dev); + return OK; +} + +int switch_release(struct net_device *dev) +{ + int i; + struct switch_priv *priv = (struct switch_priv *) dev->priv; + struct dma_device_info *dma_dev = priv->dma_device; + + for (i = 0; i < dma_dev->num_tx_chan; i++) + dma_dev->tx_chan[i].control = 0; + for (i = 0; i < dma_dev->num_rx_chan; i++) + dma_dev->rx_chan[i].control = 0; + + dma_device_update(dma_dev); + +#ifdef CONFIG_NET_HW_FLOWCONTROL + if (priv->fc_bit) { + netdev_unregister_fc(priv->fc_bit); + } +#endif + netif_stop_queue(dev); + + return OK; +} + + +void switch_rx(struct net_device *dev, int len, struct sk_buff *skb) +{ + struct switch_priv *priv = (struct switch_priv *) dev->priv; +#ifdef CONFIG_NET_HW_FLOWCONTROL + int mit_sel = 0; +#endif + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + +#ifdef CONFIG_NET_HW_FLOWCONTROL + mit_sel = netif_rx(skb); + switch (mit_sel) { + case NET_RX_SUCCESS: + case NET_RX_CN_LOW: + case NET_RX_CN_MOD: + break; + case NET_RX_CN_HIGH: + break; + case NET_RX_DROP: + if ((priv->fc_bit) + && (!test_and_set_bit(priv->fc_bit, &netdev_fc_xoff))) { + close_rx_dma(dev); + } + break; + } +#else + netif_rx(skb); +#endif + priv->stats.rx_packets++; + priv->stats.rx_bytes += len; + return; +} + +int asmlinkage switch_hw_tx(char *buf, int len, struct net_device *dev) +{ + struct switch_priv *priv = dev->priv; + struct dma_device_info *dma_dev = priv->dma_device; + + dma_dev->current_tx_chan = 0; + return dma_device_write(dma_dev, buf, len, priv->skb); +} + +int asmlinkage switch_tx(struct sk_buff *skb, struct net_device *dev) +{ + int len; + char *data; + struct switch_priv *priv = (struct switch_priv *) dev->priv; + + len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; + data = skb->data; + priv->skb = skb; + dev->trans_start = jiffies; + + if (switch_hw_tx(data, len, dev) != len) { + dev_kfree_skb_any(skb); + return OK; + } + + priv->stats.tx_packets++; + priv->stats.tx_bytes += len; + return OK; +} + +void switch_tx_timeout(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) dev->priv; + priv->stats.tx_errors++; + netif_wake_queue(dev); + return; +} + +void negotiate(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) dev->priv; + unsigned short data = get_mdio_reg(priv->mdio_phy_addr, MDIO_ADVERTISMENT_REG); + + data &= ~(MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD); + + switch (priv->current_speed_selection) { + case 10: + if (priv->current_duplex == full) + data |= MDIO_ADVERT_10_FD; + else if (priv->current_duplex == half) + data |= MDIO_ADVERT_10_HD; + else + data |= MDIO_ADVERT_10_HD | MDIO_ADVERT_10_FD; + break; + + case 100: + if (priv->current_duplex == full) + data |= MDIO_ADVERT_100_FD; + else if (priv->current_duplex == half) + data |= MDIO_ADVERT_100_HD; + else + data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD; + break; + + case 0: /* Auto */ + if (priv->current_duplex == full) + data |= MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD; + else if (priv->current_duplex == half) + data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_10_HD; + else + data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD; + break; + + default: /* assume autoneg speed and duplex */ + data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD; + } + + set_mdio_reg(priv->mdio_phy_addr, MDIO_ADVERTISMENT_REG, data); + + /* Renegotiate with link partner */ + + data = get_mdio_reg(priv->mdio_phy_addr, MDIO_BASE_CONTROL_REG); + data |= MDIO_BC_NEGOTIATE; + + set_mdio_reg(priv->mdio_phy_addr, MDIO_BASE_CONTROL_REG, data); + +} + + +void set_duplex(struct net_device *dev, enum duplex new_duplex) +{ + struct switch_priv *priv = (struct switch_priv *) dev->priv; + if (new_duplex != priv->current_duplex) { + priv->current_duplex = new_duplex; + negotiate(dev); + } +} + +void set_speed(struct net_device *dev, unsigned long speed) +{ + struct switch_priv *priv = (struct switch_priv *) dev->priv; + priv->current_speed_selection = speed; + negotiate(dev); +} + +static int switch_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) +{ + struct switch_priv *priv = (struct switch_priv *) dev->priv; + struct ethtool_cmd ecmd; + + if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd))) + return -EFAULT; + + switch (ecmd.cmd) { + case ETHTOOL_GSET: + memset((void *) &ecmd, 0, sizeof(ecmd)); + ecmd.supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; + ecmd.port = PORT_TP; + ecmd.transceiver = XCVR_EXTERNAL; + ecmd.phy_address = priv->mdio_phy_addr; + + ecmd.speed = priv->current_speed; + + ecmd.duplex = priv->full_duplex ? DUPLEX_FULL : DUPLEX_HALF; + + ecmd.advertising = ADVERTISED_TP; + if (priv->current_duplex == autoneg && priv->current_speed_selection == 0) + ecmd.advertising |= ADVERTISED_Autoneg; + else { + ecmd.advertising |= ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; + if (priv->current_speed_selection == 10) + ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full); + else if (priv->current_speed_selection == 100) + ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full); + if (priv->current_duplex == half) + ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full); + else if (priv->current_duplex == full) + ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half); + } + ecmd.autoneg = AUTONEG_ENABLE; + if (copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd))) + return -EFAULT; + break; + + case ETHTOOL_SSET: + if (!capable(CAP_NET_ADMIN)) { + return -EPERM; + } + if (ecmd.autoneg == AUTONEG_ENABLE) { + set_duplex(dev, autoneg); + set_speed(dev, 0); + } else { + set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full); + set_speed(dev, ecmd.speed == SPEED_10 ? 10 : 100); + } + break; + + case ETHTOOL_GDRVINFO: + { + struct ethtool_drvinfo info; + memset((void *) &info, 0, sizeof(info)); + strncpy(info.driver, "AMAZONE", sizeof(info.driver) - 1); + strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1); + strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1); + info.regdump_len = 0; + info.eedump_len = 0; + info.testinfo_len = 0; + if (copy_to_user(ifr->ifr_data, &info, sizeof(info))) + return -EFAULT; + } + break; + case ETHTOOL_NWAY_RST: + if (priv->current_duplex == autoneg && priv->current_speed_selection == 0) + negotiate(dev); + break; + default: + return -EOPNOTSUPP; + break; + } + return 0; +} + + + +int mac_table_tools_ioctl(struct net_device *dev, struct mac_table_req *req) +{ + int cmd; + int i; + cmd = req->cmd; + switch (cmd) { + case RESET_MAC_TABLE: + for (i = 0; i < 32; i++) { + write_mac_table_entry(i, 0); + } + break; + case READ_MAC_ENTRY: + req->entry_value = read_mac_table_entry(req->index); + break; + case WRITE_MAC_ENTRY: + write_mac_table_entry(req->index, req->entry_value); + break; + case ADD_MAC_ENTRY: + add_mac_table_entry(req->entry_value); + break; + default: + return -EINVAL; + } + + return 0; +} + + +/* + the ioctl for the switch driver is developed in the conventional way + the control type falls into some basic categories, among them, the + SIOCETHTOOL is the traditional eth interface. VLAN_TOOLS and + MAC_TABLE_TOOLS are designed specifically for amazon chip. User + should be aware of the data structures used in these interfaces. +*/ +int switch_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct data_req *switch_data_req = (struct data_req *) ifr->ifr_data; + struct mac_table_req *switch_mac_table_req; + switch (cmd) { + case SIOCETHTOOL: + switch_ethtool_ioctl(dev, ifr); + break; + case SIOCGMIIPHY: /* Get PHY address */ + break; + case SIOCGMIIREG: /* Read MII register */ + break; + case SIOCSMIIREG: /* Write MII register */ + break; + case SET_ETH_SPEED_10: /* 10 Mbps */ + break; + case SET_ETH_SPEED_100: /* 100 Mbps */ + break; + case SET_ETH_SPEED_AUTO: /* Auto negotiate speed */ + break; + case SET_ETH_DUPLEX_HALF: /* Half duplex. */ + break; + case SET_ETH_DUPLEX_FULL: /* Full duplex. */ + break; + case SET_ETH_DUPLEX_AUTO: /* Autonegotiate duplex */ + break; + case SET_ETH_REG: + AMAZON_SW_REG32(switch_data_req->index) = switch_data_req->value; + break; + case MAC_TABLE_TOOLS: + switch_mac_table_req = (struct mac_table_req *) ifr->ifr_data; + mac_table_tools_ioctl(dev, switch_mac_table_req); + break; + default: + return -EINVAL; + } + + return 0; +} + +struct net_device_stats *switch_stats(struct net_device *dev) +{ + struct switch_priv *priv = (struct switch_priv *) dev->priv; + return &priv->stats; +} + +int switch_change_mtu(struct net_device *dev, int new_mtu) +{ + if (new_mtu >= 1516) + new_mtu = 1516; + dev->mtu = new_mtu; + return 0; +} + +int switch_hw_receive(struct net_device *dev, struct dma_device_info *dma_dev) +{ + u8 *buf = NULL; + int len = 0; + struct sk_buff *skb = NULL; + + len = dma_device_read(dma_dev, &buf, (void **) &skb); + + if (len >= 0x600) { + printk("packet too large %d\n", len); + goto switch_hw_receive_err_exit; + } + + /* remove CRC */ + len -= 4; + if (skb == NULL) { + printk("cannot restore pointer\n"); + goto switch_hw_receive_err_exit; + } + if (len > (skb->end - skb->tail)) { + printk("BUG, len:%d end:%p tail:%p\n", (len + 4), skb->end, skb->tail); + goto switch_hw_receive_err_exit; + } + skb_put(skb, len); + skb->dev = dev; + switch_rx(dev, len, skb); + return OK; + + switch_hw_receive_err_exit: + if (skb) + dev_kfree_skb_any(skb); + return -EIO; +} + +int dma_intr_handler(struct dma_device_info *dma_dev, int status) +{ + struct net_device *dev; + + dev = switch_devs + (u32) dma_dev->priv; + switch (status) { + case RCV_INT: + switch_hw_receive(dev, dma_dev); + break; + case TX_BUF_FULL_INT: + netif_stop_queue(dev); + break; + case TRANSMIT_CPT_INT: + netif_wake_queue(dev); + break; + } + return OK; +} + +/* reserve 2 bytes in front of data pointer*/ +u8 *dma_buffer_alloc(int len, int *byte_offset, void **opt) +{ + u8 *buffer = NULL; + struct sk_buff *skb = NULL; + skb = dev_alloc_skb(ETHERNET_PACKET_DMA_BUFFER_SIZE); + if (skb == NULL) { + return NULL; + } + buffer = (u8 *) (skb->data); + skb_reserve(skb, 2); + *(int *) opt = (int) skb; + *byte_offset = 2; + return buffer; +} + +int dma_buffer_free(u8 * dataptr, void *opt) +{ + struct sk_buff *skb = NULL; + if (opt == NULL) { + kfree(dataptr); + } else { + skb = (struct sk_buff *) opt; + dev_kfree_skb_any(skb); + } + return OK; +} + +int init_dma_device(_dma_device_info * dma_dev) +{ + int i; + int num_tx_chan, num_rx_chan; + if (strcmp(dma_dev->device_name, "switch1") == 0) { + num_tx_chan = 1; + num_rx_chan = 2; + dma_dev->priv = (void *) 0; + } else { + num_tx_chan = 1; + num_rx_chan = 2; + dma_dev->priv = (void *) 1; + } + + dma_dev->weight = 1; + dma_dev->num_tx_chan = num_tx_chan; + dma_dev->num_rx_chan = num_rx_chan; + dma_dev->ack = 1; + dma_dev->tx_burst_len = 4; + dma_dev->rx_burst_len = 4; + for (i = 0; i < dma_dev->num_tx_chan; i++) { + dma_dev->tx_chan[i].weight = QOS_DEFAULT_WGT; + dma_dev->tx_chan[i].desc_num = 10; + dma_dev->tx_chan[i].packet_size = 0; + dma_dev->tx_chan[i].control = 0; + } + for (i = 0; i < num_rx_chan; i++) { + dma_dev->rx_chan[i].weight = QOS_DEFAULT_WGT; + dma_dev->rx_chan[i].desc_num = 10; + dma_dev->rx_chan[i].packet_size = ETHERNET_PACKET_DMA_BUFFER_SIZE; + dma_dev->rx_chan[i].control = 0; + } + dma_dev->intr_handler = dma_intr_handler; + dma_dev->buffer_alloc = dma_buffer_alloc; + dma_dev->buffer_free = dma_buffer_free; + return 0; +} + +int switch_set_mac_address(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + return OK; +} + + +int switch_init(struct net_device *dev) +{ + u64 retval = 0; + int i; + int result; + struct switch_priv *priv; + ether_setup(dev); /* assign some of the fields */ + printk("%s up using ", dev->name); + dev->open = switch_open; + dev->stop = switch_release; + dev->hard_start_xmit = switch_tx; + dev->do_ioctl = switch_ioctl; + dev->get_stats = switch_stats; + dev->change_mtu = switch_change_mtu; + dev->set_mac_address = switch_set_mac_address; + dev->tx_timeout = switch_tx_timeout; + dev->watchdog_timeo = timeout; + + SET_MODULE_OWNER(dev); + + dev->priv = kmalloc(sizeof(struct switch_priv), GFP_KERNEL); + if (dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct switch_priv)); + priv = dev->priv; + priv->dma_device = (struct dma_device_info *) kmalloc(sizeof(struct dma_device_info), GFP_KERNEL); + if ((dev - switch_devs) == 0) { + sprintf(priv->dma_device->device_name, "switch1"); + } else if ((dev - switch_devs) == 1) { + sprintf(priv->dma_device->device_name, "switch2"); + } + printk("\"%s\"\n", priv->dma_device->device_name); + init_dma_device(priv->dma_device); + result = dma_device_register(priv->dma_device); + + /* read the mac address from the mac table and put them into the mac table. */ + for (i = 0; i < 6; i++) { + retval += my_ethaddr[i]; + } + /* ethaddr not set in u-boot ? */ + if (retval == 0) { + dev->dev_addr[0] = 0x00; + dev->dev_addr[1] = 0x20; + dev->dev_addr[2] = 0xda; + dev->dev_addr[3] = 0x86; + dev->dev_addr[4] = 0x23; + dev->dev_addr[5] = 0x74 + (unsigned char) (dev - switch_devs); + } else { + for (i = 0; i < 6; i++) { + dev->dev_addr[i] = my_ethaddr[i]; + } + dev->dev_addr[5] += +(unsigned char) (dev - switch_devs); + } + return OK; +} + +int switch_init_module(void) +{ + int i = 0, result, device_present = 0; + + for (i = 0; i < AMAZON_SW_INT_NO; i++) { + sprintf(switch_devs[i].name, "eth%d", i); + + if ((result = register_netdev(switch_devs + i))) + printk("error %i registering device \"%s\"\n", result, switch_devs[i].name); + else + device_present++; + } + amazon_sw_chip_init(); + return device_present ? 0 : -ENODEV; +} + +void switch_cleanup(void) +{ + int i; + struct switch_priv *priv; + for (i = 0; i < AMAZON_SW_INT_NO; i++) { + priv = switch_devs[i].priv; + if (priv->dma_device) { + dma_device_unregister(priv->dma_device); + kfree(priv->dma_device); + } + kfree(switch_devs[i].priv); + unregister_netdev(switch_devs + i); + } + return; +} + +module_init(switch_init_module); +module_exit(switch_cleanup); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Wu Qi Ming"); diff --git a/target/linux/amazon/files/drivers/serial/amazon_asc.c b/target/linux/amazon/files/drivers/serial/amazon_asc.c new file mode 100644 index 0000000000..7c17cb0f4a --- /dev/null +++ b/target/linux/amazon/files/drivers/serial/amazon_asc.c @@ -0,0 +1,685 @@ +/* + * Driver for AMAZONASC serial ports + * + * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. + * Based on drivers/serial/serial_s3c2400.c + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Copyright (C) 2004 Infineon IFAP DC COM CPE + * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org> + * Copyright (C) 2007 John Crispin <blogic@openwrt.org> + */ + +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/tty.h> +#include <linux/tty_flip.h> +#include <linux/major.h> +#include <linux/string.h> +#include <linux/fcntl.h> +#include <linux/ptrace.h> +#include <linux/ioport.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/init.h> +#include <linux/circ_buf.h> +#include <linux/serial.h> +#include <linux/serial_core.h> +#include <linux/console.h> +#include <linux/sysrq.h> +#include <linux/irq.h> + +#include <asm/system.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/bitops.h> +#include <asm/amazon/amazon.h> +#include <asm/amazon/irq.h> +#include <asm/amazon/serial.h> + +#define PORT_AMAZONASC 111 + +#include <linux/serial_core.h> + +#define UART_NR 1 + +#define UART_DUMMY_UER_RX 1 + +#define SERIAL_AMAZONASC_MAJOR TTY_MAJOR +#define CALLOUT_AMAZONASC_MAJOR TTYAUX_MAJOR +#define SERIAL_AMAZONASC_MINOR 64 +#define SERIAL_AMAZONASC_NR UART_NR + +static void amazonasc_tx_chars(struct uart_port *port); +extern void prom_printf(const char * fmt, ...); +static struct uart_port amazonasc_ports[UART_NR]; +static struct uart_driver amazonasc_reg; +static unsigned int uartclk = 0; +extern unsigned int amazon_get_fpi_hz(void); + +static void amazonasc_stop_tx(struct uart_port *port) +{ + /* fifo underrun shuts up after firing once */ + return; +} + +static void amazonasc_start_tx(struct uart_port *port) +{ + unsigned long flags; + + local_irq_save(flags); + amazonasc_tx_chars(port); + local_irq_restore(flags); + + return; +} + +static void amazonasc_stop_rx(struct uart_port *port) +{ + /* clear the RX enable bit */ + amazon_writel(ASCWHBCON_CLRREN, AMAZON_ASC_WHBCON); +} + +static void amazonasc_enable_ms(struct uart_port *port) +{ + /* no modem signals */ + return; +} + +static void +amazonasc_rx_chars(struct uart_port *port) +{ + struct tty_struct *tty = port->info->tty; + unsigned int ch = 0, rsr = 0, fifocnt; + + fifocnt = amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_RXFFLMASK; + while (fifocnt--) + { + u8 flag = TTY_NORMAL; + ch = amazon_readl(AMAZON_ASC_RBUF); + rsr = (amazon_readl(AMAZON_ASC_CON) & ASCCON_ANY) | UART_DUMMY_UER_RX; + tty_flip_buffer_push(tty); + port->icount.rx++; + + /* + * Note that the error handling code is + * out of the main execution path + */ + if (rsr & ASCCON_ANY) { + if (rsr & ASCCON_PE) { + port->icount.parity++; + amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLRPE, ASCWHBCON_CLRPE); + } else if (rsr & ASCCON_FE) { + port->icount.frame++; + amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLRFE, ASCWHBCON_CLRFE); + } + if (rsr & ASCCON_OE) { + port->icount.overrun++; + amazon_writel_masked(AMAZON_ASC_WHBCON, ASCWHBCON_CLROE, ASCWHBCON_CLROE); + } + + rsr &= port->read_status_mask; + + if (rsr & ASCCON_PE) + flag = TTY_PARITY; + else if (rsr & ASCCON_FE) + flag = TTY_FRAME; + } + + if ((rsr & port->ignore_status_mask) == 0) + tty_insert_flip_char(tty, ch, flag); + + if (rsr & ASCCON_OE) + /* + * Overrun is special, since it's reported + * immediately, and doesn't affect the current + * character + */ + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + if (ch != 0) + tty_flip_buffer_push(tty); + + return; +} + + +static void amazonasc_tx_chars(struct uart_port *port) +{ + struct circ_buf *xmit = &port->info->xmit; + + if (uart_tx_stopped(port)) { + amazonasc_stop_tx(port); + return; + } + + while (((amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_TXFFLMASK) + >> ASCFSTAT_TXFFLOFF) != AMAZONASC_TXFIFO_FULL) + { + if (port->x_char) { + amazon_writel(port->x_char, AMAZON_ASC_TBUF); + port->icount.tx++; + port->x_char = 0; + continue; + } + + if (uart_circ_empty(xmit)) + break; + + amazon_writel(xmit->buf[xmit->tail], AMAZON_ASC_TBUF); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + port->icount.tx++; + } + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); +} + +static irqreturn_t amazonasc_tx_int(int irq, void *port) +{ + amazon_writel(ASC_IRNCR_TIR, AMAZON_ASC_IRNCR1); + amazonasc_start_tx(port); + + /* clear any pending interrupts */ + amazon_writel_masked(AMAZON_ASC_WHBCON, + (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE), + (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE)); + + return IRQ_HANDLED; +} + +static irqreturn_t amazonasc_er_int(int irq, void *port) +{ + /* clear any pending interrupts */ + amazon_writel_masked(AMAZON_ASC_WHBCON, + (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE), + (ASCWHBCON_CLRPE | ASCWHBCON_CLRFE | ASCWHBCON_CLROE)); + + return IRQ_HANDLED; +} + +static irqreturn_t amazonasc_rx_int(int irq, void *port) +{ + amazon_writel(ASC_IRNCR_RIR, AMAZON_ASC_IRNCR1); + amazonasc_rx_chars((struct uart_port *) port); + return IRQ_HANDLED; +} + +static u_int amazonasc_tx_empty(struct uart_port *port) +{ + int status; + + /* + * FSTAT tells exactly how many bytes are in the FIFO. + * The question is whether we really need to wait for all + * 16 bytes to be transmitted before reporting that the + * transmitter is empty. + */ + status = amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_TXFFLMASK; + return status ? 0 : TIOCSER_TEMT; +} + +static u_int amazonasc_get_mctrl(struct uart_port *port) +{ + /* no modem control signals - the readme says to pretend all are set */ + return TIOCM_CTS|TIOCM_CAR|TIOCM_DSR; +} + +static void amazonasc_set_mctrl(struct uart_port *port, u_int mctrl) +{ + /* no modem control - just return */ + return; +} + +static void amazonasc_break_ctl(struct uart_port *port, int break_state) +{ + /* no way to send a break */ + return; +} + +static int amazonasc_startup(struct uart_port *port) +{ + unsigned int con = 0; + unsigned long flags; + int retval; + + /* this assumes: CON.BRS = CON.FDE = 0 */ + if (uartclk == 0) + uartclk = amazon_get_fpi_hz(); + + amazonasc_ports[0].uartclk = uartclk; + + local_irq_save(flags); + + /* this setup was probably already done in u-boot */ + /* ASC and GPIO Port 1 bits 3 and 4 share the same pins + * P1.3 (RX) in, Alternate 10 + * P1.4 (TX) in, Alternate 10 + */ + amazon_writel_masked(AMAZON_GPIO_P1_DIR, 0x18, 0x10); //P1.4 output, P1.3 input + amazon_writel_masked(AMAZON_GPIO_P1_ALTSEL0, 0x18, 0x18); //ALTSETL0 11 + amazon_writel_masked(AMAZON_GPIO_P1_ALTSEL1, 0x18, 0); //ALTSETL1 00 + amazon_writel_masked(AMAZON_GPIO_P1_OD, 0x18, 0x10); + + /* set up the CLC */ + amazon_writel_masked(AMAZON_ASC_CLC, AMAZON_ASC_CLC_DISS, 0); + amazon_writel_masked(AMAZON_ASC_CLC, ASCCLC_RMCMASK, 1 << ASCCLC_RMCOFFSET); + + /* asynchronous mode */ + con = ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_OEN | ASCCON_PEN; + + /* choose the line - there's only one */ + amazon_writel(0, AMAZON_ASC_PISEL); + amazon_writel(((AMAZONASC_TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) | ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU, + AMAZON_ASC_TXFCON); + amazon_writel(((AMAZONASC_RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK) | ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU, + AMAZON_ASC_RXFCON); + wmb(); + + amazon_writel_masked(AMAZON_ASC_CON, con, con); + + retval = request_irq(AMAZONASC_RIR, amazonasc_rx_int, 0, "asc_rx", port); + if (retval){ + printk("failed to request amazonasc_rx_int\n"); + return retval; + } + retval = request_irq(AMAZONASC_TIR, amazonasc_tx_int, 0, "asc_tx", port); + if (retval){ + printk("failed to request amazonasc_tx_int\n"); + goto err1; + } + + retval = request_irq(AMAZONASC_EIR, amazonasc_er_int, 0, "asc_er", port); + if (retval){ + printk("failed to request amazonasc_er_int\n"); + goto err2; + } + + local_irq_restore(flags); + return 0; + +err2: + free_irq(AMAZONASC_TIR, port); + +err1: + free_irq(AMAZONASC_RIR, port); + local_irq_restore(flags); + return retval; +} + +static void amazonasc_shutdown(struct uart_port *port) +{ + free_irq(AMAZONASC_RIR, port); + free_irq(AMAZONASC_TIR, port); + free_irq(AMAZONASC_EIR, port); + /* + * disable the baudrate generator to disable the ASC + */ + amazon_writel(0, AMAZON_ASC_CON); + + /* flush and then disable the fifos */ + amazon_writel_masked(AMAZON_ASC_RXFCON, ASCRXFCON_RXFFLU, ASCRXFCON_RXFFLU); + amazon_writel_masked(AMAZON_ASC_RXFCON, ASCRXFCON_RXFEN, 0); + amazon_writel_masked(AMAZON_ASC_TXFCON, ASCTXFCON_TXFFLU, ASCTXFCON_TXFFLU); + amazon_writel_masked(AMAZON_ASC_TXFCON, ASCTXFCON_TXFEN, 0); +} + +static void amazonasc_set_termios(struct uart_port *port, struct ktermios *new, struct ktermios *old) +{ + unsigned int cflag; + unsigned int iflag; + unsigned int baud, quot; + unsigned int con = 0; + unsigned long flags; + + cflag = new->c_cflag; + iflag = new->c_iflag; + + /* byte size and parity */ + switch (cflag & CSIZE) { + /* 7 bits are always with parity */ + case CS7: con = ASCCON_M_7ASYNCPAR; break; + /* the ASC only suports 7 and 8 bits */ + case CS5: + case CS6: + default: + if (cflag & PARENB) + con = ASCCON_M_8ASYNCPAR; + else + con = ASCCON_M_8ASYNC; + break; + } + if (cflag & CSTOPB) + con |= ASCCON_STP; + if (cflag & PARENB) { + if (!(cflag & PARODD)) + con &= ~ASCCON_ODD; + else + con |= ASCCON_ODD; + } + + port->read_status_mask = ASCCON_OE; + if (iflag & INPCK) + port->read_status_mask |= ASCCON_FE | ASCCON_PE; + + port->ignore_status_mask = 0; + if (iflag & IGNPAR) + port->ignore_status_mask |= ASCCON_FE | ASCCON_PE; + + if (iflag & IGNBRK) { + /* + * If we're ignoring parity and break indicators, + * ignore overruns too (for real raw support). + */ + if (iflag & IGNPAR) + port->ignore_status_mask |= ASCCON_OE; + } + + /* + * Ignore all characters if CREAD is not set. + */ + if ((cflag & CREAD) == 0) + port->ignore_status_mask |= UART_DUMMY_UER_RX; + + /* set error signals - framing, parity and overrun */ + con |= ASCCON_FEN; + con |= ASCCON_OEN; + con |= ASCCON_PEN; + /* enable the receiver */ + con |= ASCCON_REN; + + /* block the IRQs */ + local_irq_save(flags); + + /* set up CON */ + amazon_writel(con, AMAZON_ASC_CON); + + /* Set baud rate - take a divider of 2 into account */ + baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); + quot = uart_get_divisor(port, baud); + quot = quot/2 - 1; + + /* the next 3 probably already happened when we set CON above */ + /* disable the baudrate generator */ + amazon_writel_masked(AMAZON_ASC_CON, ASCCON_R, 0); + /* make sure the fractional divider is off */ + amazon_writel_masked(AMAZON_ASC_CON, ASCCON_FDE, 0); + /* set up to use divisor of 2 */ + amazon_writel_masked(AMAZON_ASC_CON, ASCCON_BRS, 0); + /* now we can write the new baudrate into the register */ + amazon_writel(quot, AMAZON_ASC_BTR); + /* turn the baudrate generator back on */ + amazon_writel_masked(AMAZON_ASC_CON, ASCCON_R, ASCCON_R); + + local_irq_restore(flags); +} + +static const char *amazonasc_type(struct uart_port *port) +{ + return port->type == PORT_AMAZONASC ? "AMAZONASC" : NULL; +} + +/* + * Release the memory region(s) being used by 'port' + */ +static void amazonasc_release_port(struct uart_port *port) +{ + return; +} + +/* + * Request the memory region(s) being used by 'port' + */ +static int amazonasc_request_port(struct uart_port *port) +{ + return 0; +} + +/* + * Configure/autoconfigure the port. + */ +static void amazonasc_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) { + port->type = PORT_AMAZONASC; + amazonasc_request_port(port); + } +} + +/* + * verify the new serial_struct (for TIOCSSERIAL). + */ +static int amazonasc_verify_port(struct uart_port *port, struct serial_struct *ser) +{ + int ret = 0; + if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMAZONASC) + ret = -EINVAL; + if (ser->irq < 0 || ser->irq >= NR_IRQS) + ret = -EINVAL; + if (ser->baud_base < 9600) + ret = -EINVAL; + return ret; +} + +static struct uart_ops amazonasc_pops = { + .tx_empty = amazonasc_tx_empty, + .set_mctrl = amazonasc_set_mctrl, + .get_mctrl = amazonasc_get_mctrl, + .stop_tx = amazonasc_stop_tx, + .start_tx = amazonasc_start_tx, + .stop_rx = amazonasc_stop_rx, + .enable_ms = amazonasc_enable_ms, + .break_ctl = amazonasc_break_ctl, + .startup = amazonasc_startup, + .shutdown = amazonasc_shutdown, + .set_termios = amazonasc_set_termios, + .type = amazonasc_type, + .release_port = amazonasc_release_port, + .request_port = amazonasc_request_port, + .config_port = amazonasc_config_port, + .verify_port = amazonasc_verify_port, +}; + +static struct uart_port amazonasc_ports[UART_NR] = { + { + membase: (void *)AMAZON_ASC, + mapbase: AMAZON_ASC, + iotype: SERIAL_IO_MEM, + irq: AMAZONASC_RIR, /* RIR */ + uartclk: 0, /* filled in dynamically */ + fifosize: 16, + unused: { AMAZONASC_TIR, AMAZONASC_EIR}, /* xmit/error/xmit-buffer-empty IRQ */ + type: PORT_AMAZONASC, + ops: &amazonasc_pops, + flags: ASYNC_BOOT_AUTOCONF, + }, +}; + +static void amazonasc_console_write(struct console *co, const char *s, u_int count) +{ + int i, fifocnt; + unsigned long flags; + local_irq_save(flags); + for (i = 0; i < count;) + { + /* wait until the FIFO is not full */ + do + { + fifocnt = (amazon_readl(AMAZON_ASC_FSTAT) & ASCFSTAT_TXFFLMASK) + >> ASCFSTAT_TXFFLOFF; + } while (fifocnt == AMAZONASC_TXFIFO_FULL); + if (s[i] == '\0') + { + break; + } + if (s[i] == '\n') + { + amazon_writel('\r', AMAZON_ASC_TBUF); + do + { + fifocnt = (amazon_readl(AMAZON_ASC_FSTAT) & + ASCFSTAT_TXFFLMASK) >> ASCFSTAT_TXFFLOFF; + } while (fifocnt == AMAZONASC_TXFIFO_FULL); + } + amazon_writel(s[i], AMAZON_ASC_TBUF); + i++; + } + + local_irq_restore(flags); +} + +static void __init +amazonasc_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits) +{ + u_int lcr_h; + + lcr_h = amazon_readl(AMAZON_ASC_CON); + /* do this only if the ASC is turned on */ + if (lcr_h & ASCCON_R) { + u_int quot, div, fdiv, frac; + + *parity = 'n'; + if ((lcr_h & ASCCON_MODEMASK) == ASCCON_M_7ASYNCPAR || + (lcr_h & ASCCON_MODEMASK) == ASCCON_M_8ASYNCPAR) { + if (lcr_h & ASCCON_ODD) + *parity = 'o'; + else + *parity = 'e'; + } + + if ((lcr_h & ASCCON_MODEMASK) == ASCCON_M_7ASYNCPAR) + *bits = 7; + else + *bits = 8; + + quot = amazon_readl(AMAZON_ASC_BTR) + 1; + + /* this gets hairy if the fractional divider is used */ + if (lcr_h & ASCCON_FDE) + { + div = 1; + fdiv = amazon_readl(AMAZON_ASC_FDV); + if (fdiv == 0) + fdiv = 512; + frac = 512; + } + else + { + div = lcr_h & ASCCON_BRS ? 3 : 2; + fdiv = frac = 1; + } + /* + * This doesn't work exactly because we use integer + * math to calculate baud which results in rounding + * errors when we try to go from quot -> baud !! + * Try to make this work for both the fractional divider + * and the simple divider. Also try to avoid rounding + * errors using integer math. + */ + + *baud = frac * (port->uartclk / (div * 512 * 16 * quot)); + if (*baud > 1100 && *baud < 2400) + *baud = 1200; + if (*baud > 2300 && *baud < 4800) + *baud = 2400; + if (*baud > 4700 && *baud < 9600) + *baud = 4800; + if (*baud > 9500 && *baud < 19200) + *baud = 9600; + if (*baud > 19000 && *baud < 38400) + *baud = 19200; + if (*baud > 38400 && *baud < 57600) + *baud = 38400; + if (*baud > 57600 && *baud < 115200) + *baud = 57600; + if (*baud > 115200 && *baud < 230400) + *baud = 115200; + } +} + +static int __init amazonasc_console_setup(struct console *co, char *options) +{ + struct uart_port *port; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + /* this assumes: CON.BRS = CON.FDE = 0 */ + if (uartclk == 0) + uartclk = amazon_get_fpi_hz(); + co->index = 0; + port = &amazonasc_ports[0]; + amazonasc_ports[0].uartclk = uartclk; + amazonasc_ports[0].type = PORT_AMAZONASC; + + if (options){ + uart_parse_options(options, &baud, &parity, &bits, &flow); + } + + return uart_set_options(port, co, baud, parity, bits, flow); +} + +static struct uart_driver amazonasc_reg; +static struct console amazonasc_console = { + name: "ttyS", + write: amazonasc_console_write, + device: uart_console_device, + setup: amazonasc_console_setup, + flags: CON_PRINTBUFFER, + index: -1, + data: &amazonasc_reg, +}; + +static int __init amazonasc_console_init(void) +{ + register_console(&amazonasc_console); + return 0; +} +console_initcall(amazonasc_console_init); + +static struct uart_driver amazonasc_reg = { + .owner = THIS_MODULE, + .driver_name = "serial", + .dev_name = "ttyS", + .major = TTY_MAJOR, + .minor = 64, + .nr = UART_NR, + .cons = &amazonasc_console, +}; + +static int __init amazonasc_init(void) +{ + unsigned char res; + uart_register_driver(&amazonasc_reg); + res = uart_add_one_port(&amazonasc_reg, &amazonasc_ports[0]); + return res; +} + +static void __exit amazonasc_exit(void) +{ + uart_unregister_driver(&amazonasc_reg); +} + +module_init(amazonasc_init); +module_exit(amazonasc_exit); + +MODULE_AUTHOR("Gary Jennejohn, Felix Fietkau, John Crispin"); +MODULE_DESCRIPTION("MIPS AMAZONASC serial port driver"); +MODULE_LICENSE("GPL"); diff --git a/target/linux/amazon/files/include/asm-mips/amazon/adm6996.h b/target/linux/amazon/files/include/asm-mips/amazon/adm6996.h new file mode 100644 index 0000000000..77cf4b131d --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/adm6996.h @@ -0,0 +1,232 @@ +/****************************************************************************** + Copyright (c) 2004, Infineon Technologies. All rights reserved. + + No Warranty + Because the program is licensed free of charge, there is no warranty for + the program, to the extent permitted by applicable law. Except when + otherwise stated in writing the copyright holders and/or other parties + provide the program "as is" without warranty of any kind, either + expressed or implied, including, but not limited to, the implied + warranties of merchantability and fitness for a particular purpose. The + entire risk as to the quality and performance of the program is with + you. should the program prove defective, you assume the cost of all + necessary servicing, repair or correction. + + In no event unless required by applicable law or agreed to in writing + will any copyright holder, or any other party who may modify and/or + redistribute the program as permitted above, be liable to you for + damages, including any general, special, incidental or consequential + damages arising out of the use or inability to use the program + (including but not limited to loss of data or data being rendered + inaccurate or losses sustained by you or third parties or a failure of + the program to operate with any other programs), even if such holder or + other party has been advised of the possibility of such damages. + ****************************************************************************** + Module : ifx_swdrv.h + Date : 2004-09-01 + Description : JoeLin + Remarks: + + *****************************************************************************/ + +#ifndef _ADM_6996_MODULE_H_ +#define _ADM_6996_MODULE_H_ + +#include <asm/amazon/amazon.h> + +#define ifx_printf(x) printk x + +/* command codes */ +#define ADM_SW_SMI_READ 0x02 +#define ADM_SW_SMI_WRITE 0x01 +#define ADM_SW_SMI_START 0x01 + +#define ADM_SW_EEPROM_WRITE 0x01 +#define ADM_SW_EEPROM_WRITE_ENABLE 0x03 +#define ADM_SW_EEPROM_WRITE_DISABLE 0x00 +#define EEPROM_TYPE 8 /* for 93C66 */ + +/* bit masks */ +#define ADM_SW_BIT_MASK_1 0x00000001 +#define ADM_SW_BIT_MASK_2 0x00000002 +#define ADM_SW_BIT_MASK_4 0x00000008 +#define ADM_SW_BIT_MASK_10 0x00000200 +#define ADM_SW_BIT_MASK_16 0x00008000 +#define ADM_SW_BIT_MASK_32 0x80000000 + +/* delay timers */ +#define ADM_SW_MDC_DOWN_DELAY 5 +#define ADM_SW_MDC_UP_DELAY 5 +#define ADM_SW_CS_DELAY 5 + +/* MDIO modes */ +#define ADM_SW_MDIO_OUTPUT 1 +#define ADM_SW_MDIO_INPUT 0 + +#define ADM_SW_MAX_PORT_NUM 5 +#define ADM_SW_MAX_VLAN_NUM 15 + +/* registers */ +#define ADM_SW_PORT0_CONF 0x1 +#define ADM_SW_PORT1_CONF 0x3 +#define ADM_SW_PORT2_CONF 0x5 +#define ADM_SW_PORT3_CONF 0x7 +#define ADM_SW_PORT4_CONF 0x8 +#define ADM_SW_PORT5_CONF 0x9 +#define ADM_SW_VLAN_MODE 0x11 +#define ADM_SW_MAC_LOCK 0x12 +#define ADM_SW_VLAN0_CONF 0x13 +#define ADM_SW_PORT0_PVID 0x28 +#define ADM_SW_PORT1_PVID 0x29 +#define ADM_SW_PORT2_PVID 0x2a +#define ADM_SW_PORT34_PVID 0x2b +#define ADM_SW_PORT5_PVID 0x2c +#define ADM_SW_PHY_RESET 0x2f +#define ADM_SW_MISC_CONF 0x30 +#define ADM_SW_BNDWDH_CTL0 0x31 +#define ADM_SW_BNDWDH_CTL1 0x32 +#define ADM_SW_BNDWDH_CTL_ENA 0x33 + +/* port modes */ +#define ADM_SW_PORT_FLOWCTL 0x1 /* 802.3x flow control */ +#define ADM_SW_PORT_AN 0x2 /* auto negotiation */ +#define ADM_SW_PORT_100M 0x4 /* 100M */ +#define ADM_SW_PORT_FULL 0x8 /* full duplex */ +#define ADM_SW_PORT_TAG 0x10 /* output tag on */ +#define ADM_SW_PORT_DISABLE 0x20 /* disable port */ +#define ADM_SW_PORT_TOS 0x40 /* TOS first */ +#define ADM_SW_PORT_PPRI 0x80 /* port based priority first */ +#define ADM_SW_PORT_MDIX 0x8000 /* auto MDIX on */ +#define ADM_SW_PORT_PVID_SHIFT 10 +#define ADM_SW_PORT_PVID_BITS 4 + +/* VLAN */ +#define ADM_SW_VLAN_PORT0 0x1 +#define ADM_SW_VLAN_PORT1 0x2 +#define ADM_SW_VLAN_PORT2 0x10 +#define ADM_SW_VLAN_PORT3 0x40 +#define ADM_SW_VLAN_PORT4 0x80 +#define ADM_SW_VLAN_PORT5 0x100 + + +/* GPIO 012 enabled, output mode */ +#define GPIO_ENABLEBITS 0x000700f8 + +/* + define AMAZON GPIO port to ADM6996 EEPROM interface + MDIO -> EEDI GPIO 16, AMAZON GPIO P1.0, bi-direction + MDC -> EESK GPIO 17, AMAZON GPIO P1.1, output only + MDCS -> EECS GPIO 18, AMAZON GPIO P1.2, output only + EEDO GPIO 15, AMAZON GPIO P0.15, do not need this one! */ + +#define GPIO_MDIO 1 //P1.0 +#define GPIO_MDC 2 //P1.1 +#define GPIO_MDCS 4 //P1.2 + +//joelin #define GPIO_MDIO 0 +//joelin #define GPIO_MDC 5 /* PORT 0 GPIO5 */ +//joelin #define GPIO_MDCS 6 /* PORT 0 GPIO6 */ + + +#define MDIO_INPUT 0x00000001 +#define MDIO_OUTPUT_EN 0x00010000 + + +/* type definitions */ +typedef unsigned char U8; +typedef unsigned short U16; +typedef unsigned int U32; + +typedef struct _REGRW_ +{ + unsigned int addr; + unsigned int value; + unsigned int mode; +}REGRW, *PREGRW; + +//joelin adm6996i +typedef struct _MACENTRY_ +{ + unsigned char mac_addr[6]; + unsigned long fid:4; + unsigned long portmap:6; + union { + unsigned long age_timer:9; + unsigned long info_ctrl:9; + } ctrl; + unsigned long occupy:1; + unsigned long info_type:1; + unsigned long bad:1; + unsigned long result:3;//000:command ok ,001:all entry used,010:Entry Not found ,011:try next entry ,101:command error + + }MACENTRY, *PMACENTRY; +typedef struct _PROTOCOLFILTER_ +{ + int protocol_filter_num;//[0~7] + int ip_p; //Value Compared with Protocol in IP Heade[7:0] + char action:2;//Action for protocol Filter . +//00 = Protocol Portmap is Default Output Ports. +//01 = Protocol Portmap is 6'b0. +//10 = Protocol Portmap is the CPU port if the incoming port +//is not the CPU port. But if the incoming port is the CPU port, then Type Portmap contains Default Output Ports, excluding the CPU port. + }PROTOCOLFILTER, *PPROTOCOLFILTER; + +//joelin adm6996i + +/* Santosh: for IGMP proxy/snooping */ + +//050614:fchang int adm_process_mac_table_request (unsigned int cmd, struct _MACENTRY_ *mac); +//050614:fchang int adm_process_protocol_filter_request (unsigned int cmd, struct _PROTOCOLFILTER_ *filter); + + +/* IOCTL keys */ +#define KEY_IOCTL_ADM_REGRW 0x01 +#define KEY_IOCTL_ADM_SW_REGRW 0x02 +#define KEY_IOCTL_ADM_SW_PORTSTS 0x03 +#define KEY_IOCTL_ADM_SW_INIT 0x04 +//for adm6996i-start +#define KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_ADD 0x05 +#define KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_DEL 0x06 +#define KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_INIT 0x07 +#define KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_MORE 0x08 +#define KEY_IOCTL_ADM_SW_IOCTL_FILTER_ADD 0x09 +#define KEY_IOCTL_ADM_SW_IOCTL_FILTER_DEL 0x0a +#define KEY_IOCTL_ADM_SW_IOCTL_FILTER_GET 0x0b + +//adm6996i #define KEY_IOCTL_MAX_KEY 0x05 +#define KEY_IOCTL_MAX_KEY 0x0c +//for adm6996i-end +/* IOCTL MAGIC */ +#define ADM_MAGIC ('a'|'d'|'m'|'t'|'e'|'k') + +/* IOCTL parameters */ +#define ADM_IOCTL_REGRW _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_REGRW, REGRW) +#define ADM_SW_IOCTL_REGRW _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_REGRW, REGRW) +#define ADM_SW_IOCTL_PORTSTS _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_PORTSTS, NULL) +#define ADM_SW_IOCTL_INIT _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_INIT, NULL) + + +//6996i-stat +#define ADM_SW_IOCTL_MACENTRY_ADD _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_ADD,MACENTRY) +#define ADM_SW_IOCTL_MACENTRY_DEL _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_DEL,MACENTRY) +#define ADM_SW_IOCTL_MACENTRY_GET_INIT _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_INIT,MACENTRY) +#define ADM_SW_IOCTL_MACENTRY_GET_MORE _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_MACENTRY_GET_MORE,MACENTRY) +#define ADM_SW_IOCTL_FILTER_ADD _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_FILTER_ADD,PROTOCOLFILTER) +#define ADM_SW_IOCTL_FILTER_DEL _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_FILTER_DEL,PROTOCOLFILTER) +#define ADM_SW_IOCTL_FILTER_GET _IOWR(ADM_MAGIC, KEY_IOCTL_ADM_SW_IOCTL_FILTER_GET,PROTOCOLFILTER) + +//6996i-end + + +#define REG_READ 0x0 +#define REG_WRITE 0x1 + +/* undefine symbol */ +#define AMAZON_SW_REG(reg) *((volatile U32*)(reg)) +//#define GPIO0_INPUT_MASK 0 +//#define GPIO_conf0_REG 0x12345678 +//#define GPIO_SET_HI +//#define GPIO_SET_LOW + +#endif +/* _ADM_6996_MODULE_H_ */ diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon.h new file mode 100644 index 0000000000..d28bb418f1 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon.h @@ -0,0 +1,1440 @@ +#ifndef AMAZON_H +#define AMAZON_H +/****************************************************************************** + Copyright (c) 2002, Infineon Technologies. All rights reserved. + + No Warranty + Because the program is licensed free of charge, there is no warranty for + the program, to the extent permitted by applicable law. Except when + otherwise stated in writing the copyright holders and/or other parties + provide the program "as is" without warranty of any kind, either + expressed or implied, including, but not limited to, the implied + warranties of merchantability and fitness for a particular purpose. The + entire risk as to the quality and performance of the program is with + you. should the program prove defective, you assume the cost of all + necessary servicing, repair or correction. + + In no event unless required by applicable law or agreed to in writing + will any copyright holder, or any other party who may modify and/or + redistribute the program as permitted above, be liable to you for + damages, including any general, special, incidental or consequential + damages arising out of the use or inability to use the program + (including but not limited to loss of data or data being rendered + inaccurate or losses sustained by you or third parties or a failure of + the program to operate with any other programs), even if such holder or + other party has been advised of the possibility of such damages. +******************************************************************************/ + +#define amazon_readl(a) readl(((u32*)(a))) +#define amazon_writel(a,b) writel(a, ((u32*)(b))) +#define amazon_writel_masked(a,b,c) writel((readl(((u32*)(a))) & ~b) | (c & b), ((u32*)(a))) + +/* check ADSL link status */ +#define AMAZON_CHECK_LINK + +/***********************************************************************/ +/* Module : WDT register address and bits */ +/***********************************************************************/ + +#define AMAZON_WDT (KSEG1+0x10100900) +/***********************************************************************/ + +/***Reset Request Register***/ +#define AMAZON_RST_REQ ((volatile u32*)(AMAZON_WDT+ 0x0010)) +#define AMAZON_RST_REQ_PLL (1 << 31) +#define AMAZON_RST_REQ_PCI_CORE (1 << 13) +#define AMAZON_RST_REQ_TPE (1 << 12) +#define AMAZON_RST_REQ_AFE (1 << 11) +#define AMAZON_RST_REQ_DMA (1 << 9) +#define AMAZON_RST_REQ_SWITCH (1 << 8) +#define AMAZON_RST_REQ_DFE (1 << 7) +#define AMAZON_RST_REQ_PHY (1 << 5) +#define AMAZON_RST_REQ_PCI (1 << 4) +#define AMAZON_RST_REQ_FPI (1 << 2) +#define AMAZON_RST_REQ_CPU (1 << 1) +#define AMAZON_RST_REQ_HRST (1 << 0) +#define AMAZON_RST_ALL (AMAZON_RST_REQ_PLL \ + |AMAZON_RST_REQ_PCI_CORE \ + |AMAZON_RST_REQ_TPE \ + |AMAZON_RST_REQ_AFE \ + |AMAZON_RST_REQ_DMA \ + |AMAZON_RST_REQ_SWITCH \ + |AMAZON_RST_REQ_DFE \ + |AMAZON_RST_REQ_PHY \ + |AMAZON_RST_REQ_PCI \ + |AMAZON_RST_REQ_FPI \ + |AMAZON_RST_REQ_CPU \ + |AMAZON_RST_REQ_HRST) + +/***Reset Status Register Power On***/ +#define AMAZON_RST_SR ((volatile u32*)(AMAZON_WDT+ 0x0014)) + +/***Watchdog Timer Control Register 0***/ +#define AMAZON_WDT_CON0 ((volatile u32*)(AMAZON_WDT+ 0x0020)) + +/***Watchdog Timer Control Register 1***/ +#define AMAZON_WDT_CON1 ((volatile u32*)(AMAZON_WDT+ 0x0024)) +#define AMAZON_WDT_CON1_WDTDR (1 << 3) +#define AMAZON_WDT_CON1_WDTIR (1 << 2) + +/***Watchdog Timer Status Register***/ +#define AMAZON_WDT_SR ((volatile u32*)(AMAZON_WDT+ 0x0028)) +#define AMAZON_WDT_SR_WDTTIM(value) (((( 1 << 16) - 1) & (value)) << 16) +#define AMAZON_WDT_SR_WDTPR (1 << 5) +#define AMAZON_WDT_SR_WDTTO (1 << 4) +#define AMAZON_WDT_SR_WDTDS (1 << 3) +#define AMAZON_WDT_SR_WDTIS (1 << 2) +#define AMAZON_WDT_SR_WDTOE (1 << 1) +#define AMAZON_WDT_SR_WDTAE (1 << 0) + +/***NMI Status Register***/ +#define AMAZON_WDT_NMISR ((volatile u32*)(AMAZON_WDT+ 0x002C)) +#define AMAZON_WDT_NMISR_NMIWDT (1 << 2) +#define AMAZON_WDT_NMISR_NMIPLL (1 << 1) +#define AMAZON_WDT_NMISR_NMIEXT (1 << 0) + +#define AMAZON_WDT_RST_MON ((volatile u32*)(AMAZON_WDT+ 0x0030)) + +/***********************************************************************/ +/* Module : MCD register address and bits */ +/***********************************************************************/ +#define AMAZON_MCD (KSEG1+0x1F106000) + +/***Manufacturer Identification Register***/ +#define AMAZON_MCD_MANID ((volatile u32*)(AMAZON_MCD+ 0x0024)) +#define AMAZON_MCD_MANID_MANUF(value) (((( 1 << 11) - 1) & (value)) << 5) + +/***Chip Identification Register***/ +#define AMAZON_MCD_CHIPID ((volatile u32*)(AMAZON_MCD+ 0x0028)) +#define AMAZON_MCD_CHIPID_VERSION_GET(value) (((value) >> 28) & ((1 << 4) - 1)) +#define AMAZON_MCD_CHIPID_VERSION_SET(value) (((( 1 << 4) - 1) & (value)) << 28) +#define AMAZON_MCD_CHIPID_PART_NUMBER_GET(value) (((value) >> 12) & ((1 << 16) - 1)) +#define AMAZON_MCD_CHIPID_PART_NUMBER_SET(value) (((( 1 << 16) - 1) & (value)) << 12) +#define AMAZON_MCD_CHIPID_MANID_GET(value) (((value) >> 1) & ((1 << 11) - 1)) +#define AMAZON_MCD_CHIPID_MANID_SET(value) (((( 1 << 11) - 1) & (value)) << 1) + +#define AMAZON_CHIPID_STANDARD 0x00EB +#define AMAZON_CHIPID_YANGTSE 0x00ED + +/***Redesign Tracing Identification Register***/ +#define AMAZON_MCD_RTID ((volatile u32*)(AMAZON_MCD+ 0x002C)) +#define AMAZON_MCD_RTID_LC (1 << 15) +#define AMAZON_MCD_RTID_RIX(value) (((( 1 << 3) - 1) & (value)) << 0) + + +/***********************************************************************/ +/* Module : CGU register address and bits */ +/***********************************************************************/ + +#define AMAZON_CGU (KSEG1+0x1F103000) +/***********************************************************************/ + +/***CGU Clock Divider Select Register***/ +#define AMAZON_CGU_DIV (AMAZON_CGU + 0x0000) +/***CGU PLL0 Status Register***/ +#define AMAZON_CGU_PLL0SR (AMAZON_CGU + 0x0004) +/***CGU PLL1 Status Register***/ +#define AMAZON_CGU_PLL1SR (AMAZON_CGU + 0x0008) +/***CGU Interface Clock Control Register***/ +#define AMAZON_CGU_IFCCR (AMAZON_CGU + 0x000c) +/***CGU Oscillator Control Register***/ +#define AMAZON_CGU_OSCCR (AMAZON_CGU + 0x0010) +/***CGU Memory Clock Delay Register***/ +#define AMAZON_CGU_MCDEL (AMAZON_CGU + 0x0014) +/***CGU CPU Clock Reduction Register***/ +#define AMAZON_CGU_CPUCRD (AMAZON_CGU + 0x0018) +/***CGU Test Register**/ +#define AMAZON_CGU_TST (AMAZON_CGU + 0x003c) + +/***********************************************************************/ +/* Module : PMU register address and bits */ +/***********************************************************************/ + +#define AMAZON_PMU AMAZON_CGU +/***********************************************************************/ + + +/***PMU Power Down Control Register***/ +#define AMAZON_PMU_PWDCR ((volatile u32*)(AMAZON_PMU+ 0x001c)) +#define AMAZON_PMU_PWDCR_TPE (1 << 13) +#define AMAZON_PMU_PWDCR_PLL (1 << 12) +#define AMAZON_PMU_PWDCR_XTAL (1 << 11) +#define AMAZON_PMU_PWDCR_EBU (1 << 10) +#define AMAZON_PMU_PWDCR_DFE (1 << 9) +#define AMAZON_PMU_PWDCR_SPI (1 << 8) +#define AMAZON_PMU_PWDCR_UART (1 << 7) +#define AMAZON_PMU_PWDCR_GPT (1 << 6) +#define AMAZON_PMU_PWDCR_DMA (1 << 5) +#define AMAZON_PMU_PWDCR_PCI (1 << 4) +#define AMAZON_PMU_PWDCR_SW (1 << 3) +#define AMAZON_PMU_PWDCR_IOR (1 << 2) +#define AMAZON_PMU_PWDCR_FPI (1 << 1) +#define AMAZON_PMU_PWDCR_EPHY (1 << 0) + +/***PMU Status Register***/ +#define AMAZON_PMU_SR ((volatile u32*)(AMAZON_PMU+ 0x0020)) +#define AMAZON_PMU_SR_TPE (1 << 13) +#define AMAZON_PMU_SR_PLL (1 << 12) +#define AMAZON_PMU_SR_XTAL (1 << 11) +#define AMAZON_PMU_SR_EBU (1 << 10) +#define AMAZON_PMU_SR_DFE (1 << 9) +#define AMAZON_PMU_SR_SPI (1 << 8) +#define AMAZON_PMU_SR_UART (1 << 7) +#define AMAZON_PMU_SR_GPT (1 << 6) +#define AMAZON_PMU_SR_DMA (1 << 5) +#define AMAZON_PMU_SR_PCI (1 << 4) +#define AMAZON_PMU_SR_SW (1 << 3) +#define AMAZON_PMU_SR_IOR (1 << 2) +#define AMAZON_PMU_SR_FPI (1 << 1) +#define AMAZON_PMU_SR_EPHY (1 << 0) + +/***********************************************************************/ +/* Module : BCU register address and bits */ +/***********************************************************************/ + +#define AMAZON_BCU (KSEG1+0x10100000) +/***********************************************************************/ + + +/***BCU Control Register (0010H)***/ +#define AMAZON_BCU_CON ((volatile u32*)(AMAZON_BCU+ 0x0010)) +#define AMAZON_BCU_CON_SPC(value) (((( 1 << 8) - 1) & (value)) << 24) +#define AMAZON_BCU_CON_SPE (1 << 19) +#define AMAZON_BCU_CON_PSE (1 << 18) +#define AMAZON_BCU_CON_DBG (1 << 16) +#define AMAZON_BCU_CON_TOUT(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***BCU Error Control Capture Register (0020H)***/ +#define AMAZON_BCU_ECON ((volatile u32*)(AMAZON_BCU+ 0x0020)) +#define AMAZON_BCU_ECON_TAG(value) (((( 1 << 4) - 1) & (value)) << 24) +#define AMAZON_BCU_ECON_RDN (1 << 23) +#define AMAZON_BCU_ECON_WRN (1 << 22) +#define AMAZON_BCU_ECON_SVM (1 << 21) +#define AMAZON_BCU_ECON_ACK(value) (((( 1 << 2) - 1) & (value)) << 19) +#define AMAZON_BCU_ECON_ABT (1 << 18) +#define AMAZON_BCU_ECON_RDY (1 << 17) +#define AMAZON_BCU_ECON_TOUT (1 << 16) +#define AMAZON_BCU_ECON_ERRCNT(value) (((( 1 << 16) - 1) & (value)) << 0) +#define AMAZON_BCU_ECON_OPC(value) (((( 1 << 4) - 1) & (value)) << 28) + +/***BCU Error Address Capture Register (0024 H)***/ +#define AMAZON_BCU_EADD ((volatile u32*)(AMAZON_BCU+ 0x0024)) +#define AMAZON_BCU_EADD_FPIADR + +/***BCU Error Data Capture Register (0028H)***/ +#define AMAZON_BCU_EDAT ((volatile u32*)(AMAZON_BCU+ 0x0028)) +#define AMAZON_BCU_EDAT_FPIDAT + +/***********************************************************************/ +/* Module : Switch register address and bits */ +/***********************************************************************/ + +#define AMAZON_SWITCH (KSEG1+0x10106000) +/***********************************************************************/ +#define AMAZON_SW_UN_DEST AMAZON_SWITCH+0x00 /*Unknown destination register*/ +#define AMAZON_SW_VLAN_CTRL AMAZON_SWITCH+0x04 /*VLAN control register*/ +#define AMAZON_SW_PS_CTL AMAZON_SWITCH+0x08 /*port status control register*/ +#define AMAZON_SW_COS_CTL AMAZON_SWITCH+0x0c /*Cos control register*/ +#define AMAZON_SW_VLAN_COS AMAZON_SWITCH+0x10 /*VLAN priority cos mapping register*/ +#define AMAZON_SW_DSCP_COS3 AMAZON_SWITCH+0x14 /*DSCP cos mapping register3*/ +#define AMAZON_SW_DSCP_COS2 AMAZON_SWITCH+0x18 /*DSCP cos mapping register2*/ +#define AMAZON_SW_DSCP_COS1 AMAZON_SWITCH+0x1c /*DSCP cos mapping register1*/ +#define AMAZON_SW_DSCP_COS0 AMAZON_SWITCH+0x20 /*DSCP cos mapping register*/ +#define AMAZON_SW_ARL_CTL AMAZON_SWITCH+0x24 /*ARL control register*/ +#define AMAZON_SW_PKT_LEN AMAZON_SWITCH+0x28 /*packet length register*/ +#define AMAZON_SW_CPU_ACTL AMAZON_SWITCH+0x2c /*CPU control register1*/ +#define AMAZON_SW_DATA1 AMAZON_SWITCH+0x30 /*CPU access control register1*/ +#define AMAZON_SW_DATA2 AMAZON_SWITCH+0x34 /*CPU access control register2*/ +#define AMAZON_SW_P2_PCTL AMAZON_SWITCH+0x38 /*Port2 control register*/ +#define AMAZON_SW_P0_TX_CTL AMAZON_SWITCH+0x3c /*port0 TX control register*/ +#define AMAZON_SW_P1_TX_CTL AMAZON_SWITCH+0x40 /*port 1 TX control register*/ +#define AMAZON_SW_P0_WM AMAZON_SWITCH+0x44 /*port 0 watermark control register*/ +#define AMAZON_SW_P1_WM AMAZON_SWITCH+0x48 /*port 1 watermark control register*/ +#define AMAZON_SW_P2_WM AMAZON_SWITCH+0x4c /*port 2 watermark control register*/ +#define AMAZON_SW_GBL_WM AMAZON_SWITCH+0x50 /*Global watermark register*/ +#define AMAZON_SW_PM_CTL AMAZON_SWITCH+0x54 /*PM control register*/ +#define AMAZON_SW_P2_CTL AMAZON_SWITCH+0x58 /*PMAC control register*/ +#define AMAZON_SW_P2_TX_IPG AMAZON_SWITCH+0x5c /*port2 TX IPG control register*/ +#define AMAZON_SW_P2_RX_IPG AMAZON_SWITCH+0x60 /*prot2 RX IPG control register*/ +#define AMAZON_SW_MDIO_ACC AMAZON_SWITCH+0x64 /*MDIO access register*/ +#define AMAZON_SW_EPHY AMAZON_SWITCH+0x68 /*Ethernet PHY register*/ +#define AMAZON_SW_MDIO_CFG AMAZON_SWITCH+0x6c /*MDIO configuration register*/ +#define AMAZON_SW_P0_RCV_DROP_CNT AMAZON_SWITCH+0x70 /*port0 receive drop counter */ +#define AMAZON_SW_P0_RCV_FRAME_ERR_CNT AMAZON_SWITCH+0x74 /*port0 receive frame error conter*/ +#define AMAZON_SW_P0_TX_COLL_CNT AMAZON_SWITCH+0x78 /*port0 transmit collision counter*/ +#define AMAZON_SW_P0_TX_DROP_CNT AMAZON_SWITCH+0x7c /*port1 transmit drop counter*/ +#define AMAZON_SW_P1_RCV_DROP_CNT AMAZON_SWITCH+0x80 /*port1 receive drop counter*/ +#define AMAZON_SW_P1_RCV_FRAME_ERR_CNT AMAZON_SWITCH+0x84 /*port1 receive error counter*/ +#define AMAZON_SW_P1_TX_COLL_CNT AMAZON_SWITCH+0x88 /*port1 transmit collision counter*/ +#define AMAZON_SW_P1_TX_DROP_CNT AMAZON_SWITCH+0x8c /*port1 transmit drop counter*/ + + + +/***********************************************************************/ +/* Module : SSC register address and bits */ +/***********************************************************************/ +#define AMAZON_SSC_BASE_ADD_0 (KSEG1+0x10100800) + +/*165001:henryhsu:20050603:Source add by Bing Tao*/ + +/*configuration/Status Registers in Bus Clock Domain*/ +#define AMAZON_SSC_CLC ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0000)) +#define AMAZON_SSC_ID ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0008)) +#define AMAZON_SSC_CON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0010)) +#define AMAZON_SSC_STATE ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0014)) +#define AMAZON_SSC_WHBSTATE ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0018)) +#define AMAZON_SSC_TB ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0020)) +#define AMAZON_SSC_RB ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0024)) +#define AMAZON_SSC_FSTAT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0038)) + +/*Configuration/Status Registers in Kernel Clock Domain*/ +#define AMAZON_SSC_PISEL ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0004)) +#define AMAZON_SSC_RXFCON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0030)) +#define AMAZON_SSC_TXFCON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0034)) +#define AMAZON_SSC_BR ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0040)) +#define AMAZON_SSC_BRSTAT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0044)) +#define AMAZON_SSC_SFCON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0060)) +#define AMAZON_SSC_SFSTAT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0064)) +#define AMAZON_SSC_GPOCON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0070)) +#define AMAZON_SSC_GPOSTAT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0074)) +#define AMAZON_SSC_WHBGPOSTAT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0078)) +#define AMAZON_SSC_RXREQ ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0080)) +#define AMAZON_SSC_RXCNT ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x0084)) + +/*DMA Registers in Bus Clock Domain*/ +#define AMAZON_SSC_DMA_CON ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00ec)) + +/*interrupt Node Registers in Bus Clock Domain*/ +#define AMAZON_SSC_IRNEN ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00F4)) +#define AMAZON_SSC_IRNICR ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00FC)) +#define AMAZON_SSC_IRNCR ((volatile u32*)(AMAZON_SSC_BASE_ADD_0+0x00F8)) + +/*165001*/ + +/***********************************************************************/ + + + +/***********************************************************************/ +/* Module : EBU register address and bits */ +/***********************************************************************/ + +#define AMAZON_EBU (KSEG1+0x10105300) +/***********************************************************************/ + + +/***EBU Clock Control Register***/ +#define AMAZON_EBU_CLC ((volatile u32*)(AMAZON_EBU+ 0x0000)) +#define AMAZON_EBU_CLC_DISS (1 << 1) +#define AMAZON_EBU_CLC_DISR (1 << 0) + +/***EBU Global Control Register***/ +#define AMAZON_EBU_CON ((volatile u32*)(AMAZON_EBU+ 0x0010)) +#define AMAZON_EBU_CON_DTACS(value) (((( 1 << 3) - 1) & (value)) << 20) +#define AMAZON_EBU_CON_DTARW(value) (((( 1 << 3) - 1) & (value)) << 16) +#define AMAZON_EBU_CON_TOUTC(value) (((( 1 << 8) - 1) & (value)) << 8) +#define AMAZON_EBU_CON_ARBMODE(value) (((( 1 << 2) - 1) & (value)) << 6) +#define AMAZON_EBU_CON_ARBSYNC (1 << 5) +#define AMAZON_EBU_CON_1 (1 << 3) + +/***EBU Address Select Register 0***/ +#define AMAZON_EBU_ADDSEL0 ((volatile u32*)(AMAZON_EBU+ 0x0020)) +#define AMAZON_EBU_ADDSEL0_BASE(value) (((( 1 << 20) - 1) & (value)) << 12) +#define AMAZON_EBU_ADDSEL0_MASK(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_EBU_ADDSEL0_MIRRORE (1 << 1) +#define AMAZON_EBU_ADDSEL0_REGEN (1 << 0) + +/***EBU Address Select Register 1***/ +#define AMAZON_EBU_ADDSEL1 ((volatile u32*)(AMAZON_EBU+ 0x0024)) +#define AMAZON_EBU_ADDSEL1_BASE(value) (((( 1 << 20) - 1) & (value)) << 12) +#define AMAZON_EBU_ADDSEL1_MASK(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_EBU_ADDSEL1_MIRRORE (1 << 1) +#define AMAZON_EBU_ADDSEL1_REGEN (1 << 0) + +/***EBU Address Select Register 2***/ +#define AMAZON_EBU_ADDSEL2 ((volatile u32*)(AMAZON_EBU+ 0x0028)) +#define AMAZON_EBU_ADDSEL2_BASE(value) (((( 1 << 20) - 1) & (value)) << 12) +#define AMAZON_EBU_ADDSEL2_MASK(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_EBU_ADDSEL2_MIRRORE (1 << 1) +#define AMAZON_EBU_ADDSEL2_REGEN (1 << 0) + +/***EBU Bus Configuration Register 0***/ +#define AMAZON_EBU_BUSCON0 ((volatile u32*)(AMAZON_EBU+ 0x0060)) +#define AMAZON_EBU_BUSCON0_WRDIS (1 << 31) +#define AMAZON_EBU_BUSCON0_ALEC(value) (((( 1 << 2) - 1) & (value)) << 29) +#define AMAZON_EBU_BUSCON0_BCGEN(value) (((( 1 << 2) - 1) & (value)) << 27) +#define AMAZON_EBU_BUSCON0_AGEN(value) (((( 1 << 2) - 1) & (value)) << 24) +#define AMAZON_EBU_BUSCON0_CMULTR(value) (((( 1 << 2) - 1) & (value)) << 22) +#define AMAZON_EBU_BUSCON0_WAIT(value) (((( 1 << 2) - 1) & (value)) << 20) +#define AMAZON_EBU_BUSCON0_WAITINV (1 << 19) +#define AMAZON_EBU_BUSCON0_SETUP (1 << 18) +#define AMAZON_EBU_BUSCON0_PORTW(value) (((( 1 << 2) - 1) & (value)) << 16) +#define AMAZON_EBU_BUSCON0_WAITRDC(value) (((( 1 << 7) - 1) & (value)) << 9) +#define AMAZON_EBU_BUSCON0_WAITWRC(value) (((( 1 << 3) - 1) & (value)) << 6) +#define AMAZON_EBU_BUSCON0_HOLDC(value) (((( 1 << 2) - 1) & (value)) << 4) +#define AMAZON_EBU_BUSCON0_RECOVC(value) (((( 1 << 2) - 1) & (value)) << 2) +#define AMAZON_EBU_BUSCON0_CMULT(value) (((( 1 << 2) - 1) & (value)) << 0) + +/***EBU Bus Configuration Register 1***/ +#define AMAZON_EBU_BUSCON1 ((volatile u32*)(AMAZON_EBU+ 0x0064)) +#define AMAZON_EBU_BUSCON1_WRDIS (1 << 31) +#define AMAZON_EBU_BUSCON1_ALEC(value) (((( 1 << 2) - 1) & (value)) << 29) +#define AMAZON_EBU_BUSCON1_BCGEN(value) (((( 1 << 2) - 1) & (value)) << 27) +#define AMAZON_EBU_BUSCON1_AGEN(value) (((( 1 << 2) - 1) & (value)) << 24) +#define AMAZON_EBU_BUSCON1_CMULTR(value) (((( 1 << 2) - 1) & (value)) << 22) +#define AMAZON_EBU_BUSCON1_WAIT(value) (((( 1 << 2) - 1) & (value)) << 20) +#define AMAZON_EBU_BUSCON1_WAITINV (1 << 19) +#define AMAZON_EBU_BUSCON1_SETUP (1 << 18) +#define AMAZON_EBU_BUSCON1_PORTW(value) (((( 1 << 2) - 1) & (value)) << 16) +#define AMAZON_EBU_BUSCON1_WAITRDC(value) (((( 1 << 7) - 1) & (value)) << 9) +#define AMAZON_EBU_BUSCON1_WAITWRC(value) (((( 1 << 3) - 1) & (value)) << 6) +#define AMAZON_EBU_BUSCON1_HOLDC(value) (((( 1 << 2) - 1) & (value)) << 4) +#define AMAZON_EBU_BUSCON1_RECOVC(value) (((( 1 << 2) - 1) & (value)) << 2) +#define AMAZON_EBU_BUSCON1_CMULT(value) (((( 1 << 2) - 1) & (value)) << 0) + +/***EBU Bus Configuration Register 2***/ +#define AMAZON_EBU_BUSCON2 ((volatile u32*)(AMAZON_EBU+ 0x0068)) +#define AMAZON_EBU_BUSCON2_WRDIS (1 << 31) +#define AMAZON_EBU_BUSCON2_ALEC(value) (((( 1 << 2) - 1) & (value)) << 29) +#define AMAZON_EBU_BUSCON2_BCGEN(value) (((( 1 << 2) - 1) & (value)) << 27) +#define AMAZON_EBU_BUSCON2_AGEN(value) (((( 1 << 2) - 1) & (value)) << 24) +#define AMAZON_EBU_BUSCON2_CMULTR(value) (((( 1 << 2) - 1) & (value)) << 22) +#define AMAZON_EBU_BUSCON2_WAIT(value) (((( 1 << 2) - 1) & (value)) << 20) +#define AMAZON_EBU_BUSCON2_WAITINV (1 << 19) +#define AMAZON_EBU_BUSCON2_SETUP (1 << 18) +#define AMAZON_EBU_BUSCON2_PORTW(value) (((( 1 << 2) - 1) & (value)) << 16) +#define AMAZON_EBU_BUSCON2_WAITRDC(value) (((( 1 << 7) - 1) & (value)) << 9) +#define AMAZON_EBU_BUSCON2_WAITWRC(value) (((( 1 << 3) - 1) & (value)) << 6) +#define AMAZON_EBU_BUSCON2_HOLDC(value) (((( 1 << 2) - 1) & (value)) << 4) +#define AMAZON_EBU_BUSCON2_RECOVC(value) (((( 1 << 2) - 1) & (value)) << 2) +#define AMAZON_EBU_BUSCON2_CMULT(value) (((( 1 << 2) - 1) & (value)) << 0) + +/***********************************************************************/ +/* Module : SDRAM register address and bits */ +/***********************************************************************/ + +#define AMAZON_SDRAM (KSEG1+0x1F800000) +/***********************************************************************/ + + +/***MC Access Error Cause Register***/ +#define AMAZON_SDRAM_MC_ERRCAUSE ((volatile u32*)(AMAZON_SDRAM+ 0x0010)) +#define AMAZON_SDRAM_MC_ERRCAUSE_ERR (1 << 31) +#define AMAZON_SDRAM_MC_ERRCAUSE_PORT(value) (((( 1 << 4) - 1) & (value)) << 16) +#define AMAZON_SDRAM_MC_ERRCAUSE_CAUSE(value) (((( 1 << 2) - 1) & (value)) << 0) +#define AMAZON_SDRAM_MC_ERRCAUSE_Res(value) (((( 1 << NaN) - 1) & (value)) << NaN) + +/***MC Access Error Address Register***/ +#define AMAZON_SDRAM_MC_ERRADDR ((volatile u32*)(AMAZON_SDRAM+ 0x0020)) +#define AMAZON_SDRAM_MC_ERRADDR_ADDR + +/***MC I/O General Purpose Register***/ +#define AMAZON_SDRAM_MC_IOGP ((volatile u32*)(AMAZON_SDRAM+ 0x0100)) +#define AMAZON_SDRAM_MC_IOGP_GPR6(value) (((( 1 << 4) - 1) & (value)) << 28) +#define AMAZON_SDRAM_MC_IOGP_GPR5(value) (((( 1 << 4) - 1) & (value)) << 24) +#define AMAZON_SDRAM_MC_IOGP_GPR4(value) (((( 1 << 4) - 1) & (value)) << 20) +#define AMAZON_SDRAM_MC_IOGP_GPR3(value) (((( 1 << 4) - 1) & (value)) << 16) +#define AMAZON_SDRAM_MC_IOGP_GPR2(value) (((( 1 << 4) - 1) & (value)) << 12) +#define AMAZON_SDRAM_MC_IOGP_CPS (1 << 11) +#define AMAZON_SDRAM_MC_IOGP_CLKDELAY(value) (((( 1 << 3) - 1) & (value)) << 8) +#define AMAZON_SDRAM_MC_IOGP_CLKRAT(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_SDRAM_MC_IOGP_RDDEL(value) (((( 1 << 4) - 1) & (value)) << 0) + +/***MC Self Refresh Register***/ +#define AMAZON_SDRAM_MC_SELFRFSH ((volatile u32*)(AMAZON_SDRAM+ 0x01A0)) +#define AMAZON_SDRAM_MC_SELFRFSH_PWDS (1 << 1) +#define AMAZON_SDRAM_MC_SELFRFSH_PWD (1 << 0) +#define AMAZON_SDRAM_MC_SELFRFSH_Res(value) (((( 1 << 30) - 1) & (value)) << 2) + +/***MC Enable Register***/ +#define AMAZON_SDRAM_MC_CTRLENA ((volatile u32*)(AMAZON_SDRAM+ 0x0110)) +#define AMAZON_SDRAM_MC_CTRLENA_ENA (1 << 0) +#define AMAZON_SDRAM_MC_CTRLENA_Res(value) (((( 1 << 31) - 1) & (value)) << 1) + +/***MC Mode Register Setup Code***/ +#define AMAZON_SDRAM_MC_MRSCODE ((volatile u32*)(AMAZON_SDRAM+ 0x0120)) +#define AMAZON_SDRAM_MC_MRSCODE_UMC(value) (((( 1 << 5) - 1) & (value)) << 7) +#define AMAZON_SDRAM_MC_MRSCODE_CL(value) (((( 1 << 3) - 1) & (value)) << 4) +#define AMAZON_SDRAM_MC_MRSCODE_WT (1 << 3) +#define AMAZON_SDRAM_MC_MRSCODE_BL(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***MC Configuration Data-word Width Register***/ +#define AMAZON_SDRAM_MC_CFGDW ((volatile u32*)(AMAZON_SDRAM+ 0x0130)) +#define AMAZON_SDRAM_MC_CFGDW_DW(value) (((( 1 << 4) - 1) & (value)) << 0) +#define AMAZON_SDRAM_MC_CFGDW_Res(value) (((( 1 << 28) - 1) & (value)) << 4) + +/***MC Configuration Physical Bank 0 Register***/ +#define AMAZON_SDRAM_MC_CFGPB0 ((volatile u32*)(AMAZON_SDRAM+ 0x140)) +#define AMAZON_SDRAM_MC_CFGPB0_MCSEN0(value) (((( 1 << 4) - 1) & (value)) << 12) +#define AMAZON_SDRAM_MC_CFGPB0_BANKN0(value) (((( 1 << 4) - 1) & (value)) << 8) +#define AMAZON_SDRAM_MC_CFGPB0_ROWW0(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_SDRAM_MC_CFGPB0_COLW0(value) (((( 1 << 4) - 1) & (value)) << 0) +#define AMAZON_SDRAM_MC_CFGPB0_Res(value) (((( 1 << 16) - 1) & (value)) << 16) + +/***MC Latency Register***/ +#define AMAZON_SDRAM_MC_LATENCY ((volatile u32*)(AMAZON_SDRAM+ 0x0180)) +#define AMAZON_SDRAM_MC_LATENCY_TRP(value) (((( 1 << 4) - 1) & (value)) << 16) +#define AMAZON_SDRAM_MC_LATENCY_TRAS(value) (((( 1 << 4) - 1) & (value)) << 12) +#define AMAZON_SDRAM_MC_LATENCY_TRCD(value) (((( 1 << 4) - 1) & (value)) << 8) +#define AMAZON_SDRAM_MC_LATENCY_TDPL(value) (((( 1 << 4) - 1) & (value)) << 4) +#define AMAZON_SDRAM_MC_LATENCY_TDAL(value) (((( 1 << 4) - 1) & (value)) << 0) +#define AMAZON_SDRAM_MC_LATENCY_Res(value) (((( 1 << 12) - 1) & (value)) << 20) + +/***MC Refresh Cycle Time Register***/ +#define AMAZON_SDRAM_MC_TREFRESH ((volatile u32*)(AMAZON_SDRAM+ 0x0190)) +#define AMAZON_SDRAM_MC_TREFRESH_TREF(value) (((( 1 << 13) - 1) & (value)) << 0) +#define AMAZON_SDRAM_MC_TREFRESH_Res(value) (((( 1 << 19) - 1) & (value)) << 13) + +/***********************************************************************/ +/* Module : GPTU register address and bits */ +/***********************************************************************/ + +#define AMAZON_GPTU (KSEG1+0x10100A00) +/***********************************************************************/ + + +/***GPT Clock Control Register***/ +#define AMAZON_GPTU_CLC ((volatile u32*)(AMAZON_GPTU+ 0x0000)) +#define AMAZON_GPTU_CLC_RMC(value) (((( 1 << 8) - 1) & (value)) << 8) +#define AMAZON_GPTU_CLC_DISS (1 << 1) +#define AMAZON_GPTU_CLC_DISR (1 << 0) + +/***GPT Timer 3 Control Register***/ +#define AMAZON_GPTU_T3CON ((volatile u32*)(AMAZON_GPTU+ 0x0014)) +#define AMAZON_GPTU_T3CON_T3RDIR (1 << 15) +#define AMAZON_GPTU_T3CON_T3CHDIR (1 << 14) +#define AMAZON_GPTU_T3CON_T3EDGE (1 << 13) +#define AMAZON_GPTU_T3CON_BPS1(value) (((( 1 << 2) - 1) & (value)) << 11) +#define AMAZON_GPTU_T3CON_T3OTL (1 << 10) +#define AMAZON_GPTU_T3CON_T3UD (1 << 7) +#define AMAZON_GPTU_T3CON_T3R (1 << 6) +#define AMAZON_GPTU_T3CON_T3M(value) (((( 1 << 3) - 1) & (value)) << 3) +#define AMAZON_GPTU_T3CON_T3I(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***GPT Write Hardware Modified Timer 3 Control Register +If set and clear bit are written concurrently with 1, the associated bit is not changed.***/ +#define AMAZON_GPTU_WHBT3CON ((volatile u32*)(AMAZON_GPTU+ 0x004C)) +#define AMAZON_GPTU_WHBT3CON_SETT3CHDIR (1 << 15) +#define AMAZON_GPTU_WHBT3CON_CLRT3CHDIR (1 << 14) +#define AMAZON_GPTU_WHBT3CON_SETT3EDGE (1 << 13) +#define AMAZON_GPTU_WHBT3CON_CLRT3EDGE (1 << 12) +#define AMAZON_GPTU_WHBT3CON_SETT3OTL (1 << 11) +#define AMAZON_GPTU_WHBT3CON_CLRT3OTL (1 << 10) + +/***GPT Timer 2 Control Register***/ +#define AMAZON_GPTU_T2CON ((volatile u32*)(AMAZON_GPTU+ 0x0010)) +#define AMAZON_GPTU_T2CON_TxRDIR (1 << 15) +#define AMAZON_GPTU_T2CON_TxCHDIR (1 << 14) +#define AMAZON_GPTU_T2CON_TxEDGE (1 << 13) +#define AMAZON_GPTU_T2CON_TxIRDIS (1 << 12) +#define AMAZON_GPTU_T2CON_TxRC (1 << 9) +#define AMAZON_GPTU_T2CON_TxUD (1 << 7) +#define AMAZON_GPTU_T2CON_TxR (1 << 6) +#define AMAZON_GPTU_T2CON_TxM(value) (((( 1 << 3) - 1) & (value)) << 3) +#define AMAZON_GPTU_T2CON_TxI(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***GPT Timer 4 Control Register***/ +#define AMAZON_GPTU_T4CON ((volatile u32*)(AMAZON_GPTU+ 0x0018)) +#define AMAZON_GPTU_T4CON_TxRDIR (1 << 15) +#define AMAZON_GPTU_T4CON_TxCHDIR (1 << 14) +#define AMAZON_GPTU_T4CON_TxEDGE (1 << 13) +#define AMAZON_GPTU_T4CON_TxIRDIS (1 << 12) +#define AMAZON_GPTU_T4CON_TxRC (1 << 9) +#define AMAZON_GPTU_T4CON_TxUD (1 << 7) +#define AMAZON_GPTU_T4CON_TxR (1 << 6) +#define AMAZON_GPTU_T4CON_TxM(value) (((( 1 << 3) - 1) & (value)) << 3) +#define AMAZON_GPTU_T4CON_TxI(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***GPT Write HW Modified Timer 2 Control Register If set + and clear bit are written concurrently with 1, the associated bit is not changed.***/ +#define AMAZON_GPTU_WHBT2CON ((volatile u32*)(AMAZON_GPTU+ 0x0048)) +#define AMAZON_GPTU_WHBT2CON_SETTxCHDIR (1 << 15) +#define AMAZON_GPTU_WHBT2CON_CLRTxCHDIR (1 << 14) +#define AMAZON_GPTU_WHBT2CON_SETTxEDGE (1 << 13) +#define AMAZON_GPTU_WHBT2CON_CLRTxEDGE (1 << 12) + +/***GPT Write HW Modified Timer 4 Control Register If set + and clear bit are written concurrently with 1, the associated bit is not changed.***/ +#define AMAZON_GPTU_WHBT4CON ((volatile u32*)(AMAZON_GPTU+ 0x0050)) +#define AMAZON_GPTU_WHBT4CON_SETTxCHDIR (1 << 15) +#define AMAZON_GPTU_WHBT4CON_CLRTxCHDIR (1 << 14) +#define AMAZON_GPTU_WHBT4CON_SETTxEDGE (1 << 13) +#define AMAZON_GPTU_WHBT4CON_CLRTxEDGE (1 << 12) + +/***GPT Capture Reload Register***/ +#define AMAZON_GPTU_CAPREL ((volatile u32*)(AMAZON_GPTU+ 0x0030)) +#define AMAZON_GPTU_CAPREL_CAPREL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 2 Register***/ +#define AMAZON_GPTU_T2 ((volatile u32*)(AMAZON_GPTU+ 0x0034)) +#define AMAZON_GPTU_T2_TVAL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 3 Register***/ +#define AMAZON_GPTU_T3 ((volatile u32*)(AMAZON_GPTU+ 0x0038)) +#define AMAZON_GPTU_T3_TVAL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 4 Register***/ +#define AMAZON_GPTU_T4 ((volatile u32*)(AMAZON_GPTU+ 0x003C)) +#define AMAZON_GPTU_T4_TVAL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 5 Register***/ +#define AMAZON_GPTU_T5 ((volatile u32*)(AMAZON_GPTU+ 0x0040)) +#define AMAZON_GPTU_T5_TVAL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 6 Register***/ +#define AMAZON_GPTU_T6 ((volatile u32*)(AMAZON_GPTU+ 0x0044)) +#define AMAZON_GPTU_T6_TVAL(value) (((( 1 << 16) - 1) & (value)) << 0) + +/***GPT Timer 6 Control Register***/ +#define AMAZON_GPTU_T6CON ((volatile u32*)(AMAZON_GPTU+ 0x0020)) +#define AMAZON_GPTU_T6CON_T6SR (1 << 15) +#define AMAZON_GPTU_T6CON_T6CLR (1 << 14) +#define AMAZON_GPTU_T6CON_BPS2(value) (((( 1 << 2) - 1) & (value)) << 11) +#define AMAZON_GPTU_T6CON_T6OTL (1 << 10) +#define AMAZON_GPTU_T6CON_T6UD (1 << 7) +#define AMAZON_GPTU_T6CON_T6R (1 << 6) +#define AMAZON_GPTU_T6CON_T6M(value) (((( 1 << 3) - 1) & (value)) << 3) +#define AMAZON_GPTU_T6CON_T6I(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***GPT Write HW Modified Timer 6 Control Register If set + and clear bit are written concurrently with 1, the associated bit is not changed.***/ +#define AMAZON_GPTU_WHBT6CON ((volatile u32*)(AMAZON_GPTU+ 0x0054)) +#define AMAZON_GPTU_WHBT6CON_SETT6OTL (1 << 11) +#define AMAZON_GPTU_WHBT6CON_CLRT6OTL (1 << 10) + +/***GPT Timer 5 Control Register***/ +#define AMAZON_GPTU_T5CON ((volatile u32*)(AMAZON_GPTU+ 0x001C)) +#define AMAZON_GPTU_T5CON_T5SC (1 << 15) +#define AMAZON_GPTU_T5CON_T5CLR (1 << 14) +#define AMAZON_GPTU_T5CON_CI(value) (((( 1 << 2) - 1) & (value)) << 12) +#define AMAZON_GPTU_T5CON_T5CC (1 << 11) +#define AMAZON_GPTU_T5CON_CT3 (1 << 10) +#define AMAZON_GPTU_T5CON_T5RC (1 << 9) +#define AMAZON_GPTU_T5CON_T5UDE (1 << 8) +#define AMAZON_GPTU_T5CON_T5UD (1 << 7) +#define AMAZON_GPTU_T5CON_T5R (1 << 6) +#define AMAZON_GPTU_T5CON_T5M(value) (((( 1 << 3) - 1) & (value)) << 3) +#define AMAZON_GPTU_T5CON_T5I(value) (((( 1 << 3) - 1) & (value)) << 0) + + +/***********************************************************************/ +/* Module : ASC register address and bits */ +/***********************************************************************/ + +#define AMAZON_ASC (KSEG1+0x10100400) +/***********************************************************************/ + + +/***ASC Port Input Select Register***/ +#define AMAZON_ASC_PISEL (AMAZON_ASC+ 0x0004) +#define AMAZON_ASC_PISEL_RIS (1 << 0) + +/***ASC Control Register***/ +#define AMAZON_ASC_CON (AMAZON_ASC+ 0x0010) +#define AMAZON_ASC_CON_R (1 << 15) +#define AMAZON_ASC_CON_LB (1 << 14) +#define AMAZON_ASC_CON_BRS (1 << 13) +#define AMAZON_ASC_CON_ODD (1 << 12) +#define AMAZON_ASC_CON_FDE (1 << 11) +#define AMAZON_ASC_CON_OE (1 << 10) +#define AMAZON_ASC_CON_FE (1 << 9) +#define AMAZON_ASC_CON_PE (1 << 8) +#define AMAZON_ASC_CON_OEN (1 << 7) +#define AMAZON_ASC_CON_FEN (1 << 6) +#define AMAZON_ASC_CON_PENRXDI (1 << 5) +#define AMAZON_ASC_CON_REN (1 << 4) +#define AMAZON_ASC_CON_STP (1 << 3) +#define AMAZON_ASC_CON_M(value) (((( 1 << 3) - 1) & (value)) << 0) + +/***ASC Write Hardware Modified Control Register***/ +#define AMAZON_ASC_WHBCON (AMAZON_ASC+ 0x0050) +#define AMAZON_ASC_WHBCON_SETOE (1 << 13) +#define AMAZON_ASC_WHBCON_SETFE (1 << 12) +#define AMAZON_ASC_WHBCON_SETPE (1 << 11) +#define AMAZON_ASC_WHBCON_CLROE (1 << 10) +#define AMAZON_ASC_WHBCON_CLRFE (1 << 9) +#define AMAZON_ASC_WHBCON_CLRPE (1 << 8) +#define AMAZON_ASC_WHBCON_SETREN (1 << 5) +#define AMAZON_ASC_WHBCON_CLRREN (1 << 4) + +/***ASC Baudrate Timer/Reload Register***/ +#define AMAZON_ASC_BTR (AMAZON_ASC+ 0x0014) +#define AMAZON_ASC_BTR_BR_VALUE(value) (((( 1 << 13) - 1) & (value)) << 0) + +/***ASC Fractional Divider Register***/ +#define AMAZON_ASC_FDV (AMAZON_ASC+ 0x0018) +#define AMAZON_ASC_FDV_FD_VALUE(value) (((( 1 << 9) - 1) & (value)) << 0) + +/***ASC IrDA Pulse Mode/Width Register***/ +#define AMAZON_ASC_PMW (AMAZON_ASC+ 0x001C) +#define AMAZON_ASC_PMW_IRPW (1 << 8) +#define AMAZON_ASC_PMW_PW_VALUE(value) (((( 1 << 8) - 1) & (value)) << 0) + +/***ASC Transmit Buffer Register***/ +#define AMAZON_ASC_TBUF (AMAZON_ASC+ 0x0020) +#define AMAZON_ASC_TBUF_TD_VALUE(value) (((( 1 << 9) - 1) & (value)) << 0) + +/***ASC Receive Buffer Register***/ +#define AMAZON_ASC_RBUF (AMAZON_ASC+ 0x0024) +#define AMAZON_ASC_RBUF_RD_VALUE(value) (((( 1 << 9) - 1) & (value)) << 0) + +/***ASC Autobaud Control Register***/ +#define AMAZON_ASC_ABCON (AMAZON_ASC+ 0x0030) +#define AMAZON_ASC_ABCON_RXINV (1 << 11) +#define AMAZON_ASC_ABCON_TXINV (1 << 10) +#define AMAZON_ASC_ABCON_ABEM(value) (((( 1 << 2) - 1) & (value)) << 8) +#define AMAZON_ASC_ABCON_FCDETEN (1 << 4) +#define AMAZON_ASC_ABCON_ABDETEN (1 << 3) +#define AMAZON_ASC_ABCON_ABSTEN (1 << 2) +#define AMAZON_ASC_ABCON_AUREN (1 << 1) +#define AMAZON_ASC_ABCON_ABEN (1 << 0) + +/***Receive FIFO Control Register***/ +#define AMAZON_ASC_RXFCON (AMAZON_ASC+ 0x0040) +#define AMAZON_ASC_RXFCON_RXFITL(value) (((( 1 << 6) - 1) & (value)) << 8) +#define AMAZON_ASC_RXFCON_RXTMEN (1 << 2) +#define AMAZON_ASC_RXFCON_RXFFLU (1 << 1) +#define AMAZON_ASC_RXFCON_RXFEN (1 << 0) + +/***Transmit FIFO Control Register***/ +#define AMAZON_ASC_TXFCON (AMAZON_ASC+ 0x0044) +#define AMAZON_ASC_TXFCON_TXFITL(value) (((( 1 << 6) - 1) & (value)) << 8) +#define AMAZON_ASC_TXFCON_TXTMEN (1 << 2) +#define AMAZON_ASC_TXFCON_TXFFLU (1 << 1) +#define AMAZON_ASC_TXFCON_TXFEN (1 << 0) + +/***FIFO Status Register***/ +#define AMAZON_ASC_FSTAT (AMAZON_ASC+ 0x0048) +#define AMAZON_ASC_FSTAT_TXFFL(value) (((( 1 << 6) - 1) & (value)) << 8) +#define AMAZON_ASC_FSTAT_RXFFL(value) (((( 1 << 6) - 1) & (value)) << 0) + +/***ASC Write HW Modified Autobaud Control Register***/ +#define AMAZON_ASC_WHBABCON (AMAZON_ASC+ 0x0054) +#define AMAZON_ASC_WHBABCON_SETABEN (1 << 1) +#define AMAZON_ASC_WHBABCON_CLRABEN (1 << 0) + +/***ASC Autobaud Status Register***/ +#define AMAZON_ASC_ABSTAT (AMAZON_ASC+ 0x0034) +#define AMAZON_ASC_ABSTAT_DETWAIT (1 << 4) +#define AMAZON_ASC_ABSTAT_SCCDET (1 << 3) +#define AMAZON_ASC_ABSTAT_SCSDET (1 << 2) +#define AMAZON_ASC_ABSTAT_FCCDET (1 << 1) +#define AMAZON_ASC_ABSTAT_FCSDET (1 << 0) + +/***ASC Write HW Modified Autobaud Status Register***/ +#define AMAZON_ASC_WHBABSTAT (AMAZON_ASC+ 0x0058) +#define AMAZON_ASC_WHBABSTAT_SETDETWAIT (1 << 9) +#define AMAZON_ASC_WHBABSTAT_CLRDETWAIT (1 << 8) +#define AMAZON_ASC_WHBABSTAT_SETSCCDET (1 << 7) +#define AMAZON_ASC_WHBABSTAT_CLRSCCDET (1 << 6) +#define AMAZON_ASC_WHBABSTAT_SETSCSDET (1 << 5) +#define AMAZON_ASC_WHBABSTAT_CLRSCSDET (1 << 4) +#define AMAZON_ASC_WHBABSTAT_SETFCCDET (1 << 3) +#define AMAZON_ASC_WHBABSTAT_CLRFCCDET (1 << 2) +#define AMAZON_ASC_WHBABSTAT_SETFCSDET (1 << 1) +#define AMAZON_ASC_WHBABSTAT_CLRFCSDET (1 << 0) + +/***ASC Clock Control Register***/ +#define AMAZON_ASC_CLC (AMAZON_ASC+ 0x0000) +#define AMAZON_ASC_CLC_RMC(value) (((( 1 << 8) - 1) & (value)) << 8) +#define AMAZON_ASC_CLC_DISS (1 << 1) +#define AMAZON_ASC_CLC_DISR (1 << 0) + +/***ASC IRNCR0 **/ +#define AMAZON_ASC_IRNCR0 (AMAZON_ASC+ 0x00FC) +/***ASC IRNCR1 **/ +#define AMAZON_ASC_IRNCR1 (AMAZON_ASC+ 0x00F8) +#define ASC_IRNCR_TIR 0x1 +#define ASC_IRNCR_RIR 0x2 +#define ASC_IRNCR_EIR 0x4 +/***********************************************************************/ +/* Module : DMA register address and bits */ +/***********************************************************************/ + +#define AMAZON_DMA (KSEG1+0x10103000) +/***********************************************************************/ +#define AMAZON_DMA_CH_ON AMAZON_DMA+0x28 +#define AMAZON_DMA_CH_RST AMAZON_DMA+0x2c +#define AMAZON_DMA_CH0_ISR AMAZON_DMA+0x30 +#define AMAZON_DMA_CH1_ISR AMAZON_DMA+0x34 +#define AMAZON_DMA_CH2_ISR AMAZON_DMA+0x38 +#define AMAZON_DMA_CH3_ISR AMAZON_DMA+0x3c +#define AMAZON_DMA_CH4_ISR AMAZON_DMA+0x40 +#define AMAZON_DMA_CH5_ISR AMAZON_DMA+0x44 +#define AMAZON_DMA_CH6_ISR AMAZON_DMA+0x48 +#define AMAZON_DMA_CH7_ISR AMAZON_DMA+0x4c +#define AMAZON_DMA_CH8_ISR AMAZON_DMA+0x50 +#define AMAZON_DMA_CH9_ISR AMAZON_DMA+0x54 +#define AMAZON_DMA_CH10_ISR AMAZON_DMA+0x58 +#define AMAZON_DMA_CH11_ISR AMAZON_DMA+0x5c +#define AMAZON_DMA_CH0_MSK AMAZON_DMA+0x60 +#define AMAZON_DMA_CH1_MSK AMAZON_DMA+0x64 +#define AMAZON_DMA_CH2_MSK AMAZON_DMA+0x68 +#define AMAZON_DMA_CH3_MSK AMAZON_DMA+0x6c +#define AMAZON_DMA_CH4_MSK AMAZON_DMA+0x70 +#define AMAZON_DMA_CH5_MSK AMAZON_DMA+0x74 +#define AMAZON_DMA_CH6_MSK AMAZON_DMA+0x78 +#define AMAZON_DMA_CH7_MSK AMAZON_DMA+0x7c +#define AMAZON_DMA_CH8_MSK AMAZON_DMA+0x80 +#define AMAZON_DMA_CH9_MSK AMAZON_DMA+0x84 +#define AMAZON_DMA_CH10_MSK AMAZON_DMA+0x88 +#define AMAZON_DMA_CH11_MSK AMAZON_DMA+0x8c +#define AMAZON_DMA_Desc_BA AMAZON_DMA+0x90 +#define AMAZON_DMA_CH0_DES_LEN AMAZON_DMA+0x94 +#define AMAZON_DMA_CH1_DES_LEN AMAZON_DMA+0x98 +#define AMAZON_DMA_CH2_DES_LEN AMAZON_DMA+0x9c +#define AMAZON_DMA_CH3_DES_LEN AMAZON_DMA+0xa0 +#define AMAZON_DMA_CH4_DES_LEN AMAZON_DMA+0xa4 +#define AMAZON_DMA_CH5_DES_LEN AMAZON_DMA+0xa8 +#define AMAZON_DMA_CH6_DES_LEN AMAZON_DMA+0xac +#define AMAZON_DMA_CH7_DES_LEN AMAZON_DMA+0xb0 +#define AMAZON_DMA_CH8_DES_LEN AMAZON_DMA+0xb4 +#define AMAZON_DMA_CH9_DES_LEN AMAZON_DMA+0xb8 +#define AMAZON_DMA_CH10_DES_LEN AMAZON_DMA+0xbc +#define AMAZON_DMA_CH11_DES_LEN AMAZON_DMA+0xc0 +#define AMAZON_DMA_CH1_DES_OFST AMAZON_DMA+0xc4 +#define AMAZON_DMA_CH2_DES_OFST AMAZON_DMA+0xc8 +#define AMAZON_DMA_CH3_DES_OFST AMAZON_DMA+0xcc +#define AMAZON_DMA_CH4_DES_OFST AMAZON_DMA+0xd0 +#define AMAZON_DMA_CH5_DES_OFST AMAZON_DMA+0xd4 +#define AMAZON_DMA_CH6_DES_OFST AMAZON_DMA+0xd8 +#define AMAZON_DMA_CH7_DES_OFST AMAZON_DMA+0xdc +#define AMAZON_DMA_CH8_DES_OFST AMAZON_DMA+0xe0 +#define AMAZON_DMA_CH9_DES_OFST AMAZON_DMA+0xe4 +#define AMAZON_DMA_CH10_DES_OFST AMAZON_DMA+0xe8 +#define AMAZON_DMA_CH11_DES_OFST AMAZON_DMA+0xec +#define AMAZON_DMA_SW_BL AMAZON_DMA+0xf0 +#define AMAZON_DMA_TPE_BL AMAZON_DMA+0xf4 +#define AMAZON_DMA_DPlus2FPI_BL AMAZON_DMA+0xf8 +#define AMAZON_DMA_GRX_BUF_LEN AMAZON_DMA+0xfc +#define AMAZON_DMA_DMA_ECON_REG AMAZON_DMA+0x100 +#define AMAZON_DMA_POLLING_REG AMAZON_DMA+0x104 +#define AMAZON_DMA_CH_WGT AMAZON_DMA+0x108 +#define AMAZON_DMA_TX_WGT AMAZON_DMA+0x10c +#define AMAZON_DMA_DPLus2FPI_CLASS AMAZON_DMA+0x110 +#define AMAZON_DMA_COMB_ISR AMAZON_DMA+0x114 + +//channel reset +#define SWITCH1_RST_MASK 0x83 /* Switch1 channel mask */ +#define SWITCH2_RST_MASK 0x10C /* Switch1 channel mask */ +#define TPE_RST_MASK 0x630 /* TPE channel mask */ +#define DPlus2FPI_RST_MASK 0x840 /* DPlusFPI channel mask */ + +//ISR +#define DMA_ISR_RDERR 0x20 +#define DMA_ISR_CMDCPT 0x10 +#define DMA_ISR_CPT 0x8 +#define DMA_ISR_DURR 0x4 +#define DMA_ISR_EOP 0x2 +#define DMA_DESC_BYTEOFF_SHIFT 23 + +#define DMA_POLLING_ENABLE 0x80000000 +#define DMA_POLLING_CNT 0x50 /*minimum 0x10, max 0xfff0*/ + +/***********************************************************************/ +/* Module : Debug register address and bits */ +/***********************************************************************/ + +#define AMAZON_DEBUG (KSEG1+0x1F106000) +/***********************************************************************/ + + +/***MCD Break System Control Register***/ +#define AMAZON_DEBUG_MCD_BSCR ((volatile u32*)(AMAZON_DEBUG+ 0x0000)) + +/***PMC Performance Counter Control Register0***/ +#define AMAZON_DEBUG_PMC_PCCR0 ((volatile u32*)(AMAZON_DEBUG+ 0x0010)) + +/***PMC Performance Counter Control Register1***/ +#define AMAZON_DEBUG_PMC_PCCR1 ((volatile u32*)(AMAZON_DEBUG+ 0x0014)) + +/***PMC Performance Counter Register0***/ +#define AMAZON_DEBUG_PMC_PCR0 ((volatile u32*)(AMAZON_DEBUG+ 0x0018)) + +/*165001:henryhsu:20050603:Source modified by Bing Tao*/ + +/***PMC Performance Counter Register1***/ +//#define AMAZON_DEBUG_PMC_PCR1 ((volatile u32*)(AMAZON_DEBUG+ 0x0020)) +#define AMAZON_DEBUG_PMC_PCR1 ((volatile u32*)(AMAZON_DEBUG+ 0x001c)) + +/*165001*/ + + + +/***MCD Suspend Mode Control Register***/ +#define AMAZON_DEBUG_MCD_SMCR ((volatile u32*)(AMAZON_DEBUG+ 0x0024)) + +/***********************************************************************/ +/* Module : GPIO register address and bits */ +/***********************************************************************/ + +#define AMAZON_GPIO (KSEG1+0x10100B00) +/***********************************************************************/ + + +/***Port 0 Data Output Register (0010H)***/ +#define AMAZON_GPIO_P0_OUT ((volatile u32*)(AMAZON_GPIO+ 0x0010)) + +/***Port 1 Data Output Register (0040H)***/ +#define AMAZON_GPIO_P1_OUT ((volatile u32*)(AMAZON_GPIO+ 0x0040)) + +/***Port 0 Data Input Register (0014H)***/ +#define AMAZON_GPIO_P0_IN ((volatile u32*)(AMAZON_GPIO+ 0x0014)) + +/***Port 1 Data Input Register (0044H)***/ +#define AMAZON_GPIO_P1_IN ((volatile u32*)(AMAZON_GPIO+ 0x0044)) + +/***Port 0 Direction Register (0018H)***/ +#define AMAZON_GPIO_P0_DIR ((volatile u32*)(AMAZON_GPIO+ 0x0018)) + +/***Port 1 Direction Register (0048H)***/ +#define AMAZON_GPIO_P1_DIR ((volatile u32*)(AMAZON_GPIO+ 0x0048)) + +/***Port 0 Alternate Function Select Register 0 (001C H) ***/ +#define AMAZON_GPIO_P0_ALTSEL0 ((volatile u32*)(AMAZON_GPIO+ 0x001C)) + +/***Port 1 Alternate Function Select Register 0 (004C H) ***/ +#define AMAZON_GPIO_P1_ALTSEL0 ((volatile u32*)(AMAZON_GPIO+ 0x004C)) + +/***Port 0 Alternate Function Select Register 1 (0020 H) ***/ +#define AMAZON_GPIO_P0_ALTSEL1 ((volatile u32*)(AMAZON_GPIO+ 0x0020)) + +/***Port 1 Alternate Function Select Register 0 (0050 H) ***/ +#define AMAZON_GPIO_P1_ALTSEL1 ((volatile u32*)(AMAZON_GPIO+ 0x0050)) + +/***Port 0 Open Drain Control Register (0024H)***/ +#define AMAZON_GPIO_P0_OD ((volatile u32*)(AMAZON_GPIO+ 0x0024)) + +/***Port 1 Open Drain Control Register (0054H)***/ +#define AMAZON_GPIO_P1_OD ((volatile u32*)(AMAZON_GPIO+ 0x0054)) + +/***Port 0 Input Schmitt-Trigger Off Register (0028 H) ***/ +#define AMAZON_GPIO_P0_STOFF ((volatile u32*)(AMAZON_GPIO+ 0x0028)) + +/***Port 1 Input Schmitt-Trigger Off Register (0058 H) ***/ +#define AMAZON_GPIO_P1_STOFF ((volatile u32*)(AMAZON_GPIO+ 0x0058)) + +/***Port 0 Pull Up/Pull Down Select Register (002C H)***/ +#define AMAZON_GPIO_P0_PUDSEL ((volatile u32*)(AMAZON_GPIO+ 0x002C)) + +/***Port 1 Pull Up/Pull Down Select Register (005C H)***/ +#define AMAZON_GPIO_P1_PUDSEL ((volatile u32*)(AMAZON_GPIO+ 0x005C)) + +/***Port 0 Pull Up Device Enable Register (0030 H)***/ +#define AMAZON_GPIO_P0_PUDEN ((volatile u32*)(AMAZON_GPIO+ 0x0030)) + +/***Port 1 Pull Up Device Enable Register (0060 H)***/ +#define AMAZON_GPIO_P1_PUDEN ((volatile u32*)(AMAZON_GPIO+ 0x0060)) + +/***********************************************************************/ +/* Module : BIU register address and bits */ +/***********************************************************************/ + +#define AMAZON_BIU (KSEG1+0x1FA80000) +/***********************************************************************/ + + +/***BIU Identification Register***/ +#define AMAZON_BIU_ID ((volatile u32*)(AMAZON_BIU+ 0x0000)) +#define AMAZON_BIU_ID_ARCH (1 << 16) +#define AMAZON_BIU_ID_ID(value) (((( 1 << 8) - 1) & (value)) << 8) +#define AMAZON_BIU_ID_REV(value) (((( 1 << 8) - 1) & (value)) << 0) + +/***BIU Access Error Cause Register***/ +#define AMAZON_BIU_ERRCAUSE ((volatile u32*)(AMAZON_BIU+ 0x0100)) +#define AMAZON_BIU_ERRCAUSE_ERR (1 << 31) +#define AMAZON_BIU_ERRCAUSE_PORT(value) (((( 1 << 4) - 1) & (value)) << 16) +#define AMAZON_BIU_ERRCAUSE_CAUSE(value) (((( 1 << 2) - 1) & (value)) << 0) + +/***BIU Access Error Address Register***/ +#define AMAZON_BIU_ERRADDR ((volatile u32*)(AMAZON_BIU+ 0x0108)) +#define AMAZON_BIU_ERRADDR_ADDR + +/***********************************************************************/ +/* Module : ICU register address and bits */ +/***********************************************************************/ + +#define AMAZON_ICU (KSEG1+0x1F101000) +/***********************************************************************/ + +/***IM0 Interrupt Status Register***/ +#define AMAZON_ICU_IM0_ISR (AMAZON_ICU + 0x0010) +#define AMAZON_ICU_IM1_ISR (AMAZON_ICU + 0x0020) +#define AMAZON_ICU_IM2_ISR (AMAZON_ICU + 0x0030) +#define AMAZON_ICU_IM3_ISR (AMAZON_ICU + 0x0040) +#define AMAZON_ICU_IM4_ISR (AMAZON_ICU + 0x0050) + +/***IM0 Interrupt Enable Register***/ +#define AMAZON_ICU_IM0_IER (AMAZON_ICU + 0x0014) +#define AMAZON_ICU_IM1_IER (AMAZON_ICU + 0x0024) +#define AMAZON_ICU_IM2_IER (AMAZON_ICU + 0x0034) +#define AMAZON_ICU_IM3_IER (AMAZON_ICU + 0x0044) +#define AMAZON_ICU_IM4_IER (AMAZON_ICU + 0x0054) + +/***IM0 Interrupt Output Status Register***/ +#define AMAZON_ICU_IM0_IOSR (AMAZON_ICU + 0x0018) +#define AMAZON_ICU_IM1_IOSR (AMAZON_ICU + 0x0028) +#define AMAZON_ICU_IM2_IOSR (AMAZON_ICU + 0x0038) +#define AMAZON_ICU_IM3_IOSR (AMAZON_ICU + 0x0048) +#define AMAZON_ICU_IM4_IOSR (AMAZON_ICU + 0x0058) + +/***IM0 Interrupt Request Set Register***/ +#define AMAZON_ICU_IM0_IRSR (AMAZON_ICU + 0x001c) +#define AMAZON_ICU_IM1_IRSR (AMAZON_ICU + 0x002c) +#define AMAZON_ICU_IM2_IRSR (AMAZON_ICU + 0x003c) +#define AMAZON_ICU_IM3_IRSR (AMAZON_ICU + 0x004c) +#define AMAZON_ICU_IM4_IRSR (AMAZON_ICU + 0x005c) + +/***Interrupt Vector Value Register***/ +#define AMAZON_ICU_IM_VEC (AMAZON_ICU + 0x0060) + +/***Interrupt Vector Value Mask***/ +#define AMAZON_ICU_IM0_VEC_MASK 0x0000001f +#define AMAZON_ICU_IM1_VEC_MASK 0x000003e0 +#define AMAZON_ICU_IM2_VEC_MASK 0x00007c00 +#define AMAZON_ICU_IM3_VEC_MASK 0x000f8000 +#define AMAZON_ICU_IM4_VEC_MASK 0x01f00000 + +/***DMA Interrupt Mask Value***/ +#define AMAZON_DMA_H_MASK 0x00000fff + +/***External Interrupt Control Register***/ +#define AMAZON_ICU_EXTINTCR (AMAZON_ICU + 0x0000) +#define AMAZON_ICU_IRNICR (AMAZON_ICU + 0x0004) +#define AMAZON_ICU_IRNCR (AMAZON_ICU + 0x0008) +#define AMAZON_ICU_IRNEN (AMAZON_ICU + 0x000c) + +/***********************************************************************/ +/* Module : PCI/Card-BUS/PC-Card register address and bits */ +/***********************************************************************/ + +#define AMAZON_PCI (KSEG1+0x10105400) +#define AMAZON_PCI_CFG_BASE (KSEG1+0x11000000) +#define AMAZON_PCI_MEM_BASE (KSEG1+0x12000000) + +#define CLOCK_CONTROL AMAZON_PCI + 0x00000000 +#define ARB_CTRL_bit 1 +#define IDENTIFICATION AMAZON_PCI + 0x00000004 +#define SOFTRESET AMAZON_PCI + 0x00000010 +#define PCI_FPI_ERROR_ADDRESS AMAZON_PCI + 0x00000014 +#define FPI_PCI_ERROR_ADDRESS AMAZON_PCI + 0x00000018 +#define FPI_ERROR_TAG AMAZON_PCI + 0x0000001c +#define IRR AMAZON_PCI + 0x00000020 +#define IRA_IR AMAZON_PCI + 0x00000024 +#define IRM AMAZON_PCI + 0x00000028 +#define DMA_COMPLETE_BIT 0 +#define PCI_POWER_CHANGE_BIT 16 +#define PCI_MASTER0_BROKEN_INT_BIT 24 +#define PCI_MASTER1_BROKEN_INT_BIT 25 +#define PCI_MASTER2_BROKEN_INT_BIT 26 +#define EOI AMAZON_PCI + 0x0000002c +#define PCI_MODE AMAZON_PCI + 0x00000030 +#define PCI_MODE_cfgok_bit 24 +#define DEVICE_VENDOR_ID AMAZON_PCI + 0x00000034 +#define SUBSYSTEM_VENDOR_ID AMAZON_PCI + 0x00000038 +#define POWER_MANAGEMENT AMAZON_PCI + 0x0000003c +#define CLASS_CODE1 AMAZON_PCI + 0x00000040 +#define BAR11_MASK AMAZON_PCI + 0x00000044 +#define BAR12_MASK AMAZON_PCI + 0x00000048 +#define BAR13_MASK AMAZON_PCI + 0x0000004c +#define BAR14_MASK AMAZON_PCI + 0x00000050 +#define BAR15_MASK AMAZON_PCI + 0x00000054 +#define BAR16_MASK AMAZON_PCI + 0x00000058 +#define CARDBUS_CIS_POINTER1 AMAZON_PCI + 0x0000005c +#define SUBSYSTEM_ID1 AMAZON_PCI + 0x00000060 +#define PCI_ADDRESS_MAP_11 AMAZON_PCI + 0x00000064 +#define PCI_ADDRESS_MAP_12 AMAZON_PCI + 0x00000068 +#define PCI_ADDRESS_MAP_13 AMAZON_PCI + 0x0000006c +#define PCI_ADDRESS_MAP_14 AMAZON_PCI + 0x00000070 +#define PCI_ADDRESS_MAP_15 AMAZON_PCI + 0x00000074 +#define PCI_ADDRESS_MAP_16 AMAZON_PCI + 0x00000078 +#define FPI_SEGMENT_ENABLE AMAZON_PCI + 0x0000007c +#define CLASS_CODE2 AMAZON_PCI + 0x00000080 +#define BAR21_MASK AMAZON_PCI + 0x00000084 +#define BAR22_MASK AMAZON_PCI + 0x00000088 +#define BAR23_MASK AMAZON_PCI + 0x0000008c +#define BAR24_MASK AMAZON_PCI + 0x00000090 +#define BAR25_MASK AMAZON_PCI + 0x00000094 +#define BAR26_MASK AMAZON_PCI + 0x00000098 +#define CARDBUS_CIS_POINTER2 AMAZON_PCI + 0x0000009c +#define SUBSYSTEM_ID2 AMAZON_PCI + 0x000000a0 +#define PCI_ADDRESS_MAP_21 AMAZON_PCI + 0x000000a4 +#define PCI_ADDRESS_MAP_22 AMAZON_PCI + 0x000000a8 +#define PCI_ADDRESS_MAP_23 AMAZON_PCI + 0x000000ac +#define PCI_ADDRESS_MAP_24 AMAZON_PCI + 0x000000b0 +#define PCI_ADDRESS_MAP_25 AMAZON_PCI + 0x000000b4 +#define PCI_ADDRESS_MAP_26 AMAZON_PCI + 0x000000b8 +#define FPI_ADDRESS_MASK11LOW AMAZON_PCI + 0x000000bc +#define FPI_ADDRESS_MAP_0 AMAZON_PCI + 0x000000c0 +#define FPI_ADDRESS_MAP_1 AMAZON_PCI + 0x000000c4 +#define FPI_ADDRESS_MAP_2 AMAZON_PCI + 0x000000c8 +#define FPI_ADDRESS_MAP_3 AMAZON_PCI + 0x000000cc +#define FPI_ADDRESS_MAP_4 AMAZON_PCI + 0x000000d0 +#define FPI_ADDRESS_MAP_5 AMAZON_PCI + 0x000000d4 +#define FPI_ADDRESS_MAP_6 AMAZON_PCI + 0x000000d8 +#define FPI_ADDRESS_MAP_7 AMAZON_PCI + 0x000000dc +#define FPI_ADDRESS_MAP_11LOW AMAZON_PCI + 0x000000e0 +#define FPI_ADDRESS_MAP_11HIGH AMAZON_PCI + 0x000000e4 +#define FPI_BURST_LENGTH AMAZON_PCI + 0x000000e8 +#define SET_PCI_SERR AMAZON_PCI + 0x000000ec +#define DMA_FPI_START_ADDR AMAZON_PCI + 0x000000f0 +#define DMA_PCI_START_ADDR AMAZON_PCI + 0x000000f4 +#define DMA_TRANSFER_COUNT AMAZON_PCI + 0x000000f8 +#define DMA_CONTROL_STATUS AMAZON_PCI + 0x000000fc + +#define EXT_PCI1_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x0800 +#define EXT_PCI2_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x1000 +#define EXT_PCI3_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x1800 +#define EXT_PCI4_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x2000 +#define EXT_PCI5_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x2800 +#define EXT_PCI6_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x3000 +#define EXT_PCI7_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x3800 +#define EXT_PCI8_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x4000 +#define EXT_PCI9_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x4800 +#define EXT_PCI10_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x5000 +#define EXT_PCI11_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x5800 +#define EXT_PCI12_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x6000 +#define EXT_PCI13_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x6800 +#define EXT_PCI14_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x7000 +#define EXT_PCI15_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x7800 +#define EXT_CARDBUS_CONFIG_SPACE_BASE_ADDR AMAZON_PCI_CFG_BASE + 0XF000 +#define EXT_PCI_BAR1_ADDR 0x10 +#define EXT_PCI_BAR2_ADDR 0x14 +#define EXT_PCI_BAR3_ADDR 0x18 +#define EXT_PCI_BAR4_ADDR 0x1C +#define EXT_PCI_BAR5_ADDR 0x20 +#define EXT_PCI_BAR6_ADDR 0x24 + +#define DEVICE_ID_VECDOR_ID_ADDR AMAZON_PCI_CFG_BASE + 0x0 +#define STATUS_COMMAND_ADDR AMAZON_PCI_CFG_BASE + 0x4 +#define BUS_MASTER_ENABLE_BIT 2 +#define MEM_SPACE_ENABLE_BIT 1 +#define CLASS_CODE_REVISION_ADDR AMAZON_PCI_CFG_BASE + 0x8 +#define BIST_HEADER_TYPE_LATENCY_CAHCE_ADDR AMAZON_PCI_CFG_BASE + 0xC +#define BAR1_ADDR AMAZON_PCI_CFG_BASE + 0x10 +#define BAR2_ADDR AMAZON_PCI_CFG_BASE + 0x14 +#define BAR3_ADDR AMAZON_PCI_CFG_BASE + 0x18 +#define BAR4_ADDR AMAZON_PCI_CFG_BASE + 0x1C +#define BAR3_ADDR AMAZON_PCI_CFG_BASE + 0x18 +#define BAR4_ADDR AMAZON_PCI_CFG_BASE + 0x1C +#define BAR5_ADDR AMAZON_PCI_CFG_BASE + 0x20 +#define BAR6_ADDR AMAZON_PCI_CFG_BASE + 0x24 +#define CARDBUS_CIS_POINTER_ADDR AMAZON_PCI_CFG_BASE + 0x28 +#define SUBSYSTEM_ID_VENDOR_ID_ADDR AMAZON_PCI_CFG_BASE + 0x2C +#define EXPANSION_ROM_BASE_ADDR AMAZON_PCI_CFG_BASE + 0x30 +#define CAPABILITIES_POINTER_ADDR AMAZON_PCI_CFG_BASE + 0x34 +#define RESERVED_0x38 AMAZON_PCI_CFG_BASE + 0x38 +#define MAX_LAT_MIN_GNT_INT_PIN_LINE_ADDR AMAZON_PCI_CFG_BASE + 0x3C +#define POWER_MNGT_NEXT_POINTER_CAP_ID_ADDR AMAZON_PCI_CFG_BASE + 0x40 +#define POWER_MANAGEMENT_CTRL_STATUS_ADDR AMAZON_PCI_CFG_BASE + 0x44 +#define RESERVED_0x48 AMAZON_PCI_CFG_BASE + 0x48 +#define RESERVED_0x4C AMAZON_PCI_CFG_BASE + 0x4C +#define ERROR_ADDR_PCI_FPI_ADDR AMAZON_PCI_CFG_BASE + 0x50 +#define ERROR_ADdR_FPI_PCI_ADDR AMAZON_PCI_CFG_BASE + 0x54 +#define ERROR_TAG_FPI_PCI_ADDR AMAZON_PCI_CFG_BASE + 0x58 +#define PCI_ARB_CTRL_STATUS_ADDR AMAZON_PCI_CFG_BASE + 0x5C +#define INTERNAL_ARB_ENABLE_BIT 0 +#define ARB_SCHEME_BIT 1 +#define PCI_MASTER0_PRIOR_2BITS 2 +#define PCI_MASTER1_PRIOR_2BITS 4 +#define PCI_MASTER2_PRIOR_2BITS 6 +#define PCI_MASTER0_REQ_MASK_2BITS 8 +#define PCI_MASTER1_REQ_MASK_2BITS 10 +#define PCI_MASTER2_REQ_MASK_2BITS 12 +#define PCI_MASTER0_GNT_MASK_2BITS 14 +#define PCI_MASTER1_GNT_MASK_2BITS 16 +#define PCI_MASTER2_GNT_MASK_2BITS 18 +#define FPI_PCI_INT_STATUS_ADDR AMAZON_PCI_CFG_BASE + 0x60 +#define FPI_PCI_INT_ACK_ADDR AMAZON_PCI_CFG_BASE + 0x64 +#define FPI_PCI_INT_MASK_ADDR AMAZON_PCI_CFG_BASE + 0x68 +#define CARDBUS_CTRL_STATUS_ADDR AMAZON_PCI_CFG_BASE + 0x6C +#define CARDBUS_CFRAME_ENABLE 0 + +#define CLOCK_CONTROL_default 0x00000000 +#define CLOCK_CONTROL_mask 0x00000003 + +#define IDENTIFICATION_default 0x0011C002 +#define IDENTIFICATION_mask 0x00000000 + +#define SOFTRESET_default 0x00000000 +// SOFTRESET bit 0 is writable but will be reset to 0 after software reset is over +#define SOFTRESET_mask 0x00000000 + +#define PCI_FPI_ERROR_ADDRESS_default 0xFFFFFFFF +#define PCI_FPI_ERROR_ADDRESS_mask 0x00000000 + +#define FPI_PCI_ERROR_ADDRESS_default 0xFFFFFFFF +#define FPI_PCI_ERROR_ADDRESS_mask 0x00000000 + +#define FPI_ERROR_TAG_default 0x0000000F +#define FPI_ERROR_TAG_mask 0x00000000 + +#define IRR_default 0x00000000 +#define IRR_mask 0x07013b2F + +#define IRA_IR_default 0x00000000 +#define IRA_IR_mask 0x07013b2F + +#define IRM_default 0x00000000 +#define IRM_mask 0xFFFFFFFF + +#define EOI_default 0x00000000 +#define EOI_mask 0x00000000 + +#define PCI_MODE_default 0x01000103 +#define PCI_MODE_mask 0x1107070F + +#define DEVICE_VENDOR_ID_default 0x000C15D1 +#define DEVICE_VENDOR_ID_mask 0xFFFFFFFF + +#define SUBSYSTEM_VENDOR_ID_default 0x000015D1 +#define SUBSYSTEM_VENDOR_ID_mask 0x0000FFFF + +#define POWER_MANAGEMENT_default 0x0000001B +#define POWER_MANAGEMENT_mask 0x0000001F + +#define CLASS_CODE1_default 0x00028000 +#define CLASS_CODE1_mask 0x00FFFFFF + +#define BAR11_MASK_default 0x0FF00008 +#define BAR11_MASK_mask 0x8FF00008 + +#define BAR12_MASK_default 0x80001800 +#define BAR12_MASK_mask 0x80001F08 + +#define BAR13_MASK_default 0x8FF00008 +#define BAR13_MASK_mask 0x8FF00008 + +#define BAR14_MASK_default 0x8F000000 +#define BAR14_MASK_mask 0x8FFFFF08 + +#define BAR15_MASK_default 0x80000000 +#define BAR15_MASK_mask 0x8FFFFF08 + +#define BAR16_MASK_default 0x80000001 +// bit 0 and bit 3 is mutually exclusive +#define BAR16_MASK_mask 0x8FFFFFF9 + +#define CARDBUS_CIS_POINTER1_default 0x00000000 +#define CARDBUS_CIS_POINTER1_mask 0x03FFFFFF + +#define SUBSYSTEM_ID1_default 0x0000000C +#define SUBSYSTEM_ID1_mask 0x0000FFFF + +#define PCI_ADDRESS_MAP_11_default 0x18000000 +#define PCI_ADDRESS_MAP_11_mask 0x7FFFFFF1 + +#define PCI_ADDRESS_MAP_12_default 0x18100000 +#define PCI_ADDRESS_MAP_12_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_13_default 0x18200000 +#define PCI_ADDRESS_MAP_13_mask 0x7FF00001 + +#define PCI_ADDRESS_MAP_14_default 0x70000000 +#define PCI_ADDRESS_MAP_14_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_15_default 0x00000001 +#define PCI_ADDRESS_MAP_15_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_16_default 0x60000000 +#define PCI_ADDRESS_MAP_16_mask 0x7FF00001 + +#define FPI_SEGMENT_ENABLE_default 0x000003FF +#define FPI_SEGMENT_ENABLE_mask 0x000003FF + +#define CLASS_CODE2_default 0x00FF0000 +#define CLASS_CODE2_mask 0x00FFFFFF + +#define BAR21_MASK_default 0x80000008 +#define BAR21_MASK_mask 0x8FFFFFF8 + +#define BAR22_MASK_default 0x80000008 +#define BAR22_MASK_mask 0x80001F08 + +#define BAR23_MASK_default 0x80000008 +#define BAR23_MASK_mask 0x8FF00008 + +#define BAR24_MASK_default 0x8FE00000 +#define BAR24_MASK_mask 0x8FFFFF08 + +#define BAR25_MASK_default 0x8FFFF000 +#define BAR25_MASK_mask 0x8FFFFF08 + +#define BAR26_MASK_default 0x8FFFFFE1 +#define BAR26_MASK_mask 0x8FFFFFF1 + +#define CARDBUS_CIS_POINTER2_default 0x00000000 +#define CARDBUS_CIS_POINTER2_mask 0x03FFFFFF + +#define SUBSYSTEM_ID2_default 0x0000000C +#define SUBSYSTEM_ID2_mask 0x0000FFFF + +#define PCI_ADDRESS_MAP_21_default 0x3FE00000 +#define PCI_ADDRESS_MAP_21_mask 0x7FFFFFF1 + +#define PCI_ADDRESS_MAP_22_default 0x68000000 +#define PCI_ADDRESS_MAP_22_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_23_default 0x20000000 +#define PCI_ADDRESS_MAP_23_mask 0x7FF00001 + +#define PCI_ADDRESS_MAP_24_default 0x70000001 +#define PCI_ADDRESS_MAP_24_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_25_default 0x78000001 +#define PCI_ADDRESS_MAP_25_mask 0x7FFFFF01 + +#define PCI_ADDRESS_MAP_26_default 0x20000000 +#define PCI_ADDRESS_MAP_26_mask 0x7FF00001 + +#define FPI_ADDRESS_MASK11LOW_default 0x00000000 +#define FPI_ADDRESS_MASK11LOW_mask 0x00070000 + +#define FPI_ADDRESS_MAP_0_default 0x00000000 +#define FPI_ADDRESS_MAP_0_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_1_default 0x10000000 +#define FPI_ADDRESS_MAP_1_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_2_default 0x20000000 +#define FPI_ADDRESS_MAP_2_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_3_default 0x30000000 +#define FPI_ADDRESS_MAP_3_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_4_default 0x40000000 +#define FPI_ADDRESS_MAP_4_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_5_default 0x50000000 +#define FPI_ADDRESS_MAP_5_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_6_default 0x60000000 +#define FPI_ADDRESS_MAP_6_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_7_default 0x70000000 +#define FPI_ADDRESS_MAP_7_mask 0xFFF00000 + +#define FPI_ADDRESS_MAP_11LOW_default 0xB0000000 +#define FPI_ADDRESS_MAP_11LOW_mask 0xFFFF0000 + +#define FPI_ADDRESS_MAP_11HIGH_default 0xB8000000 +#define FPI_ADDRESS_MAP_11HIGH_mask 0xFFF80000 + +#define FPI_BURST_LENGTH_default 0x00000000 +#define FPI_BURST_LENGTH_mask 0x00000303 + +#define SET_PCI_SERR_default 0x00000000 +#define SET_PCI_SERR_mask 0x00000000 + +#define DMA_FPI_START_ADDRESS_default 0x00000000 +#define DMA_FPI_START_ADDRESS_mask 0xFFFFFFFF + +#define DMA_PCI_START_ADDRESS_default 0x00000000 +#define DMA_PCI_START_ADDRESS_mask 0xFFFFFFFF + +#define DMA_TRANSFER_COUNT_default 0x00000000 +#define DMA_TRANSFER_COUNT_mask 0x0000FFFF + +#define DMA_CONTROL_STATUS_default 0x00000000 +#define DMA_CONTROL_STATUS_mask 0x00000000 // bit 0,1 is writable + +/***********************************************************************/ +#undef IKOS_MINI_BOOT //don't run a full booting +#ifdef CONFIG_USE_IKOS +#define CONFIG_USE_VENUS //Faster, 10M CPU and 192k baudrate +#ifdef CONFIG_USE_VENUS +#define IKOS_CPU_SPEED 10000000 +#else +#define IKOS_CPU_SPEED 180000 //IKOS is slow +#endif +#endif //CONFIG_USE_IKOS + +/* 165001:henryhsu:20050603:Source Modify form Bing Tao */ + +#if defined(CONFIG_NET_WIRELESS_SPURS) || defined(CONFIG_NET_WIRELESS_SPURS_MODULE) +#define EBU_PCI_SOFTWARE_ARBITOR +#endif + +#define AMAZON_B11 +#ifdef AMAZON_B11 +#define SWITCH_BUF_FPI_ADDR (0x10110000) +#define SWITCH_BUF_ADDR (KSEG1+SWITCH_BUF_FPI_ADDR) +#define SWITCH_BUF_SIZE (0x2800) +#define AMAZON_B11_CBM_QD_ADDR (SWITCH_BUF_ADDR+0x0) +#define AMAZON_B11_BOND_CELL_ADDR (SWITCH_BUF_ADDR+0x000) +#endif +#define AMAZON_REFERENCE_BOARD +//for AMAZON ATM bonding application +#ifdef AMAZON_REFERENCE_BOARD +#define GPIO_DETECT_LOW +#else +#undef GPIO_DETECT_LOW +#endif + +/* 165001 */ + +#undef AMAZON_IKOS_DEBUG_MSG +#undef AMAZON_INT_DEBUG_MSG +#undef AMAZON_ATM_DEBUG_MSG +#undef AMAZON_DMA_DEBUG_MSG +#undef AMAZON_SW_DEBUG_MSG +#undef AMAZON_WDT_DEBUG_MSG +#undef AMAZON_MTD_DEBUG_MSG +#undef AMAZON_SSC_DEBUG_MSG +#undef AMAZON_MEI_DEBUG_MSG + +#ifdef AMAZON_IKOS_DEBUG_MSG +#define AMAZON_IKOS_DMSG(fmt,args...) printk("%s:" fmt, __FUNCTION__, ##args) +#else +#define AMAZON_IKOS_DMSG(fmt,args...) +#endif + +#ifdef AMAZON_WDT_DEBUG_MSG +#define AMAZON_WDT_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args) +#else +#define AMAZON_WDT_DMSG(fm,args...) +#endif + +#ifdef AMAZON_SSC_DEBUG_MSG +#define AMAZON_SSC_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args) +#else +#define AMAZON_SSC_DMSG(fm,args...) +#endif + +#ifdef AMAZON_DMA_DEBUG_MSG +#define AMAZON_DMA_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args) +#else +#define AMAZON_DMA_DMSG(fm,args...) +#endif + +#ifdef AMAZON_ATM_DEBUG_MSG +#define AMAZON_TPE_DMSG(fmt, args...) printk( "%s: " fmt, __FUNCTION__ , ##args) +#else //not AMAZON_ATM_DEBUG +#define AMAZON_TPE_DMSG(fmt, args...) +#endif //AMAZON_ATM_DEBUG + +#ifdef AMAZON_SW_DEBUG_MSG +#define AMAZON_SW_DMSG(fmt,args...) printk("%s: " fmt, __FUNCTION__ , ##args) +#else +#define AMAZON_SW_DMSG(fmt,args...) +#endif + +#ifdef AMAZON_MTD_DEBUG_MSG +#define AMAZON_MTD_DMSG(fmt,args...) printk("%s: " fmt, __FUNCTION__ , ##args) +#else +#define AMAZON_MTD_DMSG(fmt,args...) +#endif + +#ifdef AMAZON_INT_DEBUG_MSG +#define AMAZON_INT_DMSG(x...) printk(x) +#else +#define AMAZON_INT_DMSG(x...) +#endif + +#ifdef AMAZON_MEI_DEBUG_MSG +#define AMAZON_MEI_DMSG(fmt,args...) printk("%s:" fmt, __FUNCTION__, ##args) +#else +#define AMAZON_MEI_DMSG(fmt,args...) +#endif + +#endif //AMAZON_H diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_dma.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_dma.h new file mode 100644 index 0000000000..63ab5924e5 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_dma.h @@ -0,0 +1,148 @@ +#ifndef AMAZON_DMA_H +#define AMAZON_DMA_H + +#define RCV_INT 1 +#define TX_BUF_FULL_INT 2 +#define TRANSMIT_CPT_INT 4 + +#define QOS_DEFAULT_WGT 0x7fffffffUL; + + +enum attr_t{ + TX=0, + RX=1, + RESERVED=2, + DEFAULT=3, + +}; + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +typedef struct rx_desc{ + u32 data_length:16; + volatile u32 reserved:7; + volatile u32 byte_offset:2; + volatile u32 Burst_length_offset:3; + volatile u32 EoP:1; + volatile u32 Res:1; + volatile u32 C:1; + volatile u32 OWN:1; + volatile u32 Data_Pointer; + /*fix me:should be 28 bits here, 32 bits just for host simulatiuon purpose*/ +}_rx_desc; + + +typedef struct tx_desc{ + volatile u32 data_length:16; + volatile u32 reserved1:7; + volatile u32 byte_offset:5; + volatile u32 EoP:1; + volatile u32 SoP:1; + volatile u32 C:1; + volatile u32 OWN:1; + volatile u32 Data_Pointer;//fix me:should be 28 bits here +}_tx_desc; +#else //BIG +typedef struct rx_desc{ + union + { + struct + { + volatile u32 OWN :1; + volatile u32 C :1; + volatile u32 SoP :1; + volatile u32 EoP :1; + volatile u32 Burst_length_offset :3; + volatile u32 byte_offset :2; + volatile u32 reserve :7; + volatile u32 data_length :16; + }field; + + volatile u32 word; + }status; + + volatile u32 Data_Pointer; +}_rx_desc; + + +typedef struct tx_desc{ + union + { + struct + { + volatile u32 OWN :1; + volatile u32 C :1; + volatile u32 SoP :1; + volatile u32 EoP :1; + volatile u32 byte_offset :5; + volatile u32 reserved :7; + volatile u32 data_length :16; + }field; + + volatile u32 word; + }status; + + volatile u32 Data_Pointer; +}_tx_desc; + +#endif //ENDIAN + +struct dma_channel_info{ + /*filled by driver, optional*/ + enum attr_t attr;/*TX or RX*/ + int weight; + int desc_num; + int packet_size; + int control;/*on or off*/ + + int desc_base; + int status; +}; + +typedef struct dma_channel_info _dma_channel_info; + +struct dma_device_info{ + /*variables*/ + /*filled by driver, compulsary*/ + char device_name[15]; + enum attr_t attr;/*default or else*/ + int tx_burst_len; + int rx_burst_len; + + int logic_rx_chan_base; + int logic_tx_chan_base; + u8 on_ch_bit; + /*filled by driver, optional*/ + int weight; + int current_tx_chan; + int current_rx_chan; + int num_tx_chan; + int num_rx_chan; + struct dma_channel_info tx_chan[2]; + struct dma_channel_info rx_chan[4]; + + /*functions, optional*/ + u8* (*buffer_alloc)(int len,int* offset, void** opt); + int (*buffer_free)(u8* dataptr, void* opt); + int (*intr_handler)(struct dma_device_info* info, int status); + /*set by device, clear by dma*/ + int ack; + void * priv; /* used by peripheral driver only */ +}; +typedef struct dma_device_info _dma_device_info; + +int dma_device_register(struct dma_device_info* info); + +int dma_device_unregister(struct dma_device_info* info); + +int dma_device_read(struct dma_device_info* info, u8** dataptr, void** opt); + +int dma_device_write(struct dma_device_info* info, u8* dataptr, int len, void* opt); + +int dma_device_update(struct dma_device_info* info); + +void dma_device_update_rx(struct dma_device_info* dma_dev); + +void dma_device_update_tx(struct dma_device_info* dma_dev); + +void register_handler_sim(int (*handler)(int)); +#endif /* AMAZON_DMA_H */ diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei.h new file mode 100644 index 0000000000..6ac8ab310b --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei.h @@ -0,0 +1,220 @@ +#ifndef _AMAZON_MEI_H +#define _AMAZON_MEI_H +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include "amazon_mei_app.h" + +#define AMAZON_MEI_DEBUG_ON +#define AMAZON_MEI_CMV_EXTRA + +#define AMAZON_MEI_MAJOR 106 + +/* +** Define where in ME Processor's memory map the Stratify chip lives +*/ +#define MEI_SPACE_ACCESS 0xB0100C00 + +#define MAXSWAPSIZE 8 * 1024 //8k *(32bits) +//#define AMAZON_ADSL_IMAGESIZE 16*1024 // 16k * (32bits) + + +// Mailboxes +#define MSG_LENGTH 16 // x16 bits +#define YES_REPLY 1 +#define NO_REPLY 0 + +#define CMV_TIMEOUT 100 //jiffies +#define MIB_INTERVAL 10000 //msec + +/*** Bit definitions ***/ + +#define FALSE 0 +#define TRUE 1 +#define BIT0 1<<0 +#define BIT1 1<<1 +#define BIT2 1<<2 +#define BIT3 1<<3 +#define BIT4 1<<4 +#define BIT5 1<<5 +#define BIT6 1<<6 +#define BIT7 1<<7 +#define BIT8 1<<8 +#define BIT9 1<<9 +#define BIT10 1<<10 +#define BIT11 1<<11 +#define BIT12 1<<12 +#define BIT13 1<<13 +#define BIT14 1<<14 +#define BIT15 1<<15 +#define BIT16 1<<16 +#define BIT17 1<<17 +#define BIT18 1<<18 +#define BIT19 1<<19 +#define BIT20 1<<20 +#define BIT21 1<<21 +#define BIT22 1<<22 +#define BIT23 1<<23 +#define BIT24 1<<24 +#define BIT25 1<<25 +#define BIT26 1<<26 +#define BIT27 1<<27 +#define BIT28 1<<28 +#define BIT29 1<<29 +#define BIT30 1<<30 +#define BIT31 1<<31 + + +/*** Register address offsets, relative to MEI_SPACE_ADDRESS ***/ +#define MEI_DATA_XFR (0x0000 + MEI_SPACE_ACCESS) +#define MEI_VERSION (0x0200 + MEI_SPACE_ACCESS) +#define ARC_GP_STAT (0x0204 + MEI_SPACE_ACCESS) +#define MEI_XFR_ADDR (0x020C + MEI_SPACE_ACCESS) +#define MEI_TO_ARC_INT (0x021C + MEI_SPACE_ACCESS) +#define ARC_TO_MEI_INT (0x0220 + MEI_SPACE_ACCESS) +#define ARC_TO_MEI_INT_MASK (0x0224 + MEI_SPACE_ACCESS) +#define MEI_DEBUG_WAD (0x0228 + MEI_SPACE_ACCESS) +#define MEI_DEBUG_RAD (0x022C + MEI_SPACE_ACCESS) +#define MEI_DEBUG_DATA (0x0230 + MEI_SPACE_ACCESS) +#define MEI_DEBUG_DEC (0x0234 + MEI_SPACE_ACCESS) +#define MEI_CONTROL (0x0238 + MEI_SPACE_ACCESS) +#define AT_CELLRDY_BC0 (0x023C + MEI_SPACE_ACCESS) +#define AT_CELLRDY_BC1 (0x0240 + MEI_SPACE_ACCESS) +#define AR_CELLRDY_BC0 (0x0244 + MEI_SPACE_ACCESS) +#define AR_CELLRDY_BC1 (0x0248 + MEI_SPACE_ACCESS) +#define AAI_ACCESS (0x024C + MEI_SPACE_ACCESS) +#define AAITXCB0 (0x0300 + MEI_SPACE_ACCESS) +#define AAITXCB1 (0x0304 + MEI_SPACE_ACCESS) +#define AAIRXCB0 (0x0308 + MEI_SPACE_ACCESS) +#define AAIRXCB1 (0x030C + MEI_SPACE_ACCESS) + + +// MEI_TO_ARC_INTERRUPT Register definitions +#define MEI_TO_ARC_INT1 BIT3 +#define MEI_TO_ARC_INT0 BIT2 +#define MEI_TO_ARC_CS_DONE BIT1 +#define MEI_TO_ARC_MSGAV BIT0 + +// ARC_TO_MEI_INTERRUPT Register definitions +#define ARC_TO_MEI_INT1 BIT8 +#define ARC_TO_MEI_INT0 BIT7 +#define ARC_TO_MEI_CS_REQ BIT6 +#define ARC_TO_MEI_DBG_DONE BIT5 +#define ARC_TO_MEI_MSGACK BIT4 +#define ARC_TO_MEI_NO_ACCESS BIT3 +#define ARC_TO_MEI_CHECK_AAITX BIT2 +#define ARC_TO_MEI_CHECK_AAIRX BIT1 +#define ARC_TO_MEI_MSGAV BIT0 + +// ARC_TO_MEI_INTERRUPT_MASK Register definitions +#define GP_INT1_EN BIT8 +#define GP_INT0_EN BIT7 +#define CS_REQ_EN BIT6 +#define DBG_DONE_EN BIT5 +#define MSGACK_EN BIT4 +#define NO_ACC_EN BIT3 +#define AAITX_EN BIT2 +#define AAIRX_EN BIT1 +#define MSGAV_EN BIT0 + +// MEI_CONTROL Register definitions +#define INT_LEVEL BIT2 +#define SOFT_RESET BIT1 +#define HOST_MSTR BIT0 + +// MEI_DEBUG_DECODE Register definitions +#define MEI_DEBUG_DEC_MASK (0x3) +#define MEI_DEBUG_DEC_AUX_MASK (0x0) +#define MEI_DEBUG_DEC_DMP1_MASK (0x1) +#define MEI_DEBUG_DEC_DMP2_MASK (0x2) +#define MEI_DEBUG_DEC_CORE_MASK (0x3) + + +// ARC_TO_MEI_MAILBOX[11] is a special location used to indicate +// page swap requests. +#define MEI_TO_ARC_MAILBOX (0x15FC0) +#define MEI_TO_ARC_MAILBOXR (0x15FEC) +#define ARC_TO_MEI_MAILBOX (0x15F90) +#define ARC_MEI_MAILBOXR (0x15FBC) + +// Codeswap request messages are indicated by setting BIT31 +#define OMB_CODESWAP_MESSAGE_MSG_TYPE_MASK (0x80000000) + +/* +** Swap page header +*/ +// Page must be loaded at boot time if size field has BIT31 set +#define BOOT_FLAG (BIT31) +#define BOOT_FLAG_MASK ~BOOT_FLAG + +// Swap page header describes size in 32-bit words, load location, and image offset +// for program and/or data segments +typedef struct _arc_swp_page_hdr +{ + u32 p_offset; // Offset bytes of progseg from beginning of image + u32 p_dest; // Destination addr of progseg on processor + u32 p_size; // Size in 32-bitwords of program segment + u32 d_offset; // Offset bytes of dataseg from beginning of image + u32 d_dest; // Destination addr of dataseg on processor + u32 d_size; // Size in 32-bitwords of data segment +}ARC_SWP_PAGE_HDR; + + +/* +** Swap image header +*/ +#define GET_PROG 0 // Flag used for program mem segment +#define GET_DATA 1 // Flag used for data mem segment + +// Image header contains size of image, checksum for image, and count of +// page headers. Following that are 'count' page headers followed by +// the code and/or data segments to be loaded +typedef struct _arc_img_hdr +{ + u32 size; // Size of binary image in bytes + u32 checksum; // Checksum for image + u32 count; // Count of swp pages in image + ARC_SWP_PAGE_HDR page[1]; // Should be "count" pages - '1' to make compiler happy +}ARC_IMG_HDR; + + + +/* +** Native size for the Stratiphy interface is 32-bits. All reads and writes +** MUST be aligned on 32-bit boundaries. Trickery must be invoked to read word and/or +** byte data. Read routines are provided. Write routines are probably a bad idea, as the +** Arc has unrestrained, unseen access to the same memory, so a read-modify-write cycle +** could very well have unintended results. +*/ +MEI_ERROR meiCMV(u16 *, int); // first arg is CMV to ARC, second to indicate whether need reply + +void meiLongwordWrite(u32 ul_address, u32 ul_data); +void meiLongwordRead(u32 ul_address, u32 *pul_data); + + +MEI_ERROR meiDMAWrite(u32 destaddr, u32 *databuff, u32 databuffsize); +MEI_ERROR meiDebugWrite(u32 destaddr, u32 *databuff, u32 databuffsize); + +MEI_ERROR meiDMARead(u32 srcaddr, u32 *databuff, u32 databuffsize); +MEI_ERROR meiDebugRead(u32 srcaddr, u32 *databuff, u32 databuffsize); + +void meiPollForDbgDone(void); + +void meiMailboxInterruptsDisable(void); +void meiMailboxInterruptsEnable(void); + +MEI_ERROR meiMailboxWrite(u16 *msgsrcbuffer, u16 msgsize); +MEI_ERROR meiMailboxRead(u16 *msgdestbuffer, u16 msgsize); + +int meiGetPage( u32 Page, u32 data, u32 MaxSize, u32 *Buffer, u32 *Dest); + +MEI_ERROR meiHaltArc(void); +MEI_ERROR meiRunArc(void); + +MEI_ERROR meiDownloadBootCode(void); + +MEI_ERROR meiForceRebootAdslModem(void); + +void makeCMV(u8 opcode, u8 group, u16 address, u16 index, int size, u16 * data); + +#endif + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app.h new file mode 100644 index 0000000000..89700d9d76 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app.h @@ -0,0 +1,54 @@ +//509221:tc.chen 2005/09/22 Reset DFE added when MEI_TO_ARC_CS_DONE not cleared by ARC and Added AMAZON_MEI_DEBUG_MODE ioctl + +#ifndef _AMAZON_MEI_APP_H +#define _AMAZON_MEI_APP_H + +///////////////////////////////////////////////////////////////////////////////////////////////////// + + // ioctl control +#define AMAZON_MEI_START 300 +#define AMAZON_MEI_REPLY 301 +#define AMAZON_MEI_NOREPLY 302 + +#define AMAZON_MEI_RESET 303 +#define AMAZON_MEI_REBOOT 304 +#define AMAZON_MEI_HALT 305 +#define AMAZON_MEI_CMV_WINHOST 306 +#define AMAZON_MEI_CMV_READ 307 +#define AMAZON_MEI_CMV_WRITE 308 +#define AMAZON_MEI_MIB_DAEMON 309 +#define AMAZON_MEI_SHOWTIME 310 +#define AMAZON_MEI_REMOTE 311 +#define AMAZON_MEI_READDEBUG 312 +#define AMAZON_MEI_WRITEDEBUG 313 +#define AMAZON_MEI_LOP 314 + +#define AMAZON_MEI_PCM_SETUP 315 +#define AMAZON_MEI_PCM_START_TIMER 316 +#define AMAZON_MEI_PCM_STOP_TIMER 317 +#define AMAZON_MEI_PCM_CHECK 318 +#define AMAZON_MEI_GET_EOC_LEN 319 +#define AMAZON_MEI_GET_EOC_DATA 320 +#define AMAZON_MEI_PCM_GETDATA 321 +#define AMAZON_MEI_PCM_GPIO 322 +#define AMAZON_MEI_EOC_SEND 323 +//MIB +#define AMAZON_MIB_LO_ATUC 324 +#define AMAZON_MIB_LO_ATUR 325 +#define AMAZON_MEI_DOWNLOAD 326 + +#define AMAZON_MEI_DEBUG_MODE 327 //509221:tc.chen +#define LOOP_DIAGNOSTIC_MODE_COMPLETE 328 + + +/*** Enums ***/ +typedef enum mei_error +{ + MEI_SUCCESS = 0, + MEI_FAILURE = -1, + MEI_MAILBOX_FULL = -2, + MEI_MAILBOX_EMPTY = -3, + MEI_MAILBOX_TIMEOUT = -4, +}MEI_ERROR; + +#endif diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app_ioctl.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app_ioctl.h new file mode 100644 index 0000000000..d98f60b171 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_app_ioctl.h @@ -0,0 +1,1169 @@ +// 603221:tc.chen 2006/03/21 added APIs to support the WEB related parameters for ADSL Statistics + +#ifndef __AMAZON_MEI_APP_IOCTL_H +#define __AMAZON_MEI_APP_IOCTL_H + +#ifdef __KERNEL__ +#include "amazon_mei_ioctl.h" +#endif + +/* Interface Name */ +//#define INTERFACE_NAME <define the interface> + +/* adslLineTable constants */ +#define GET_ADSL_LINE_CODE 1 + +/* adslAtucPhysTable constants */ +#define GET_ADSL_ATUC_PHY 4 + +/* adslAturPhysTable constants */ +#define GET_ADSL_ATUR_PHY 10 + +/* adslAtucChanTable constants */ +#define GET_ADSL_ATUC_CHAN_INFO 15 + +/* adslAturChanTable constants */ +#define GET_ADSL_ATUR_CHAN_INFO 18 + +/* adslAtucPerfDataTable constants */ +#define GET_ADSL_ATUC_PERF_DATA 21 + +/* adslAturPerfDataTable constants */ +#define GET_ADSL_ATUR_PERF_DATA 40 + +/* adslAtucIntervalTable constants */ +#define GET_ADSL_ATUC_INTVL_INFO 60 + +/* adslAturIntervalTable constants */ +#define GET_ADSL_ATUR_INTVL_INFO 65 + +/* adslAtucChanPerfDataTable constants */ +#define GET_ADSL_ATUC_CHAN_PERF_DATA 70 + +/* adslAturChanPerfDataTable constants */ +#define GET_ADSL_ATUR_CHAN_PERF_DATA 90 + +/* adslAtucChanIntervalTable constants */ +#define GET_ADSL_ATUC_CHAN_INTVL_INFO 110 + +/* adslAturChanIntervalTable constants */ +#define GET_ADSL_ATUR_CHAN_INTVL_INFO 115 + +/* adslLineAlarmConfProfileTable constants */ +#define GET_ADSL_ALRM_CONF_PROF 120 +#define SET_ADSL_ALRM_CONF_PROF 121 + +/* adslAturTrap constants */ +#define ADSL_ATUR_TRAPS 135 + +////////////////// RFC-3440 ////////////// + +#ifdef AMAZON_MEI_MIB_RFC3440 +/* adslLineExtTable */ +#define GET_ADSL_ATUC_LINE_EXT 201 +#define SET_ADSL_ATUC_LINE_EXT 203 + +/* adslAtucPerfDateExtTable */ +#define GET_ADSL_ATUC_PERF_DATA_EXT 205 + +/* adslAtucIntervalExtTable */ +#define GET_ADSL_ATUC_INTVL_EXT_INFO 221 + +/* adslAturPerfDataExtTable */ +#define GET_ADSL_ATUR_PERF_DATA_EXT 225 + +/* adslAturIntervalExtTable */ +#define GET_ADSL_ATUR_INTVL_EXT_INFO 233 + +/* adslAlarmConfProfileExtTable */ +#define GET_ADSL_ALRM_CONF_PROF_EXT 235 +#define SET_ADSL_ALRM_CONF_PROF_EXT 236 + +/* adslAturExtTrap */ +#define ADSL_ATUR_EXT_TRAPS 240 + +#endif + +// 603221:tc.chen start +/* The following constants are added to support the WEB related ADSL Statistics */ + +/* adslLineStatus constants */ +#define GET_ADSL_LINE_STATUS 245 + +/* adslLineRate constants */ +#define GET_ADSL_LINE_RATE 250 + +/* adslLineInformation constants */ +#define GET_ADSL_LINE_INFO 255 + +/* adslNearEndPerformanceStats constants */ +#define GET_ADSL_NEAREND_STATS 270 + +/* adslFarEndPerformanceStats constants */ +#define GET_ADSL_FAREND_STATS 290 + +// 603221:tc.chen end + +/* Loop diagnostics mode of the ADSL line related constants */ +#define GET_ADSL_LOOP_DIAGNOSTICS_MODE 295 +#define SET_ADSL_LOOP_DIAGNOSTICS_MODE 296 +#define IS_ADSL_LOOP_DIAGNOSTICS_MODE_COMPLETE 299 + +/* Sub-carrier related parameters */ +#define GET_ADSL_ATUC_SUBCARRIER_STATS 297 +#define GET_ADSL_ATUR_SUBCARRIER_STATS 298 +#define GET_ADSL_LINE_INIT_STATS 150 +#define GET_ADSL_POWER_SPECTRAL_DENSITY 151 + + +/////////////////////////////////////////////////////////// +// makeCMV(Opcode, Group, Address, Index, Size, Data) + +/* adslLineCode Flags */ +#define LINE_CODE_FLAG 0x1 /* BIT 0th position */ + +/* adslAtucPhysTable Flags */ +#define ATUC_PHY_SER_NUM_FLAG 0x1 /* BIT 0th position */ +#define ATUC_PHY_SER_NUM_FLAG_MAKECMV1 makeCMV(H2D_CMV_READ, INFO, 57, 0, 12, data) +#define ATUC_PHY_SER_NUM_FLAG_MAKECMV2 makeCMV(H2D_CMV_READ, INFO, 57, 12, 4, data) + +#define ATUC_PHY_VENDOR_ID_FLAG 0x2 /* BIT 1 */ +#define ATUC_PHY_VENDOR_ID_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 64, 0, 4, data) + +#define ATUC_PHY_VER_NUM_FLAG 0x4 /* BIT 2 */ +#define ATUC_PHY_VER_NUM_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 58, 0, 8, data) + +#define ATUC_CURR_STAT_FLAG 0x8 /* BIT 3 */ + +#define ATUC_CURR_OUT_PWR_FLAG 0x10 /* BIT 4 */ +#define ATUC_CURR_OUT_PWR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 5, 1, data) + +#define ATUC_CURR_ATTR_FLAG 0x20 /* BIT 5 */ +#define ATUC_CURR_ATTR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 0, 2, data) + + +/* adslAturPhysTable Flags */ +#define ATUR_PHY_SER_NUM_FLAG 0x1 /* BIT 0th position */ +#define ATUR_PHY_SER_NUM_FLAG_MAKECMV1 makeCMV(H2D_CMV_READ, INFO, 62, 0, 12, data) +#define ATUR_PHY_SER_NUM_FLAG_MAKECMV2 makeCMV(H2D_CMV_READ, INFO, 62, 12, 4, data) + +#define ATUR_PHY_VENDOR_ID_FLAG 0x2 /* BIT 1 */ +#define ATUR_PHY_VENDOR_ID_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 65, 0, 4, data) + +#define ATUR_PHY_VER_NUM_FLAG 0x4 /* BIT 2 */ +#define ATUR_PHY_VER_NUM_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 61, 0, 8, data) + +#define ATUR_SNRMGN_FLAG 0x8 +#define ATUR_SNRMGN_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 4, 1, data) + +#define ATUR_ATTN_FLAG 0x10 +#define ATUR_ATTN_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 2, 1, data) + +#define ATUR_CURR_STAT_FLAG 0x20 /* BIT 3 */ + +#define ATUR_CURR_OUT_PWR_FLAG 0x40 /* BIT 4 */ +#define ATUR_CURR_OUT_PWR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 5, 1, data) + +#define ATUR_CURR_ATTR_FLAG 0x80 /* BIT 5 */ +#define ATUR_CURR_ATTR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 0, 2, data) + +/* adslAtucChanTable Flags */ +#define ATUC_CHAN_INTLV_DELAY_FLAG 0x1 /* BIT 0th position */ +#define ATUC_CHAN_INTLV_DELAY_FLAG_MAKECMV makeCMV(H2D_CMV_READ, RATE, 3, 1, 1, data) + +#define ATUC_CHAN_CURR_TX_RATE_FLAG 0x2 /* BIT 1 */ +#define ATUC_CHAN_CURR_TX_RATE_FLAG_MAKECMV makeCMV(H2D_CMV_READ, RATE, 1, 0, 2, data) + +#define ATUC_CHAN_PREV_TX_RATE_FLAG 0x4 /* BIT 2 */ + +/* adslAturChanTable Flags */ +#define ATUR_CHAN_INTLV_DELAY_FLAG 0x1 /* BIT 0th position */ +#define ATUR_CHAN_INTLV_DELAY_FLAG_MAKECMV makeCMV(H2D_CMV_READ, RATE, 2, 1, 1, data) + +#define ATUR_CHAN_CURR_TX_RATE_FLAG 0x2 /* BIT 1 */ +#define ATUR_CHAN_CURR_TX_RATE_FLAG_MAKECMV makeCMV(H2D_CMV_READ, RATE, 0, 0, 2, data) + +#define ATUR_CHAN_PREV_TX_RATE_FLAG 0x4 /* BIT 2 */ + +#define ATUR_CHAN_CRC_BLK_LEN_FLAG 0x8 /* BIT 3 */ + +/* adslAtucPerfDataTable Flags */ +#define ATUC_PERF_LOFS_FLAG 0x1 /* BIT 0th position */ +#define ATUC_PERF_LOSS_FLAG 0x2 /* BIT 1 */ +#define ATUC_PERF_LO_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 0, 0, 1, data) +#define ATUC_PERF_ESS_FLAG 0x4 /* BIT 2 */ +#define ATUC_PERF_ESS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 7, 0, 1, data) +#define ATUC_PERF_INITS_FLAG 0x8 /* BIT 3 */ +#define ATUC_PERF_VALID_INTVLS_FLAG 0x10 /* BIT 4 */ +#define ATUC_PERF_INVALID_INTVLS_FLAG 0x20 /* BIT 5 */ +#define ATUC_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */ +#define ATUC_PERF_CURR_15MIN_LOFS_FLAG 0x80 /* BIT 7 */ +#define ATUC_PERF_CURR_15MIN_LOSS_FLAG 0x100 /* BIT 8 */ +#define ATUC_PERF_CURR_15MIN_ESS_FLAG 0x200 /* BIT 9 */ +#define ATUC_PERF_CURR_15MIN_INIT_FLAG 0x400 /* BIT 10 */ +#define ATUC_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11 */ +#define ATUC_PERF_CURR_1DAY_LOFS_FLAG 0x1000 /* BIT 12 */ +#define ATUC_PERF_CURR_1DAY_LOSS_FLAG 0x2000 /* BIT 13 */ +#define ATUC_PERF_CURR_1DAY_ESS_FLAG 0x4000 /* BIT 14 */ +#define ATUC_PERF_CURR_1DAY_INIT_FLAG 0x8000 /* BIT 15 */ +#define ATUC_PERF_PREV_1DAY_MON_SEC_FLAG 0x10000 /* BIT 16 */ +#define ATUC_PERF_PREV_1DAY_LOFS_FLAG 0x20000 /* BIT 17 */ +#define ATUC_PERF_PREV_1DAY_LOSS_FLAG 0x40000 /* BIT 18 */ +#define ATUC_PERF_PREV_1DAY_ESS_FLAG 0x80000 /* BIT 19 */ +#define ATUC_PERF_PREV_1DAY_INITS_FLAG 0x100000 /* BIT 20 */ + +/* adslAturPerfDataTable Flags */ +#define ATUR_PERF_LOFS_FLAG 0x1 /* BIT 0th position */ +#define ATUR_PERF_LOSS_FLAG 0x2 /* BIT 1 */ +#define ATUR_PERF_LPR_FLAG 0x4 /* BIT 2 */ +#define ATUR_PERF_LO_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 1, 0, 1, data) +#define ATUR_PERF_ESS_FLAG 0x8 /* BIT 3 */ +#define ATUR_PERF_ESS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 33, 0, 1, data) +#define ATUR_PERF_VALID_INTVLS_FLAG 0x10 /* BIT 4 */ +#define ATUR_PERF_INVALID_INTVLS_FLAG 0x20 /* BIT 5 */ +#define ATUR_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */ +#define ATUR_PERF_CURR_15MIN_LOFS_FLAG 0x80 /* BIT 7 */ +#define ATUR_PERF_CURR_15MIN_LOSS_FLAG 0x100 /* BIT 8 */ +#define ATUR_PERF_CURR_15MIN_LPR_FLAG 0x200 /* BIT 9 */ +#define ATUR_PERF_CURR_15MIN_ESS_FLAG 0x400 /* BIT 10 */ +#define ATUR_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11 */ +#define ATUR_PERF_CURR_1DAY_LOFS_FLAG 0x1000 /* BIT 12 */ +#define ATUR_PERF_CURR_1DAY_LOSS_FLAG 0x2000 /* BIT 13 */ +#define ATUR_PERF_CURR_1DAY_LPR_FLAG 0x4000 /* BIT 14 */ +#define ATUR_PERF_CURR_1DAY_ESS_FLAG 0x8000 /* BIT 15 */ +#define ATUR_PERF_PREV_1DAY_MON_SEC_FLAG 0x10000 /* BIT 16 */ +#define ATUR_PERF_PREV_1DAY_LOFS_FLAG 0x20000 /* BIT 17 */ +#define ATUR_PERF_PREV_1DAY_LOSS_FLAG 0x40000 /* BIT 18 */ +#define ATUR_PERF_PREV_1DAY_LPR_FLAG 0x80000 /* BIT 19 */ +#define ATUR_PERF_PREV_1DAY_ESS_FLAG 0x100000 /* BIT 20 */ + +/* adslAtucIntervalTable Flags */ +#define ATUC_INTVL_LOF_FLAG 0x1 /* BIT 0th position */ +#define ATUC_INTVL_LOS_FLAG 0x2 /* BIT 1 */ +#define ATUC_INTVL_ESS_FLAG 0x4 /* BIT 2 */ +#define ATUC_INTVL_INIT_FLAG 0x8 /* BIT 3 */ +#define ATUC_INTVL_VALID_DATA_FLAG 0x10 /* BIT 4 */ + +/* adslAturIntervalTable Flags */ +#define ATUR_INTVL_LOF_FLAG 0x1 /* BIT 0th position */ +#define ATUR_INTVL_LOS_FLAG 0x2 /* BIT 1 */ +#define ATUR_INTVL_LPR_FLAG 0x4 /* BIT 2 */ +#define ATUR_INTVL_ESS_FLAG 0x8 /* BIT 3 */ +#define ATUR_INTVL_VALID_DATA_FLAG 0x10 /* BIT 4 */ + +/* adslAtucChanPerfDataTable Flags */ +#define ATUC_CHAN_RECV_BLK_FLAG 0x01 /* BIT 0th position */ +#define ATUC_CHAN_TX_BLK_FLAG 0x02 /* BIT 1 */ +#define ATUC_CHAN_CORR_BLK_FLAG 0x04 /* BIT 2 */ +#define ATUC_CHAN_UNCORR_BLK_FLAG 0x08 /* BIT 3 */ +#define ATUC_CHAN_PERF_VALID_INTVL_FLAG 0x10 /* BIT 4 */ +#define ATUC_CHAN_PERF_INVALID_INTVL_FLAG 0x20 /* BIT 5 */ +#define ATUC_CHAN_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */ +#define ATUC_CHAN_PERF_CURR_15MIN_RECV_BLK_FLAG 0x80 /* BIT 7 */ +#define ATUC_CHAN_PERF_CURR_15MIN_TX_BLK_FLAG 0x100 /* BIT 8 */ +#define ATUC_CHAN_PERF_CURR_15MIN_CORR_BLK_FLAG 0x200 /* BIT 9 */ +#define ATUC_CHAN_PERF_CURR_15MIN_UNCORR_BLK_FLAG 0x400 /* BIT 10 */ +#define ATUC_CHAN_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11*/ +#define ATUC_CHAN_PERF_CURR_1DAY_RECV_BLK_FLAG 0x1000 /* BIT 12 */ +#define ATUC_CHAN_PERF_CURR_1DAY_TX_BLK_FLAG 0x2000 /* BIT 13 */ +#define ATUC_CHAN_PERF_CURR_1DAY_CORR_BLK_FLAG 0x4000 /* BIT 14 */ +#define ATUC_CHAN_PERF_CURR_1DAY_UNCORR_BLK_FLAG 0x8000 /* BIT 15 */ +#define ATUC_CHAN_PERF_PREV_1DAY_MONI_SEC_FLAG 0x10000 /* BIT 16 */ +#define ATUC_CHAN_PERF_PREV_1DAY_RECV_BLK_FLAG 0x20000 /* BIT 17 */ +#define ATUC_CHAN_PERF_PREV_1DAY_TX_BLK_FLAG 0x40000 /* BIT 18 */ +#define ATUC_CHAN_PERF_PREV_1DAY_CORR_BLK_FLAG 0x80000 /* BIT 19 */ +#define ATUC_CHAN_PERF_PREV_1DAY_UNCORR_BLK_FLAG 0x100000 /* BIT 20 */ + + +/* adslAturChanPerfDataTable Flags */ +#define ATUR_CHAN_RECV_BLK_FLAG 0x01 /* BIT 0th position */ +#define ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_LSW makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data) +#define ATUR_CHAN_RECV_BLK_FLAG_MAKECMV_MSW makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data) +#define ATUR_CHAN_TX_BLK_FLAG 0x02 /* BIT 1 */ +#define ATUR_CHAN_TX_BLK_FLAG_MAKECMV_LSW makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data) +#define ATUR_CHAN_TX_BLK_FLAG_MAKECMV_MSW makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data) +#define ATUR_CHAN_CORR_BLK_FLAG 0x04 /* BIT 2 */ +#define ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_INTL makeCMV(H2D_CMV_READ, PLAM, 3, 0, 1, data) +#define ATUR_CHAN_CORR_BLK_FLAG_MAKECMV_FAST makeCMV(H2D_CMV_READ, PLAM, 3, 1, 1, data) +#define ATUR_CHAN_UNCORR_BLK_FLAG 0x08 /* BIT 3 */ +#define ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_INTL makeCMV(H2D_CMV_READ, PLAM, 2, 0, 1, data) +#define ATUR_CHAN_UNCORR_BLK_FLAG_MAKECMV_FAST makeCMV(H2D_CMV_READ, PLAM, 2, 1, 1, data) +#define ATUR_CHAN_PERF_VALID_INTVL_FLAG 0x10 /* BIT 4 */ +#define ATUR_CHAN_PERF_INVALID_INTVL_FLAG 0x20 /* BIT 5 */ +#define ATUR_CHAN_PERF_CURR_15MIN_TIME_ELAPSED_FLAG 0x40 /* BIT 6 */ +#define ATUR_CHAN_PERF_CURR_15MIN_RECV_BLK_FLAG 0x80 /* BIT 7 */ +#define ATUR_CHAN_PERF_CURR_15MIN_TX_BLK_FLAG 0x100 /* BIT 8 */ +#define ATUR_CHAN_PERF_CURR_15MIN_CORR_BLK_FLAG 0x200 /* BIT 9 */ +#define ATUR_CHAN_PERF_CURR_15MIN_UNCORR_BLK_FLAG 0x400 /* BIT 10 */ +#define ATUR_CHAN_PERF_CURR_1DAY_TIME_ELAPSED_FLAG 0x800 /* BIT 11 */ +#define ATUR_CHAN_PERF_CURR_1DAY_RECV_BLK_FLAG 0x1000 /* BIT 12 */ +#define ATUR_CHAN_PERF_CURR_1DAY_TX_BLK_FLAG 0x2000 /* BIT 13 */ +#define ATUR_CHAN_PERF_CURR_1DAY_CORR_BLK_FLAG 0x4000 /* BIT 14 */ +#define ATUR_CHAN_PERF_CURR_1DAY_UNCORR_BLK_FLAG 0x8000 /* BIT 15 */ +#define ATUR_CHAN_PERF_PREV_1DAY_MONI_SEC_FLAG 0x10000 /* BIT 16 */ +#define ATUR_CHAN_PERF_PREV_1DAY_RECV_BLK_FLAG 0x20000 /* BIT 17 */ +#define ATUR_CHAN_PERF_PREV_1DAY_TRANS_BLK_FLAG 0x40000 /* BIT 18 */ +#define ATUR_CHAN_PERF_PREV_1DAY_CORR_BLK_FLAG 0x80000 /* BIT 19 */ +#define ATUR_CHAN_PERF_PREV_1DAY_UNCORR_BLK_FLAG 0x100000 /* BIT 20 */ + +/* adslAtucChanIntervalTable Flags */ +#define ATUC_CHAN_INTVL_NUM_FLAG 0x1 /* BIT 0th position */ +#define ATUC_CHAN_INTVL_RECV_BLK_FLAG 0x2 /* BIT 1 */ +#define ATUC_CHAN_INTVL_TX_BLK_FLAG 0x4 /* BIT 2 */ +#define ATUC_CHAN_INTVL_CORR_BLK_FLAG 0x8 /* BIT 3 */ +#define ATUC_CHAN_INTVL_UNCORR_BLK_FLAG 0x10 /* BIT 4 */ +#define ATUC_CHAN_INTVL_VALID_DATA_FLAG 0x20 /* BIT 5 */ + +/* adslAturChanIntervalTable Flags */ +#define ATUR_CHAN_INTVL_NUM_FLAG 0x1 /* BIT 0th Position */ +#define ATUR_CHAN_INTVL_RECV_BLK_FLAG 0x2 /* BIT 1 */ +#define ATUR_CHAN_INTVL_TX_BLK_FLAG 0x4 /* BIT 2 */ +#define ATUR_CHAN_INTVL_CORR_BLK_FLAG 0x8 /* BIT 3 */ +#define ATUR_CHAN_INTVL_UNCORR_BLK_FLAG 0x10 /* BIT 4 */ +#define ATUR_CHAN_INTVL_VALID_DATA_FLAG 0x20 /* BIT 5 */ + +/* adslLineAlarmConfProfileTable Flags */ +#define ATUC_THRESH_15MIN_LOFS_FLAG 0x01 /* BIT 0th position */ +#define ATUC_THRESH_15MIN_LOSS_FLAG 0x02 /* BIT 1 */ +#define ATUC_THRESH_15MIN_ESS_FLAG 0x04 /* BIT 2 */ +#define ATUC_THRESH_FAST_RATEUP_FLAG 0x08 /* BIT 3 */ +#define ATUC_THRESH_INTERLEAVE_RATEUP_FLAG 0x10 /* BIT 4 */ +#define ATUC_THRESH_FAST_RATEDOWN_FLAG 0x20 /* BIT 5 */ +#define ATUC_THRESH_INTERLEAVE_RATEDOWN_FLAG 0x40 /* BIT 6 */ +#define ATUC_INIT_FAILURE_TRAP_ENABLE_FLAG 0x80 /* BIT 7 */ +#define ATUR_THRESH_15MIN_LOFS_FLAG 0x100 /* BIT 8 */ +#define ATUR_THRESH_15MIN_LOSS_FLAG 0x200 /* BIT 9 */ +#define ATUR_THRESH_15MIN_LPRS_FLAG 0x400 /* BIT 10 */ +#define ATUR_THRESH_15MIN_ESS_FLAG 0x800 /* BIT 11 */ +#define ATUR_THRESH_FAST_RATEUP_FLAG 0x1000 /* BIT 12 */ +#define ATUR_THRESH_INTERLEAVE_RATEUP_FLAG 0x2000 /* BIT 13 */ +#define ATUR_THRESH_FAST_RATEDOWN_FLAG 0x4000 /* BIT 14 */ +#define ATUR_THRESH_INTERLEAVE_RATEDOWN_FLAG 0x8000 /* BIT 15 */ +#define LINE_ALARM_CONF_PROFILE_ROWSTATUS_FLAG 0x10000 /* BIT 16 */ + + +/* adslAturTraps Flags */ +#define ATUC_PERF_LOFS_THRESH_FLAG 0x1 /* BIT 0th position */ +#define ATUC_PERF_LOSS_THRESH_FLAG 0x2 /* BIT 1 */ +#define ATUC_PERF_ESS_THRESH_FLAG 0x4 /* BIT 2 */ +#define ATUC_RATE_CHANGE_FLAG 0x8 /* BIT 3 */ +#define ATUR_PERF_LOFS_THRESH_FLAG 0x10 /* BIT 4 */ +#define ATUR_PERF_LOSS_THRESH_FLAG 0x20 /* BIT 5 */ +#define ATUR_PERF_LPRS_THRESH_FLAG 0x40 /* BIT 6 */ +#define ATUR_PERF_ESS_THRESH_FLAG 0x80 /* BIT 7 */ +#define ATUR_RATE_CHANGE_FLAG 0x100 /* BIT 8 */ + +//RFC- 3440 FLAG DEFINITIONS + +#ifdef AMAZON_MEI_MIB_RFC3440 +/* adslLineExtTable flags */ +#define ATUC_LINE_TRANS_CAP_FLAG 0x1 /* BIT 0th position */ +#define ATUC_LINE_TRANS_CAP_FLAG_MAKECMV makeCMV(H2D_CMV_READ,INFO, 67, 0, 1, data) +#define ATUC_LINE_TRANS_CONFIG_FLAG 0x2 /* BIT 1 */ +#define ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV makeCMV(H2D_CMV_READ,INFO, 67, 0, 1, data) +#define ATUC_LINE_TRANS_CONFIG_FLAG_MAKECMV_WR makeCMV(H2D_CMV_WRITE,INFO, 67, 0, 1, data) +#define ATUC_LINE_TRANS_ACTUAL_FLAG 0x4 /* BIT 2 */ +#define ATUC_LINE_TRANS_ACTUAL_FLAG_MAKECMV makeCMV(H2D_CMV_READ,STAT, 1, 0, 1, data) +#define LINE_GLITE_POWER_STATE_FLAG 0x8 /* BIT 3 */ +#define LINE_GLITE_POWER_STATE_FLAG_MAKECMV makeCMV(H2D_CMV_READ,STAT, 0, 0, 1, data) + +/* adslAtucPerfDataExtTable flags */ +#define ATUC_PERF_STAT_FASTR_FLAG 0x1 /* BIT 0th position */ +#define ATUC_PERF_STAT_FASTR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data) +#define ATUC_PERF_STAT_FAILED_FASTR_FLAG 0x2 /* BIT 1 */ +#define ATUC_PERF_STAT_FAILED_FASTR_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data) +#define ATUC_PERF_STAT_SESL_FLAG 0X4 /* BIT 2 */ +#define ATUC_PERF_STAT_SESL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 8, 0, 1, data) +#define ATUC_PERF_STAT_UASL_FLAG 0X8 /* BIT 3 */ +#define ATUC_PERF_STAT_UASL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 10, 0, 1, data) +#define ATUC_PERF_CURR_15MIN_FASTR_FLAG 0X10 /* BIT 4 */ +#define ATUC_PERF_CURR_15MIN_FAILED_FASTR_FLAG 0X20 /* BIT 5 */ +#define ATUC_PERF_CURR_15MIN_SESL_FLAG 0X40 /* BIT 6 */ +#define ATUC_PERF_CURR_15MIN_UASL_FLAG 0X80 /* BIT 7 */ +#define ATUC_PERF_CURR_1DAY_FASTR_FLAG 0X100 /* BIT 8 */ +#define ATUC_PERF_CURR_1DAY_FAILED_FASTR_FLAG 0X200 /* BIT 9 */ +#define ATUC_PERF_CURR_1DAY_SESL_FLAG 0X400 /* BIT 10 */ +#define ATUC_PERF_CURR_1DAY_UASL_FLAG 0X800 /* BIT 11 */ +#define ATUC_PERF_PREV_1DAY_FASTR_FLAG 0X1000 /* BIT 12 */ +#define ATUC_PERF_PREV_1DAY_FAILED_FASTR_FLAG 0X2000 /* BIT 13 */ +#define ATUC_PERF_PREV_1DAY_SESL_FLAG 0X4000 /* BIT 14 */ +#define ATUC_PERF_PREV_1DAY_UASL_FLAG 0X8000 /* BIT 15 */ + +/* adslAturPerfDataExtTable */ +#define ATUR_PERF_STAT_SESL_FLAG 0X1 /* BIT 0th position */ +#define ATUR_PERF_STAT_SESL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 34, 0, 1, data) +#define ATUR_PERF_STAT_UASL_FLAG 0X2 /* BIT 1 */ +#define ATUR_PERF_STAT_UASL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 36, 0, 1, data) +#define ATUR_PERF_CURR_15MIN_SESL_FLAG 0X4 /* BIT 2 */ +#define ATUR_PERF_CURR_15MIN_UASL_FLAG 0X8 /* BIT 3 */ +#define ATUR_PERF_CURR_1DAY_SESL_FLAG 0X10 /* BIT 4 */ +#define ATUR_PERF_CURR_1DAY_UASL_FLAG 0X20 /* BIT 5 */ +#define ATUR_PERF_PREV_1DAY_SESL_FLAG 0X40 /* BIT 6 */ +#define ATUR_PERF_PREV_1DAY_UASL_FLAG 0X80 /* BIT 7 */ + +/* adslAutcIntervalExtTable flags */ +#define ATUC_INTERVAL_FASTR_FLAG 0x1 /* Bit 0 */ +#define ATUC_INTERVAL_FAILED_FASTR_FLAG 0x2 /* Bit 1 */ +#define ATUC_INTERVAL_SESL_FLAG 0x4 /* Bit 2 */ +#define ATUC_INTERVAL_UASL_FLAG 0x8 /* Bit 3 */ + +/* adslAturIntervalExtTable */ +#define ATUR_INTERVAL_SESL_FLAG 0X1 /* BIT 0th position */ +#define ATUR_INTERVAL_UASL_FLAG 0X2 /* BIT 1 */ + +/* adslAlarmConfProfileExtTable */ +#define ATUC_THRESH_15MIN_FAILED_FASTR_FLAG 0X1/* BIT 0th position */ +#define ATUC_THRESH_15MIN_SESL_FLAG 0X2 /* BIT 1 */ +#define ATUC_THRESH_15MIN_UASL_FLAG 0X4 /* BIT 2 */ +#define ATUR_THRESH_15MIN_SESL_FLAG 0X8 /* BIT 3 */ +#define ATUR_THRESH_15MIN_UASL_FLAG 0X10 /* BIT 4 */ + +/* adslAturExtTraps */ +#define ATUC_15MIN_FAILED_FASTR_TRAP_FLAG 0X1 /* BIT 0th position */ +#define ATUC_15MIN_SESL_TRAP_FLAG 0X2 /* BIT 1 */ +#define ATUC_15MIN_UASL_TRAP_FLAG 0X4 /* BIT 2 */ +#define ATUR_15MIN_SESL_TRAP_FLAG 0X8 /* BIT 3 */ +#define ATUR_15MIN_UASL_TRAP_FLAG 0X10 /* BIT 4 */ + +// 603221:tc.chen start +/* adslLineStatus Flags */ +#define LINE_STAT_MODEM_STATUS_FLAG 0x1 /* BIT 0th position */ +#define LINE_STAT_MODEM_STATUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 0, 0, 1, data) +#define LINE_STAT_MODE_SEL_FLAG 0x2 /* BIT 1 */ +#define LINE_STAT_MODE_SEL_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 1, 0, 1, data) +#define LINE_STAT_TRELLCOD_ENABLE_FLAG 0x4 /* BIT 2 */ +#define LINE_STAT_TRELLCOD_ENABLE_FLAG_MAKECMV makeCMV(H2D_CMV_READ, OPTN, 2, 0, 1, data) +#define LINE_STAT_LATENCY_FLAG 0x8 /* BIT 3 */ +#define LINE_STAT_LATENCY_FLAG_MAKECMV makeCMV(H2D_CMV_READ, STAT, 12, 0, 1, data) + +/* adslLineRate Flags */ +#define LINE_RATE_DATA_RATEDS_FLAG 0x1 /* BIT 0th position */ +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP0_MAKECMV makeCMV(H2D_CMV_READ, RATE, 1, 0, 2, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL1_LP1_MAKECMV makeCMV(H2D_CMV_READ, RATE, 1, 2, 2, data) + + +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 12, 0, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 13, 0, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 14, 0, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 15, 0, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 17, 0, 2, data) + +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_RP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 12, 1, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_MP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 13, 1, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_LP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 14, 1, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_TP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 15, 1, 1, data) +#define LINE_RATE_DATA_RATEDS_FLAG_ADSL2_KP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 17, 2, 2, data) + +#define LINE_RATE_DATA_RATEUS_FLAG 0x2 /* BIT 1 */ +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP0_MAKECMV makeCMV(H2D_CMV_READ, RATE, 0, 0, 2, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL1_LP1_MAKECMV makeCMV(H2D_CMV_READ, RATE, 0, 2, 2, data) + + +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 23, 0, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 24, 0, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 25, 0, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 26, 0, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 28, 0, 2, data) + +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_RP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 23, 1, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_MP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 24, 1, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_LP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 25, 1, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_TP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 26, 1, 1, data) +#define LINE_RATE_DATA_RATEUS_FLAG_ADSL2_KP_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 28, 2, 2, data) + +#define LINE_RATE_ATTNDRDS_FLAG 0x4 /* BIT 2 */ +#define LINE_RATE_ATTNDRDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 4, 2, data) + +#define LINE_RATE_ATTNDRUS_FLAG 0x8 /* BIT 3 */ +#define LINE_RATE_ATTNDRUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 4, 2, data) + +/* adslLineInformation Flags */ +#define LINE_INFO_INTLV_DEPTHDS_FLAG 0x1 /* BIT 0th position */ +#define LINE_INFO_INTLV_DEPTHDS_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 27, 0, 1, data) +#define LINE_INFO_INTLV_DEPTHDS_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 27, 1, 1, data) +#define LINE_INFO_INTLV_DEPTHUS_FLAG 0x2 /* BIT 1 */ +#define LINE_INFO_INTLV_DEPTHUS_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 16, 0, 1, data) +#define LINE_INFO_INTLV_DEPTHUS_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, CNFG, 16, 1, 1, data) +#define LINE_INFO_LATNDS_FLAG 0x4 /* BIT 2 */ +#define LINE_INFO_LATNDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 1, 1, data) +#define LINE_INFO_LATNUS_FLAG 0x8 /* BIT 3 */ +#define LINE_INFO_LATNUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 1, 1, data) +#define LINE_INFO_SATNDS_FLAG 0x10 /* BIT 4 */ +#define LINE_INFO_SATNDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 2, 1, data) +#define LINE_INFO_SATNUS_FLAG 0x20 /* BIT 5 */ +#define LINE_INFO_SATNUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 2, 1, data) +#define LINE_INFO_SNRMNDS_FLAG 0x40 /* BIT 6 */ +#define LINE_INFO_SNRMNDS_FLAG_ADSL1_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 3, 1, data) +#define LINE_INFO_SNRMNDS_FLAG_ADSL2_MAKECMV makeCMV(H2D_CMV_READ, RATE, 3, 0, 1, data) +#define LINE_INFO_SNRMNDS_FLAG_ADSL2PLUS_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 46, 0, 1, data) +#define LINE_INFO_SNRMNUS_FLAG 0x80 /* BIT 7 */ +#define LINE_INFO_SNRMNUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 3, 1, data) +#define LINE_INFO_ACATPDS_FLAG 0x100 /* BIT 8 */ +#define LINE_INFO_ACATPDS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 68, 6, 1, data) +#define LINE_INFO_ACATPUS_FLAG 0x200 /* BIT 9 */ +#define LINE_INFO_ACATPUS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, INFO, 69, 6, 1, data) + +/* adslNearEndPerformanceStats Flags */ +#define NEAREND_PERF_SUPERFRAME_FLAG_LSW_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 20, 0, 1, data) +#define NEAREND_PERF_SUPERFRAME_FLAG_MSW_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 21, 0, 1, data) +#define NEAREND_PERF_SUPERFRAME_FLAG 0x1 /* BIT 0th position */ +#define NEAREND_PERF_LOS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 0, 0, 1, data) +#define NEAREND_PERF_LOS_FLAG 0x2 /* BIT 1 */ +#define NEAREND_PERF_LOF_FLAG 0x4 /* BIT 2 */ +#define NEAREND_PERF_LPR_FLAG 0x8 /* BIT 3 */ +#define NEAREND_PERF_NCD_FLAG 0x10 /* BIT 4 */ +#define NEAREND_PERF_LCD_FLAG 0x20 /* BIT 5 */ +#define NEAREND_PERF_CRC_FLAG 0x40 /* BIT 6 */ +#define NEAREND_PERF_CRC_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 2, 0, 1, data) +#define NEAREND_PERF_CRC_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 2, 1, 1, data) +#define NEAREND_PERF_RSCORR_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 3, 0, 1, data) +#define NEAREND_PERF_RSCORR_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 3, 1, 1, data) +#define NEAREND_PERF_RSCORR_FLAG 0x80 /* BIT 7 */ +#define NEAREND_PERF_FECS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 6, 0, 1, data) +#define NEAREND_PERF_FECS_FLAG 0x100 /* BIT 8 */ +#define NEAREND_PERF_ES_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 7, 0, 1, data) +#define NEAREND_PERF_ES_FLAG 0x200 /* BIT 9 */ +#define NEAREND_PERF_SES_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 8, 0, 1, data) +#define NEAREND_PERF_SES_FLAG 0x400 /* BIT 10 */ +#define NEAREND_PERF_LOSS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 9, 0, 1, data) +#define NEAREND_PERF_LOSS_FLAG 0x800 /* BIT 11 */ +#define NEAREND_PERF_UAS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 10, 0, 1, data) +#define NEAREND_PERF_UAS_FLAG 0x1000 /* BIT 12 */ +#define NEAREND_PERF_HECERR_FLAG_BC0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 11, 0, 2, data) +#define NEAREND_PERF_HECERR_FLAG_BC1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 11, 2, 2, data) +#define NEAREND_PERF_HECERR_FLAG 0x2000 /* BIT 13 */ + +/* adslFarEndPerformanceStats Flags */ +#define FAREND_PERF_LOS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 1, 0, 1, data) +#define FAREND_PERF_LOS_FLAG 0x1 /* BIT 0th position */ +#define FAREND_PERF_LOF_FLAG 0x2 /* BIT 1 */ +#define FAREND_PERF_LPR_FLAG 0x4 /* BIT 2 */ +#define FAREND_PERF_NCD_FLAG 0x8 /* BIT 3 */ +#define FAREND_PERF_LCD_FLAG 0x10 /* BIT 4 */ +#define FAREND_PERF_CRC_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 24, 0, 1, data) +#define FAREND_PERF_CRC_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 24, 1, 1, data) +#define FAREND_PERF_CRC_FLAG 0x20 /* BIT 5 */ +#define FAREND_PERF_RSCORR_FLAG_LP0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 28, 0, 1, data) +#define FAREND_PERF_RSCORR_FLAG_LP1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 28, 1, 1, data) +#define FAREND_PERF_RSCORR_FLAG 0x40 /* BIT 6 */ +#define FAREND_PERF_FECS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 32, 0, 1, data) +#define FAREND_PERF_FECS_FLAG 0x80 /* BIT 7 */ +#define FAREND_PERF_ES_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 33, 0, 1, data) +#define FAREND_PERF_ES_FLAG 0x100 /* BIT 8 */ +#define FAREND_PERF_SES_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 34, 0, 1, data) +#define FAREND_PERF_SES_FLAG 0x200 /* BIT 9 */ +#define FAREND_PERF_LOSS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 35, 0, 1, data) +#define FAREND_PERF_LOSS_FLAG 0x400 /* BIT 10 */ +#define FAREND_PERF_UAS_FLAG_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 36, 0, 1, data) +#define FAREND_PERF_UAS_FLAG 0x800 /* BIT 11 */ +#define FAREND_PERF_HECERR_FLAG_BC0_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 37, 0, 2, data) +#define FAREND_PERF_HECERR_FLAG_BC1_MAKECMV makeCMV(H2D_CMV_READ, PLAM, 37, 2, 2, data) +#define FAREND_PERF_HECERR_FLAG 0x1000 /* BIT 12 */ +// 603221:tc.chen end +/* TR-69 related additional parameters - defines */ +/* Defines for struct adslATURSubcarrierInfo */ +#define NEAREND_HLINSC 0x1 +#define NEAREND_HLINSC_MAKECMV(mode) makeCMV(mode, INFO, 71, 2, 1, data) +#define NEAREND_HLINPS 0x2 +#define NEAREND_HLINPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 73, idx, size, data) +#define NEAREND_HLOGMT 0x4 +#define NEAREND_HLOGMT_MAKECMV(mode) makeCMV(mode, INFO, 80, 0, 1, data) +#define NEAREND_HLOGPS 0x8 +#define NEAREND_HLOGPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 75, idx, size, data) +#define NEAREND_QLNMT 0x10 +#define NEAREND_QLNMT_MAKECMV(mode) makeCMV(mode, INFO, 80, 1, 1, data) +#define NEAREND_QLNPS 0x20 +#define NEAREND_QLNPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 77, idx, size, data) +#define NEAREND_SNRMT 0x40 +#define NEAREND_SNRMT_MAKECMV(mode) makeCMV(mode, INFO, 80, 2, 1, data) +#define NEAREND_SNRPS 0x80 +#define NEAREND_SNRPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 78, idx, size, data) +#define NEAREND_BITPS 0x100 +#define NEAREND_BITPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 22, idx, size, data) +#define NEAREND_GAINPS 0x200 +#define NEAREND_GAINPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 24, idx, size, data) + +/* Defines for struct adslATUCSubcarrierInfo */ +#define FAREND_HLINSC 0x1 +#define FAREND_HLINSC_MAKECMV(mode) makeCMV(mode, INFO, 70, 0, 1, data) +#define FAREND_HLINPS 0x2 +#define FAREND_HLINPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 72, idx, size, data) +#define FAREND_HLOGMT 0x4 +#define FAREND_HLOGMT_MAKECMV(mode) makeCMV(mode, INFO, 79, 0, 1, data) +#define FAREND_HLOGPS 0x8 +#define FAREND_HLOGPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 74, idx, size, data) +#define FAREND_QLNMT 0x10 +#define FAREND_QLNMT_MAKECMV(mode) makeCMV(mode, INFO, 79, 1, 1, data) +#define FAREND_QLNPS 0x20 +#define FAREND_QLNPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 76, idx, size, data) +#define FAREND_SNRMT 0x40 +#define FAREND_SNRMT_MAKECMV(mode) makeCMV(mode, INFO, 79, 2, 1, data) +#define FAREND_SNRPS 0x80 +#define FAREND_SNRPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 10, idx, size, data) +#define FAREND_BITPS 0x100 +#define FAREND_BITPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 23, idx, size, data) +#define FAREND_GAINPS 0x200 +#define FAREND_GAINPS_MAKECMV(mode,idx,size) makeCMV(mode, INFO, 25, idx, size, data) + + +// GET_ADSL_POWER_SPECTRAL_DENSITY +#define NOMPSD_US_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 0, 1, data) +#define NOMPSD_DS_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 1, 1, data) +#define PCB_US_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 6, 1, data) +#define PCB_DS_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 7, 1, data) +#define RMSGI_US_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 10, 1, data) +#define RMSGI_DS_MAKECMV makeCMV(H2D_CMV_READ, INFO, 102, 11, 1, data) + + +#endif +/////////////////////////////////////////////////Macro Definitions ? FLAG Setting & Testing + +#define SET_FLAG(flags, flag_val) ((*flags) = ((*flags) | flag_val)) +// -- This macro sets the flags with the flag_val. Here flags is passed as a pointer + +#define IS_FLAG_SET(flags, test_flag) (((*flags) & (test_flag)) == (test_flag)? test_flag:0) +// -- This macro verifies whether test_flag has been set in flags. Here flags is passed as a pointer + + +#define CLR_FLAG(flags, flag_bit) ((*flags) = (*flags) & (~flag_bit)) +// -- This macro resets the specified flag_bit in the flags. Here flags is passed as a pointer + + +////////////////////////////////////////////////DATA STRUCTURES ORGANIZATION + +//Here are the data structures used for accessing mib parameters. The ioctl call includes the third parameter as a void pointer. This parameter has to be type-casted in the driver code to the corresponding structure depending upon the command type. For Ex: consider the ioctl used to get the adslLineCode type, ioctl(fd,GET_ADSL_LINE_CODE,void *struct_adslLineTableEntry). In the driver code we check on the type of the command, i.e GET_ADSL_LINE_CODE and type-cast the void pointer to struct adslLineTableEntry type. + // +#define u32 unsigned int +#define u16 unsigned short +#define s16 short +#define u8 unsigned char + + +typedef u32 AdslPerfTimeElapsed; +typedef u32 AdslPerfPrevDayCount; +typedef u32 PerfCurrentCount; +typedef u32 PerfIntervalCount; +typedef u32 AdslPerfCurrDayCount; + + +//ioctl(int fd, GET_ADSL_LINE_CODE, void *struct_adslLineTableEntry) + +typedef struct adslLineTableEntry { + int ifIndex; + int adslLineCode; + u8 flags; +} adslLineTableEntry; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct adslLineExtTableEntry { + int ifIndex; + u16 adslLineTransAtucCap; + u16 adslLineTransAtucConfig; + u16 adslLineTransAtucActual; + int adslLineGlitePowerState; + u32 flags; +}adslLineExtTableEntry; +#endif +//ioctl(int fd, GET_ADSL_ATUC_PHY, void *struct_adslAtucPhysEntry) + +typedef struct adslVendorId { + u16 country_code; + u_char provider_id[4]; /* Ascii characters */ + u_char revision_info[2]; +}adslVendorId; + + +typedef struct adslAtucPhysEntry { + int ifIndex; + char serial_no[32]; + union { + char vendor_id[16]; + adslVendorId vendor_info; + } vendor_id; + + char version_no[16]; + u32 status; + int outputPwr; + u32 attainableRate; + u8 flags; +} adslAtucPhysEntry; + + +//ioctl(int fd, GET_ADSL_ATUR_PHY, void *struct_adslAturPhysEntry) + +typedef struct adslAturPhysEntry { + int ifIndex; + char serial_no[32]; + union { + char vendor_id[16]; + adslVendorId vendor_info; + } vendor_id; + char version_no[16]; + int SnrMgn; + u32 Attn; + u32 status; + int outputPwr; + u32 attainableRate; + u8 flags; +} adslAturPhysEntry; + + +//ioctl(int fd, GET_ADSL_ATUC_CHAN_INFO, void *struct_adslAtucChanInfo) + +typedef struct adslAtucChanInfo { + int ifIndex; + u32 interleaveDelay; + u32 currTxRate; + u32 prevTxRate; + u8 flags; +} adslAtucChanInfo; + + +//ioctl(int fd, GET_ADSL_ATUR_CHAN_INFO, void *struct_adslAturChanInfo) + +typedef struct adslAturChanInfo { + int ifIndex; + u32 interleaveDelay; + u32 currTxRate; + u32 prevTxRate; + u32 crcBlkLen; + u8 flags; +} adslAturChanInfo; + + +//ioctl(int fd, GET_ADSL_ATUC_PERF_DATA, void *struct_atucPerfDataEntry) + +typedef struct atucPerfDataEntry +{ + int ifIndex; + u32 adslAtucPerfLofs; + u32 adslAtucPerfLoss; + u32 adslAtucPerfESs; + u32 adslAtucPerfInits; + int adslAtucPerfValidIntervals; + int adslAtucPerfInvalidIntervals; + AdslPerfTimeElapsed adslAtucPerfCurr15MinTimeElapsed; + PerfCurrentCount adslAtucPerfCurr15MinLofs; + PerfCurrentCount adslAtucPerfCurr15MinLoss; + PerfCurrentCount adslAtucPerfCurr15MinESs; + PerfCurrentCount adslAtucPerfCurr15MinInits; + AdslPerfTimeElapsed adslAtucPerfCurr1DayTimeElapsed; + AdslPerfCurrDayCount adslAtucPerfCurr1DayLofs; + AdslPerfCurrDayCount adslAtucPerfCurr1DayLoss; + AdslPerfCurrDayCount adslAtucPerfCurr1DayESs; + AdslPerfCurrDayCount adslAtucPerfCurr1DayInits; + int adslAtucPerfPrev1DayMoniSecs; + AdslPerfPrevDayCount adslAtucPerfPrev1DayLofs; + AdslPerfPrevDayCount adslAtucPerfPrev1DayLoss; + AdslPerfPrevDayCount adslAtucPerfPrev1DayESs; + AdslPerfPrevDayCount adslAtucPerfPrev1DayInits; + u32 flags; +} atucPerfDataEntry; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct atucPerfDataExtEntry + { + int ifIndex; + u32 adslAtucPerfStatFastR; + u32 adslAtucPerfStatFailedFastR; + u32 adslAtucPerfStatSesL; + u32 adslAtucPerfStatUasL; + u32 adslAtucPerfCurr15MinFastR; + u32 adslAtucPerfCurr15MinFailedFastR; + u32 adslAtucPerfCurr15MinSesL; + u32 adslAtucPerfCurr15MinUasL; + u32 adslAtucPerfCurr1DayFastR; + u32 adslAtucPerfCurr1DayFailedFastR; + u32 adslAtucPerfCurr1DaySesL; + u32 adslAtucPerfCurr1DayUasL; + u32 adslAtucPerfPrev1DayFastR; + u32 adslAtucPerfPrev1DayFailedFastR; + u32 adslAtucPerfPrev1DaySesL; + u32 adslAtucPerfPrev1DayUasL; + u32 flags; +} atucPerfDataExtEntry; + +#endif +//ioctl(int fd, GET_ADSL_ATUR_PERF_DATA, void *struct_aturPerfDataEntry) + +typedef struct aturPerfDataEntry +{ + int ifIndex; + u32 adslAturPerfLofs; + u32 adslAturPerfLoss; + u32 adslAturPerfLprs; + u32 adslAturPerfESs; + int adslAturPerfValidIntervals; + int adslAturPerfInvalidIntervals; + AdslPerfTimeElapsed adslAturPerfCurr15MinTimeElapsed; + PerfCurrentCount adslAturPerfCurr15MinLofs; + PerfCurrentCount adslAturPerfCurr15MinLoss; + PerfCurrentCount adslAturPerfCurr15MinLprs; + PerfCurrentCount adslAturPerfCurr15MinESs; + AdslPerfTimeElapsed adslAturPerfCurr1DayTimeElapsed; + AdslPerfCurrDayCount adslAturPerfCurr1DayLofs; + AdslPerfCurrDayCount adslAturPerfCurr1DayLoss; + AdslPerfCurrDayCount adslAturPerfCurr1DayLprs; + AdslPerfCurrDayCount adslAturPerfCurr1DayESs; + int adslAturPerfPrev1DayMoniSecs; + AdslPerfPrevDayCount adslAturPerfPrev1DayLofs; + AdslPerfPrevDayCount adslAturPerfPrev1DayLoss; + AdslPerfPrevDayCount adslAturPerfPrev1DayLprs; + AdslPerfPrevDayCount adslAturPerfPrev1DayESs; + u32 flags; +} aturPerfDataEntry; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct aturPerfDataExtEntry + { + int ifIndex; + u32 adslAturPerfStatSesL; + u32 adslAturPerfStatUasL; + u32 adslAturPerfCurr15MinSesL; + u32 adslAturPerfCurr15MinUasL; + u32 adslAturPerfCurr1DaySesL; + u32 adslAturPerfCurr1DayUasL; + u32 adslAturPerfPrev1DaySesL; + u32 adslAturPerfPrev1DayUasL; + u32 flags; +} aturPerfDataExtEntry; +#endif +//ioctl(int fd, GET_ADSL_ATUC_INTVL_INFO, void *struct_adslAtucInvtInfo) + +typedef struct adslAtucIntvlInfo { + int ifIndex; + int IntervalNumber; + PerfIntervalCount intervalLOF; + PerfIntervalCount intervalLOS; + PerfIntervalCount intervalES; + PerfIntervalCount intervalInits; + int intervalValidData; + u8 flags; +} adslAtucIntvlInfo; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct adslAtucInvtlExtInfo + { + int ifIndex; + int IntervalNumber; + u32 adslAtucIntervalFastR; + u32 adslAtucIntervalFailedFastR; + u32 adslAtucIntervalSesL; + u32 adslAtucIntervalUasL; + u32 flags; +} adslAtucInvtlExtInfo; +#endif +//ioctl(int fd, GET_ADSL_ATUR_INTVL_INFO, void *struct_adslAturInvtlInfo) + +typedef struct adslAturIntvlInfo { + int ifIndex; + int IntervalNumber; + PerfIntervalCount intervalLOF; + PerfIntervalCount intervalLOS; + PerfIntervalCount intervalLPR; + PerfIntervalCount intervalES; + int intervalValidData; + u8 flags; +} adslAturIntvlInfo; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct adslAturInvtlExtInfo + { + int ifIndex; + int IntervalNumber; + u32 adslAturIntervalSesL; + u32 adslAturIntervalUasL; + u32 flags; +} adslAturInvtlExtInfo; +#endif +//ioctl(int fd, GET_ADSL_ATUC_CHAN_PERF_DATA, void *struct_atucChannelPerfDataEntry) + +typedef struct atucChannelPerfDataEntry +{ + int ifIndex; + u32 adslAtucChanReceivedBlks; + u32 adslAtucChanTransmittedBlks; + u32 adslAtucChanCorrectedBlks; + u32 adslAtucChanUncorrectBlks; + int adslAtucChanPerfValidIntervals; + int adslAtucChanPerfInvalidIntervals; + AdslPerfTimeElapsed adslAtucChanPerfCurr15MinTimeElapsed; + PerfCurrentCount adslAtucChanPerfCurr15MinReceivedBlks; + PerfCurrentCount adslAtucChanPerfCurr15MinTransmittedBlks; + PerfCurrentCount adslAtucChanPerfCurr15MinCorrectedBlks; + PerfCurrentCount adslAtucChanPerfCurr15MinUncorrectBlks; + AdslPerfTimeElapsed adslAtucChanPerfCurr1DayTimeElapsed; + AdslPerfCurrDayCount adslAtucChanPerfCurr1DayReceivedBlks; + AdslPerfCurrDayCount adslAtucChanPerfCurr1DayTransmittedBlks; + AdslPerfCurrDayCount adslAtucChanPerfCurr1DayCorrectedBlks; + AdslPerfCurrDayCount adslAtucChanPerfCurr1DayUncorrectBlks; + int adslAtucChanPerfPrev1DayMoniSecs; + AdslPerfPrevDayCount adslAtucChanPerfPrev1DayReceivedBlks; + AdslPerfPrevDayCount adslAtucChanPerfPrev1DayTransmittedBlks; + AdslPerfPrevDayCount adslAtucChanPerfPrev1DayCorrectedBlks; + AdslPerfPrevDayCount adslAtucChanPerfPrev1DayUncorrectBlks; + u32 flags; +}atucChannelPerfDataEntry; + + +//ioctl(int fd, GET_ADSL_ATUR_CHAN_PERF_DATA, void *struct_aturChannelPerfDataEntry) + +typedef struct aturChannelPerfDataEntry +{ + int ifIndex; + u32 adslAturChanReceivedBlks; + u32 adslAturChanTransmittedBlks; + u32 adslAturChanCorrectedBlks; + u32 adslAturChanUncorrectBlks; + int adslAturChanPerfValidIntervals; + int adslAturChanPerfInvalidIntervals; + AdslPerfTimeElapsed adslAturChanPerfCurr15MinTimeElapsed; + PerfCurrentCount adslAturChanPerfCurr15MinReceivedBlks; + PerfCurrentCount adslAturChanPerfCurr15MinTransmittedBlks; + PerfCurrentCount adslAturChanPerfCurr15MinCorrectedBlks; + PerfCurrentCount adslAturChanPerfCurr15MinUncorrectBlks; + AdslPerfTimeElapsed adslAturChanPerfCurr1DayTimeElapsed; + AdslPerfCurrDayCount adslAturChanPerfCurr1DayReceivedBlks; + AdslPerfCurrDayCount adslAturChanPerfCurr1DayTransmittedBlks; + AdslPerfCurrDayCount adslAturChanPerfCurr1DayCorrectedBlks; + AdslPerfCurrDayCount adslAturChanPerfCurr1DayUncorrectBlks; + int adslAturChanPerfPrev1DayMoniSecs; + AdslPerfPrevDayCount adslAturChanPerfPrev1DayReceivedBlks; + AdslPerfPrevDayCount adslAturChanPerfPrev1DayTransmittedBlks; + AdslPerfPrevDayCount adslAturChanPerfPrev1DayCorrectedBlks; + AdslPerfPrevDayCount adslAturChanPerfPrev1DayUncorrectBlks; + u32 flags; +} aturChannelPerfDataEntry; + + +//ioctl(int fd, GET_ADSL_ATUC_CHAN_INTVL_INFO, void *struct_adslAtucChanIntvlInfo) + +typedef struct adslAtucChanIntvlInfo { + int ifIndex; + int IntervalNumber; + PerfIntervalCount chanIntervalRecvdBlks; + PerfIntervalCount chanIntervalXmitBlks; + PerfIntervalCount chanIntervalCorrectedBlks; + PerfIntervalCount chanIntervalUncorrectBlks; + int intervalValidData; + u8 flags; +} adslAtucChanIntvlInfo; + + +//ioctl(int fd, GET_ADSL_ATUR_CHAN_INTVL_INFO, void *struct_adslAturChanIntvlInfo) + +typedef struct adslAturChanIntvlInfo { + int ifIndex; + int IntervalNumber; + PerfIntervalCount chanIntervalRecvdBlks; + PerfIntervalCount chanIntervalXmitBlks; + PerfIntervalCount chanIntervalCorrectedBlks; + PerfIntervalCount chanIntervalUncorrectBlks; + int intervalValidData; + u8 flags; +} adslAturChanIntvlInfo; + + +//ioctl(int fd, GET_ADSL_ALRM_CONF_PROF, void *struct_adslLineAlarmConfProfileEntry) +//ioctl(int fd, SET_ADSL_ALRM_CONF_PROF, void *struct_adslLineAlarmConfProfileEntry) + +typedef struct adslLineAlarmConfProfileEntry + { + unsigned char adslLineAlarmConfProfileName[32]; + int adslAtucThresh15MinLofs; + int adslAtucThresh15MinLoss; + int adslAtucThresh15MinESs; + u32 adslAtucThreshFastRateUp; + u32 adslAtucThreshInterleaveRateUp; + u32 adslAtucThreshFastRateDown; + u32 adslAtucThreshInterleaveRateDown; + int adslAtucInitFailureTrapEnable; + int adslAturThresh15MinLofs; + int adslAturThresh15MinLoss; + int adslAturThresh15MinLprs; + int adslAturThresh15MinESs; + u32 adslAturThreshFastRateUp; + u32 adslAturThreshInterleaveRateUp; + u32 adslAturThreshFastRateDown; + u32 adslAturThreshInterleaveRateDown; + int adslLineAlarmConfProfileRowStatus; + u32 flags; +} adslLineAlarmConfProfileEntry; + +#ifdef AMAZON_MEI_MIB_RFC3440 +typedef struct adslLineAlarmConfProfileExtEntry + { + u8 adslLineAlarmConfProfileExtName[32]; + u32 adslAtucThreshold15MinFailedFastR; + u32 adslAtucThreshold15MinSesL; + u32 adslAtucThreshold15MinUasL; + u32 adslAturThreshold15MinSesL; + u32 adslAturThreshold15MinUasL; + u32 flags; +} adslLineAlarmConfProfileExtEntry; +#endif +//TRAPS + +// 603221:tc.chen start +/* The following Data Sturctures are added to support the WEB related parameters for ADSL Statistics */ +typedef struct adslLineStatus + { + int adslModemStatus; + u32 adslModeSelected; + int adslAtucThresh15MinESs; + int adslTrellisCodeEnable; + int adslLatency; + u8 flags; + } adslLineStatusInfo; + +typedef struct adslLineRate + { + u32 adslDataRateds; + u32 adslDataRateus; + u32 adslATTNDRds; + u32 adslATTNDRus; + u8 flags; + } adslLineRateInfo; + +typedef struct adslLineInfo + { + u32 adslInterleaveDepthds; + u32 adslInterleaveDepthus; + u32 adslLATNds; + u32 adslLATNus; + u32 adslSATNds; + u32 adslSATNus; + int adslSNRMds; + int adslSNRMus; + int adslACATPds; + int adslACATPus; + u32 flags; + } adslLineInfo; + +typedef struct adslNearEndPerfStats + { + u32 adslSuperFrames; + u32 adslneLOS; + u32 adslneLOF; + u32 adslneLPR; + u32 adslneNCD; + u32 adslneLCD; + u32 adslneCRC; + u32 adslneRSCorr; + u32 adslneFECS; + u32 adslneES; + u32 adslneSES; + u32 adslneLOSS; + u32 adslneUAS; + u32 adslneHECErrors; + u32 flags; + } adslNearEndPerfStats; + +typedef struct adslFarEndPerfStats + { + u32 adslfeLOS; + u32 adslfeLOF; + u32 adslfeLPR; + u32 adslfeNCD; + u32 adslfeLCD; + u32 adslfeCRC; + u32 adslfeRSCorr; + u32 adslfeFECS; + u32 adslfeES; + u32 adslfeSES; + u32 adslfeLOSS; + u32 adslfeUAS; + u32 adslfeHECErrors; + u32 flags; + } adslFarEndPerfStats; +// 603221:tc.chen end + +/* The number of tones (and hence indexes) is dependent on the ADSL mode - G.992.1, G.992.2, G.992.3, * G.992.4 and G.992.5 */ +typedef struct adslATURSubcarrierInfo { + int ifindex; + u16 HLINSCds; + u16 HLINpsds[1024];/* Even index = real part; Odd Index + = imaginary part for each tone */ + u16 HLOGMTds; + u16 HLOGpsds[512]; + u16 QLNMTds; + u16 QLNpsds[512]; + u16 SNRMTds; + u16 SNRpsds[512]; + u16 BITpsds[512]; + u16 GAINpsds[512]; + u16 flags; +}adslATURSubcarrierInfo; + +typedef struct adslATUCSubcarrierInfo { + int ifindex; + u16 HLINSCus; + u16 HLINpsus[128];/* Even index = real part; Odd Index + = imaginary part for each tone */ + u16 HLOGMTus; + u16 HLOGpsus[64]; + u16 QLNMTus; + u16 QLNpsus[64]; + u16 SNRMTus; + u16 SNRpsus[64]; + u16 BITpsus[64]; + u16 GAINpsus[64]; + u16 flags; +}adslATUCSubcarrierInfo; + +#ifndef u_int16 +#define u_int16 u16 +#endif + +typedef struct adslInitStats { + u_int16 FullInitializationCount; + u_int16 FailedFullInitializationCount; + u_int16 LINIT_Errors; + u_int16 Init_Timeouts; +}adslInitStats; + +typedef struct adslPowerSpectralDensity { + int ACTPSDds; + int ACTPSDus; +}adslPowerSpectralDensity; + + +//ioctl(int fd, ADSL_ATUR_TRAPS, void *uint16_flags) +typedef union structpts { + adslLineTableEntry * adslLineTableEntry_pt; + adslAtucPhysEntry * adslAtucPhysEntry_pt; + adslAturPhysEntry * adslAturPhysEntry_pt; + adslAtucChanInfo * adslAtucChanInfo_pt; + adslAturChanInfo * adslAturChanInfo_pt; + atucPerfDataEntry * atucPerfDataEntry_pt; + aturPerfDataEntry * aturPerfDataEntry_pt; + adslAtucIntvlInfo * adslAtucIntvlInfo_pt; + adslAturIntvlInfo * adslAturIntvlInfo_pt; + atucChannelPerfDataEntry * atucChannelPerfDataEntry_pt; + aturChannelPerfDataEntry * aturChannelPerfDataEntry_pt; + adslAtucChanIntvlInfo * adslAtucChanIntvlInfo_pt; + adslAturChanIntvlInfo * adslAturChanIntvlInfo_pt; + adslLineAlarmConfProfileEntry * adslLineAlarmConfProfileEntry_pt; + // RFC 3440 + + #ifdef AMAZON_MEI_MIB_RFC3440 + adslLineExtTableEntry * adslLineExtTableEntry_pt; + atucPerfDataExtEntry * atucPerfDataExtEntry_pt; + adslAtucInvtlExtInfo * adslAtucInvtlExtInfo_pt; + aturPerfDataExtEntry * aturPerfDataExtEntry_pt; + adslAturInvtlExtInfo * adslAturInvtlExtInfo_pt; + adslLineAlarmConfProfileExtEntry * adslLineAlarmConfProfileExtEntry_pt; + #endif +// 603221:tc.chen start + adslLineStatusInfo * adslLineStatusInfo_pt; + adslLineRateInfo * adslLineRateInfo_pt; + adslLineInfo * adslLineInfo_pt; + adslNearEndPerfStats * adslNearEndPerfStats_pt; + adslFarEndPerfStats * adslFarEndPerfStats_pt; +// 603221:tc.chen end + adslATUCSubcarrierInfo * adslATUCSubcarrierInfo_pt; + adslATURSubcarrierInfo * adslATURSubcarrierInfo_pt; + adslPowerSpectralDensity * adslPowerSpectralDensity_pt; +}structpts; + +#endif /* ] __AMAZON_MEI_APP_IOCTL_H */ diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_ioctl.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_ioctl.h new file mode 100644 index 0000000000..02a150eac4 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_mei_ioctl.h @@ -0,0 +1,757 @@ +//509221:tc.chen 2005/09/22 Reset DFE added when MEI_TO_ARC_CS_DONE not cleared by ARC and Added AMAZON_MEI_DEBUG_MODE ioctl +#ifndef _AMAZON_MEI_IOCTL_H +#define _AMAZON_MEI_IOCTL_H + +///////////////////////////////////////////////////////////////////////////////////////////////////// +#define PCM_BUFF_SIZE 1024 //bytes +// interrupt numbers + +#ifndef _AMAZON_ADSL_APP + +typedef struct pcm_data_struct{ + u16 S; + u16 temp; + u16 LSW; + u16 MSW; + u16 len; + u16 rdindex; + u16 wrindex; + u16 flow; + + int finish; + u8 buff[PCM_BUFF_SIZE]; + int point; +}pcm_data_struct; + +typedef struct amazon_clreoc_pkt{ + struct list_head list; + u8 * command; //point to clreoc command data + int len; //command length +}amazon_clreoc_pkt; + +// Number of intervals +#define INTERVAL_NUM 192 //two days +typedef struct amazon_mei_mib{ + struct list_head list; + struct timeval start_time; //start of current interval + + int AtucPerfLof; + int AtucPerfLos; + int AtucPerfEs; + int AtucPerfInit; + + int AturPerfLof; + int AturPerfLos; + int AturPerfLpr; + int AturPerfEs; + + int AturChanPerfRxBlk; + int AturChanPerfTxBlk; + int AturChanPerfCorrBlk; + int AturChanPerfUncorrBlk; + + //RFC-3440 + int AtucPerfStatFastR; + int AtucPerfStatFailedFastR; + int AtucPerfStatSesL; + int AtucPerfStatUasL; + int AturPerfStatSesL; + int AturPerfStatUasL; +}amazon_mei_mib; + +typedef struct adslChanPrevTxRate{ + u32 adslAtucChanPrevTxRate; + u32 adslAturChanPrevTxRate; +}adslChanPrevTxRate; + +typedef struct adslPhysCurrStatus{ + u32 adslAtucCurrStatus; + u32 adslAturCurrStatus; +}adslPhysCurrStatus; + +typedef struct ChanType{ + int interleave; + int fast; +// 603221:tc.chen start + int bearchannel0; + int bearchannel1; +// 603221:tc.chen end +}ChanType; + +typedef struct mib_previous_read{ + u16 ATUC_PERF_ESS; + u16 ATUR_PERF_ESS; + u32 ATUR_CHAN_RECV_BLK; + u16 ATUR_CHAN_CORR_BLK_INTL; + u16 ATUR_CHAN_CORR_BLK_FAST; + u16 ATUR_CHAN_UNCORR_BLK_INTL; + u16 ATUR_CHAN_UNCORR_BLK_FAST; + u16 ATUC_PERF_STAT_FASTR; + u16 ATUC_PERF_STAT_FAILED_FASTR; + u16 ATUC_PERF_STAT_SESL; + u16 ATUC_PERF_STAT_UASL; + u16 ATUR_PERF_STAT_SESL; +}mib_previous_read; + +typedef struct mib_flags_pretime{ + struct timeval ATUC_PERF_LOSS_PTIME; + struct timeval ATUC_PERF_LOFS_PTIME; + struct timeval ATUR_PERF_LOSS_PTIME; + struct timeval ATUR_PERF_LOFS_PTIME; + struct timeval ATUR_PERF_LPR_PTIME; +}mib_flags_pretime; + + // cmv message structures +#define MP_PAYLOAD_SIZE 12 +typedef struct mpmessage{ + u16 iFunction; + u16 iGroup; + u16 iAddress; + u16 iIndex; + u16 iPayload[MP_PAYLOAD_SIZE]; +}MPMessage; +#endif + + +typedef struct meireg{ + u32 iAddress; + u32 iData; +}meireg; + +#define MEIDEBUG_BUFFER_SIZES 50 +typedef struct meidebug{ + u32 iAddress; + u32 iCount; + u32 buffer[MEIDEBUG_BUFFER_SIZES]; +}meidebug; + +//============================================================================== +// Group definitions +//============================================================================== +#define OPTN 5 +#define CNFG 8 +#define CNTL 1 +#define STAT 2 +#define RATE 6 +#define PLAM 7 +#define INFO 3 +#define TEST 4 +//============================================================================== +// Opcode definitions +//============================================================================== +#define H2D_CMV_READ 0x00 +#define H2D_CMV_WRITE 0x04 +#define H2D_CMV_INDICATE_REPLY 0x10 +#define H2D_ERROR_OPCODE_UNKNOWN 0x20 +#define H2D_ERROR_CMV_UNKNOWN 0x30 + +#define D2H_CMV_READ_REPLY 0x01 +#define D2H_CMV_WRITE_REPLY 0x05 +#define D2H_CMV_INDICATE 0x11 +#define D2H_ERROR_OPCODE_UNKNOWN 0x21 +#define D2H_ERROR_CMV_UNKNOWN 0x31 +#define D2H_ERROR_CMV_READ_NOT_AVAILABLE 0x41 +#define D2H_ERROR_CMV_WRITE_ONLY 0x51 +#define D2H_ERROR_CMV_READ_ONLY 0x61 + +#define H2D_DEBUG_READ_DM 0x02 +#define H2D_DEBUG_READ_PM 0x06 +#define H2D_DEBUG_WRITE_DM 0x0a +#define H2D_DEBUG_WRITE_PM 0x0e + +#define D2H_DEBUG_READ_DM_REPLY 0x03 +#define D2H_DEBUG_READ_FM_REPLY 0x07 +#define D2H_DEBUG_WRITE_DM_REPLY 0x0b +#define D2H_DEBUG_WRITE_FM_REPLY 0x0f +#define D2H_ERROR_ADDR_UNKNOWN 0x33 + +#define D2H_AUTONOMOUS_MODEM_READY_MSG 0xf1 +//============================================================================== +// INFO register address field definitions +//============================================================================== + +#define INFO_TxState 0 +#define INFO_RxState 1 +#define INFO_TxNextState 2 +#define INFO_RxNextState 3 +#define INFO_TxStateJumpFrom 4 +#define INFO_RxStateJumpFrom 5 + +#define INFO_ReverbSnrBuf 8 +#define INFO_ReverbEchoSnrBuf 9 +#define INFO_MedleySnrBuf 10 +#define INFO_RxShowtimeSnrBuf 11 +#define INFO_DECdelay 12 +#define INFO_DECExponent 13 +#define INFO_DECTaps 14 +#define INFO_AECdelay 15 +#define INFO_AECExponent 16 +#define INFO_AECTaps 17 +#define INFO_TDQExponent 18 +#define INFO_TDQTaps 19 +#define INFO_FDQExponent 20 +#define INFO_FDQTaps 21 +#define INFO_USBat 22 +#define INFO_DSBat 23 +#define INFO_USFineGains 24 +#define INFO_DSFineGains 25 +#define INFO_BitloadFirstChannel 26 +#define INFO_BitloadLastChannel 27 +#define INFO_PollEOCData 28 // CO specific +#define INFO_CSNRMargin 29 // CO specific +#define INFO_RCMsgs1 30 +#define INFO_RMsgs1 31 +#define INFO_RMsgRA 32 +#define INFO_RCMsgRA 33 +#define INFO_RMsg2 34 +#define INFO_RCMsg2 35 +#define INFO_BitLoadOK 36 +#define INFO_RCRates1 37 +#define INFO_RRates1Tab 38 +#define INFO_RMsgs1Tab 39 +#define INFO_RMsgRATab 40 +#define INFO_RRatesRA 41 +#define INFO_RCRatesRA 42 +#define INFO_RRates2 43 +#define INFO_RCRates2 44 +#define INFO_PackedRMsg2 45 +#define INFO_RxBitSwapFlag 46 +#define INFO_TxBitSwapFlag 47 +#define INFO_ShowtimeSNRUpdateCount 48 +#define INFO_ShowtimeFDQUpdateCount 49 +#define INFO_ShowtimeDECUpdateCount 50 +#define INFO_CopyRxBuffer 51 +#define INFO_RxToneBuf 52 +#define INFO_TxToneBuf 53 +#define INFO_Version 54 +#define INFO_TimeStamp 55 +#define INFO_feVendorID 56 +#define INFO_feSerialNum 57 +#define INFO_feVersionNum 58 +#define INFO_BulkMemory 59 //Points to start of bulk memory +#define INFO_neVendorID 60 +#define INFO_neVersionNum 61 +#define INFO_neSerialNum 62 + +//============================================================================== +// RATE register address field definitions +//============================================================================== + + +#define RATE_UsRate 0 +#define RATE_DsRate 1 + + +//============================================================================== +// PLAM (Physical Layer Management) register address field definitions +// (See G997.1 for reference) +//============================================================================== + + + // /// + // Failure Flags /// + // /// + +#define PLAM_NearEndFailureFlags 0 +#define PLAM_FarEndFailureFlags 1 + + // /// + // Near End Failure Flags Bit Definitions /// + // /// + +// ADSL Failures /// +#define PLAM_LOS_FailureBit 0x0001 +#define PLAM_LOF_FailureBit 0x0002 +#define PLAM_LPR_FailureBit 0x0004 +#define PLAM_RFI_FailureBit 0x0008 + +// ATM Failures /// +#define PLAM_NCD_LP0_FailureBit 0x0010 +#define PLAM_NCD_LP1_FailureBit 0x0020 +#define PLAM_LCD_LP0_FailureBit 0x0040 +#define PLAM_LCD_LP1_FailureBit 0x0080 + +#define PLAM_NCD_BC0_FailureBit 0x0100 +#define PLAM_NCD_BC1_FailureBit 0x0200 +#define PLAM_LCD_BC0_FailureBit 0x0400 +#define PLAM_LCD_BC1_FailureBit 0x0800 + // /// + // Performance Counts /// + // /// + +#define PLAM_NearEndCrcCnt 2 +#define PLAM_CorrectedRSErrors 3 + +#define PLAM_NearEndECSCnt 6 +#define PLAM_NearEndESCnt 7 +#define PLAM_NearEndSESCnt 8 +#define PLAM_NearEndLOSSCnt 9 +#define PLAM_NearEndUASLCnt 10 + +#define PLAM_NearEndHECErrCnt 11 + +#define PLAM_NearEndHECTotCnt 16 +#define PLAM_NearEndCellTotCnt 18 +#define PLAM_NearEndSfCntLSW 20 +#define PLAM_NearEndSfCntMSW 21 + +#define PLAM_FarEndFebeCnt 24 + +#define PLAM_FarEndFecCnt 28 + +#define PLAM_FarEndFECSCnt 32 +#define PLAM_FarEndESCnt 33 +#define PLAM_FarEndSESCnt 34 +#define PLAM_FarEndLOSSCnt 35 +#define PLAM_FarEndUASLCnt 36 + +#define PLAM_FarEndHECErrCnt 37 + +#define PLAM_FarEndHECTotCnt 41 + +#define PLAM_FarEndCellTotCnt 43 + +#define PLAM_LineAttn 45 +#define PLAM_SNRMargin 46 + + +//============================================================================== +// CNTL register address and bit field definitions +//============================================================================== + + +#define CNTL_ModemControl 0 + +#define CNTL_ModemReset 0x0 +#define CNTL_ModemStart 0x2 + + +//============================================================================== +// STAT register address and bit field definitions +//============================================================================== + +#define STAT_MacroState 0 +#define STAT_Mode 1 +#define STAT_DMTFramingMode 2 +#define STAT_SleepState 3 +#define STAT_Misc 4 +#define STAT_FailureState 5 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // STAT_OLRStatus provides status of OLR + //16-bit STAT_OLRStatus_DS + // [1:0] : OLR status 00=IDLE, 01=OLR_IN_PROGRESS, 10=OLR_Completed, 11=OLR_Aborted + // [3:2]: Reserved + // [5:4]: OLR_Type (1:bitswap; 2: DRR; 3: SRA) + // [7:6]: Reserved + // [10:8]: >0=Request. 0=not. For DS, # of request transmissions/retransmissions (3 bits). + // [11]: 1=Receive Response, 0=not + // [15:12]: Reserved + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// +#define STAT_OLRStatus_DS 6 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // STAT_OLRStatus provides status of OLR + // 16-bit STAT_OLRStatus_US CMV + // [1:0] : OLR status 00=IDLE, 01=OLR_IN_PROGRESS, 10=OLR_Completed, 11=OLR_Aborted + // [3:2]: Reserved + // [5:4]: OLR_Type (1:bitswap; 2: DRR; 3: SRA) + // [7:6]: Reserved + // [8]: 1=Request Received. 0=not. + // [10:9]: Reserved + // [11]: 1=Response Sent, 0=not + // [15:12]: Reserved + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/// +#define STAT_OLRStatus_US 7 + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // STAT_PMStatus provides status of PM + // 16-bit STAT_PMStatus CMV + // [1:0] : PM Status 00=IDLE, 01=PM_IN_PROGRESS, 10=PM_Completed, 11=PM_Aborted + // [2] : 0=ATU_R initiated PM; 1 = ATU_C initiated PM + // [3]: Reserved + // [5:4]: PM_Type (1:Simple Request; 2: L2 request; 3: L2 trim) + // [7:6]: Reserved + // [10:8]: >0=Request. 0=not. # of request transmissions/retransmissions (3 bits). + // [11]: 1=Response, 0=not + // [15:12]: Reserved + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// +#define STAT_PMStatus 8 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 16-bit STAT_OLRError_DS, STAT_OLRError_US, STAT_PMError + // [3:0]: OLR/PM response reason code + // [7:4]: OLR/PM Internal error code + // [15:8]: OLR/PM Reserved for future + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// +#define STAT_OLRError_DS 9 +#define STAT_OLRError_US 10 +#define STAT_PMError 11 + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STAT_MacroState +// MacroState reflects the high level state of the modem + +#define STAT_InitState 0x0000 +#define STAT_ReadyState 0x0001 +#define STAT_FailState 0x0002 +#define STAT_IdleState 0x0003 +#define STAT_QuietState 0x0004 +#define STAT_GhsState 0x0005 +#define STAT_FullInitState 0x0006 +#define STAT_ShowTimeState 0x0007 +#define STAT_FastRetrainState 0x0008 +#define STAT_LoopDiagMode 0x0009 +#define STAT_ShortInit 0x000A // Bis short initialization /// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STAT_Mode +// ConfigurationMode indicates the mode of the current ADSL Link. In general, a modem may use +// G.Hs or some other mechanism to negotiate the specific mode of operation. +// The OPTN_modeControl CMV is used to select a set of desired modes. +// The STAT_Mode CMV indicates which mode was actually selected. + +#define STAT_ConfigMode_T1413 0x0001 +#define STAT_ConfigMode_G992_2_AB 0x0002 +#define STAT_ConfigMode_G992_1_A 0x0004 +#define STAT_ConfigMode_G992_1_B 0x0008 +#define STAT_ConfigMode_G992_1_C 0x0010 +#define STAT_ConfigMode_G992_2_C 0x0020 + +#define STAT_ConfigMode_G992_3_A 0x0100 +#define STAT_ConfigMode_G992_3_B 0x0200 +#define STAT_ConfigMode_G992_3_I 0x0400 +#define STAT_ConfigMode_G992_3_J 0x0800 +#define STAT_ConfigMode_G992_3_L 0x1000 + +#define STAT_ConfigMode_G992_4_A 0x2000 +#define STAT_ConfigMode_G992_4_I 0x4000 + +#define STAT_ConfigMode_G992_5 0x8000 + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STAT_DMTFramingMode +// FramingMode indicates the DMT framing mde negotiated during initialization. The framing mode +// status is not applicable in BIS mode and its value is undefined +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define STAT_FramingModeMask 0x0003 + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STAT_Misc +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define STAT_OverlappedSpectrum 0x0008 +#define STAT_TCM 0x0010 +#define STAT_TDQ_at_1104 0x0020 +#define STAT_T1413_Signal_Detected 0x0040 +#define STAT_AnnexL_US_Mask1_PSD 0x1000 //indicate we actually selected G992.3 AnnexL US PSD mask1 +#define STAT_AnnexL_US_Mask2_PSD 0x2000 //indicate we actually selected G992.3 AnnexL US PSD mask2 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// STAT_FailureState +// when the MacroSTate indicates the fail state, FailureState provides a failure code +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +#define E_CODE_NO_ERROR 0 +#define E_CODE_BAT_TX 1 // TX BAT table is incorrect */ +#define E_CODE_BAT_RX 2 // RX BAT table is incorrect */ +#define E_CODE_PROFILE 3 // profile is not selected in fast retrain */ +#define E_CODE_TX_AOC_FIFO_OVERFLOW 4 +#define E_CODE_TRUNCATE_FR 5 //Fast Retrain truncated due to no stored profiles*/ +#define E_CODE_BITLOAD 6 // bit loading fails */ +#define E_CODE_ST_ERROR 7 // showtime CRC error */ +#define E_CODE_RESERVED 8 // using parameters reserved by the ITU-T */ +#define E_CODE_C_TONES 9 // detected C_TONES */ +#define E_CODE_CODESWAP_ERR 10 // codeswap not finished in time */ +#define E_CODE_FIFO_OVERFLOW 11 // we have run out of fifo space */ +#define E_CODE_C_BG_DECODE_ERR 12 // error in decoding C-BG message */ +#define E_CODE_C_RATES2_DECODE_ERR 13 // error in decoding C-MSGS2 and C-RATES2 */ +#define E_CODE_RCMedleyRx_C_SEGUE2_Failure 14 // Timeout after RCMedleyRx waiting for C_SEGUE2 */ +#define E_CODE_RReverbRATx_C_SEGUE2_Failure 15 // Timeout after RReverbRATx waiting for C_SEGUE2 */ +#define E_CODE_RReverb3Tx_C_SEGUE1_Failure 16 // Timeout after RReverb3Tx waiting for C_SEGUE1 */ +#define E_CODE_RCCRC2Rx_C_RATES1_DECOD_ERR 17 // Received CRC not equal to computed CRC */ +#define E_CODE_RCCRC1Rx_C_RATES1_DECOD_ERR 18 // Received CRC not equal to computed CRC */ +#define E_CODE_RReverb5Tx_C_SEGUE2_Failure 19 // Timeout after RReverb5Tx waiting for C_SEGUE2 */ +#define E_CODE_RReverb6Tx_C_SEGUE3_Failure 20 // Timeout after RReverb6Tx waiting for C_SEGUE3 */ +#define E_CODE_RSegue5Tx_C_SEGUE3_Failure 21 // Timeout after RSegue5Tx waiting for C_SEGUE3 */ +#define E_CODE_RCReverb5Rx_C_SEGUE_Failure 22 // Timeout after RCReverb5Rx waiting for C_SEGUE */ +#define E_CODE_RCReverbRARx_C_SEGUE2_Failure 23 // Timeout after RCReverbRARx waiting for C_SEGUE2 */ +#define E_CODE_RCCRC4Rx_CMSGS2_DECOD_ERR 24 // Received CRC not equal to computed CRC */ +#define E_CODE_RCCRC5Rx_C_BG_DECOD_ERR 25 // Received CRC not equal to computed CRC */ +#define E_CODE_RCCRC3Rx_DECOD_ERR 26 // Received CRC not equal to computed CRC */ +#define E_CODE_RCPilot3_DEC_PATH_DEL_TIMEOUT 27 // DEC Path Delay timeout */ +#define E_CODE_RCPilot3_DEC_TRAINING_TIMEOUT 28 // DEC Training timeout */ +#define E_CODE_RCReverb3Rx_C_SEGUE1_Failure 29 // Timeout after RCReverb3Rx waiting for C_SEGUE1 */ +#define E_CODE_RCReverb2Rx_SignalEnd_Failure 30 // Timeout waiting for the end of RCReverb2Rx signal */ +#define E_CODE_RQuiet2_SignalEnd_Failure 31 // Timeout waiting for the end of RQuiet2 signal */ +#define E_CODE_RCReverbFR1Rx_Failure 32 // Timeout waiting for the end of RCReverbFR1Rx signal */ +#define E_CODE_RCPilotFR1Rx_SignalEnd_Failure 33 // Timeout waiting for the end of RCPilotFR1Rx signal */ +#define E_CODE_RCReverbFR2Rx_C_Segue_Failure 34 // Timeout after RCReverbFR2Rx waiting for C_SEGUE */ +#define E_CODE_RCReverbFR5Rx_SignalEnd_TIMEOUT 35 // Timeout waiting for the end of RCReverbFR5Rx signal */ +#define E_CODE_RCReverbFR6Rx_C_SEGUE_Failure 36 // Timeout after RCReverbFR6Rx waiting for C_SEGUE */ +#define E_CODE_RCReverbFR8Rx_C_SEGUE_FR4_Failure 37 // Timeout after RCReverbFR8Rx waiting for C_SEGUE_FR4 */ +#define E_CODE_RCReverbFR8Rx_No_PROFILE 38 // Timeout since no profile was selected */ +#define E_CODE_RCReverbFR8Rx_SignalEnd_TIMEOUT 39 // Timeout waiting for the end of RCReverbFR8Rx signal */ +#define E_CODE_RCCRCFR1_DECOD_ERR 40 // Received CRC not equal to computed CRC */ +#define E_CODE_RCRecovRx_SingnalEnd_TIMEOUT 41 // Timeout waiting for the end of RCRecovRx signal */ +#define E_CODE_RSegueFR5Tx_TX_Not_Ready_TIMEOUT 42 // Timeout after RSegueFR5Tx waiting for C_SEGUE2 */ +#define E_CODE_RRecovTx_SignalEnd_TIMEOUT 43 // Timeout waiting for the end of RRecovTx signal */ +#define E_CODE_RCMedleyFRRx_C_SEGUE2_Failure 44 // Timeout after RCMedleyFRRx waiting for C_SEGUE2 */ +#define E_CODE_CONFIGURATION_PARAMETERS_ERROR 45 // one of the configuration parameters do not meet the standard */ +#define E_CODE_BAD_MEM_ACCESS 46 +#define E_CODE_BAD_INSTRUCTION_ACCESS 47 +#define E_CODE_TX_EOC_FIFO_OVERFLOW 48 +#define E_CODE_RX_EOC_FIFO_OVERFLOW 49 +#define E_CODE_GHS_CD_FLAG_TIME_OUT 50 // Timeout when transmitting Flag in handshake cleardown */ + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//STAT_OLRStatus: +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define STAT_OLRPM_IDLE 0x0000 +#define STAT_OLRPM_IN_PROGRESS 0x0001 +#define STAT_OLRPM_COMPLETE 0x0002 +#define STAT_OLRPM_ABORTED 0x0003 +#define STAT_OLRPM_RESPONSE 0x0800 + +#define STAT_OLR_BITSWAP 0x0010 +#define STAT_OLR_DRR 0x0020 +#define STAT_OLR_SRA 0x0030 + +//STAT_PMStatus_US: +#define STAT_PM_CO_REQ 0x0004 +#define STAT_PM_SIMPLE_REQ 0x0010 +#define STAT_PM_L2_REQ 0x0020 +#define STAT_PM_L2_TRIM_REQ 0x0030 + +// STAT_OLRError_DS, STAT_OLRError_US +//4 bit response reason code: +#define RESP_BUSY 0x01 +#define RESP_INVALID_PARAMETERS 0x02 +#define RESP_NOT_ENABLED 0x03 +#define RESP_NOT_SUPPORTED 0x04 + +//4 bit internal error code (common for OLR and PM) +#define REQ_INVALID_BiGi 0x10 +#define REQ_INVALID_Lp 0x20 +#define REQ_INVALID_Bpn 0x30 +#define REQ_INVALID_FRAMING_CONSTRAINT 0x40 +#define REQ_NOT_IN_L0_STATE 0x50 +#define REQ_NOT_IN_L2_STATE 0x60 +#define REQ_INVALID_PCB 0x70 +#define REQ_VIOLATES_MARGIN 0x80 + +//STAT_PMError +//4 bit response reason code: +#define RESP_STATE_NOT_DESIRED 0x03 +#define RESP_INFEASIBLE_PARAMETERS 0x04 + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OPTN register address and bit field definitions +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define OPTN_ModeControl 0 +#define OPTN_DMTLnkCtl 1 +// Reserved 2 +#define OPTN_GhsControl 3 +// Reserved 4 +#define OPTN_PwrManControl 5 +#define OPTN_AnnexControl 6 +#define OPTN_ModeControl1 7 +// Reserved 8 +#define OPTN_StateMachineCtrl 9 +// Reserved 10 +// Reserved 11 +#define OPTN_BisLinkControl 12 +#define OPTN_ATMAddrConfig 13 +#define OPTN_ATMNumCellConfig 14 + +// Mode control defines the allowable operating modes of an ADSL link. In general, a modem may /// +// use G.Hs or some other mechanism to negotiate the specific mode of operation. /// +// The OPTN_ModeControl CMV is used to select a set of desired modes /// +// The STAT_ModeControl CMV indicates which mode was actually selected /// + +// OPTN_ModeControl +#define OPTN_ConfigMode_T1413 0x0001 +#define OPTN_ConfigMode_G992_2_AB 0x0002 +#define OPTN_ConfigMode_G992_1_A 0x0004 +#define OPTN_ConfigMode_G992_1_B 0x0008 +#define OPTN_ConfigMode_G992_1_C 0x0010 +#define OPTN_ConfigMode_G992_2_C 0x0020 + +#define OPTN_ConfigMode_G992_3_A 0x0100 +#define OPTN_ConfigMode_G992_3_B 0x0200 +#define OPTN_ConfigMode_G992_3_I 0x0400 +#define OPTN_ConfigMode_G992_3_J 0x0800 +#define OPTN_ConfigMode_G992_3_L 0x1000 + +#define OPTN_ConfigMode_G992_4_A 0x2000 +#define OPTN_ConfigMode_G992_4_I 0x4000 + +#define OPTN_ConfigMode_G992_5 0x8000 + +// OPTN_PwrManControl +#define OPTN_PwrManWakeUpGhs 0x1 +#define OPTN_PwrManWakeUpFR 0x2 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OPTN_DMT Link Control +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define OPTN_DMT_DualLatency_Dis 0x200 +#define OPTN_DMT_S_Dis 0x100 +#define OPTN_DMT_FRAMINGMODE 0x1 +#define OPTN_DMT_FRAMINGMODE_MASK 0x7 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OPTN_BIS Link Control +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define OPTN_BisLinkContrl_LineProbeDis 0x1 +#define OPTN_BisLinkContrl_DSBlackBitsEn 0x2 +#define OPTN_BisLinkContrl_DiagnosticModeEn 0x4 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OPTN_GhsControl +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// for OPTN_GhsControl, we will assign 16bit word as follows +// bit 0~3: set the control over which start(initial) message CPE will send: +// +// BIT: 2 1 0 +// 0 0 1 CLR +// 0 1 0 MR +// 0 1 1 MS +// 1 0 0 MP +// +// // bit 4~6: set the control over which message will be sent when we get at lease one CL/CLR exchange +// BIT: 5 4 +// 0 1 MS +// 1 0 MR +// 1 1 MP +// +// // bit 15: RT initiated G.hs sample sessions one through eight. Session one is default. +// BIT: 15 +// 1 means session one +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define OPTN_GHS_ST_GHS 0x8000 +#define OPTN_GHS_INIT_MASK 0x000F +#define OPTN_GHS_RESP_MASK 0x00F0 + +#define OPTN_RTInitTxMsg_CLR 0x0001 +#define OPTN_RTInitTxMsg_MR 0x0002 +#define OPTN_RTInitTxMsg_MS 0x0003 +#define OPTN_RTInitTxMsg_MP 0x0004 + +#define OPTN_RTRespTxMsg_MS 0x0010 +#define OPTN_RTRespTxMsg_MR 0x0020 +#define OPTN_RTRespTxMsg_MP 0x0030 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// OPTN_AnnexControl +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +// G.992.3 Annex A/L1/L2 US PSD Mask preferred + +#define OPTN_G992_3_AnnexA_PreferredModeMask 0x3000 +#define OPTN_G992_3_AnnexA_PreferredModeA 0x0000 // default AnnexA PSD mask /// +#define OPTN_G992_3_AnnexA_PreferredModeL1 0x1000 // AnnexL wide spectrum upstream PSD mask /// +#define OPTN_G992_3_AnnexA_PreferredModeL2 0x2000 // AnnexL narrow spectrum upstream PSD mask /// + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//OPTN_ATMAddrConfig +// Bits 4:0 are Utopia address for BC1 +// Bits 9:5 are Utopia address for BC0 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define OPTN_UTPADDR_BC1 0x001F +#define OPTN_UTPADDR_BC0 0x03E0 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//OPTN_ATMNumCellConfig +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define OPTN_BC1_NUM_CELL_PAGES 0x000F // Bits 0:3 /// +#define OPTN_BC0_NUM_CELL_PAGES 0x00F0 // Bits 4:7 /// + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CNFG register address field /// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////// +// these cmvs are used by bis handshake /// +/////////////////////////////////////////// + +// Each of the CNFG_TPS entries points to a structure of type (TPS_TC_BearerChannel_t) +#define CNFG_TPS_TC_DS0 0 +#define CNFG_TPS_TC_DS1 1 +#define CNFG_TPS_TC_US0 2 +#define CNFG_TPS_TC_US1 3 + +#define CNFG_HDLC_Overhead_Requirements 4 + +// Each of the CNFG_PMS entries points to a structure of type (PMS_TC_LatencyPath_t) +#define CNFG_PMS_TC_DS0 5 +#define CNFG_PMS_TC_DS1 6 +#define CNFG_PMS_TC_US0 7 +#define CNFG_PMS_TC_US1 8 + +// CNFG_PMD_PARAMETERS points to a structure of type (PMD_params_t) +#define CNFG_PMD_PARAMETERS 9 + +//////////////////////////////////////////////////////////// +// these cmvs are used by bis training and showtime code /// +//////////////////////////////////////////////////////////// + +//////////////// +// Tx Config /// +//////////////// +#define CNFG_tx_Cnfg_Nbc 10 +#define CNFG_tx_Cnfg_Nlp 11 +#define CNFG_tx_Cnfg_Rp 12 +#define CNFG_tx_Cnfg_Mp 13 +#define CNFG_tx_Cnfg_Lp 14 +#define CNFG_tx_Cnfg_Tp 15 +#define CNFG_tx_Cnfg_Dp 16 +#define CNFG_tx_Cnfg_Bpn 17 +#define CNFG_tx_Cnfg_FramingMode 18 +#define CNFG_tx_Cnfg_MSGLp 19 +#define CNFG_tx_Cnfg_MSGc 20 + + +//////////////// +// Rx Config /// +//////////////// +#define CNFG_rx_Cnfg_Nbc 21 +#define CNFG_rx_Cnfg_Nlp 22 +#define CNFG_rx_Cnfg_Rp 23 +#define CNFG_rx_Cnfg_Mp 24 +#define CNFG_rx_Cnfg_Lp 25 +#define CNFG_rx_Cnfg_Tp 26 +#define CNFG_rx_Cnfg_Dp 27 +#define CNFG_rx_Cnfg_Bpn 28 +#define CNFG_rx_Cnfg_FramingMode 29 +#define CNFG_rx_Cnfg_MSGLp 30 +#define CNFG_rx_Cnfg_MSGc 31 + +#define CNFG_tx_Cnfg_BCnToLPp 32 +#define CNFG_rx_Cnfg_BCnToLPp 33 + + + +#endif + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_sw.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_sw.h new file mode 100644 index 0000000000..3b73b53892 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_sw.h @@ -0,0 +1,176 @@ +#ifndef AMAZON_SW_H +#define AMAZON_SW_H +#define SET_ETH_SPEED_AUTO SIOCDEVPRIVATE +#define SET_ETH_SPEED_10 SIOCDEVPRIVATE+1 +#define SET_ETH_SPEED_100 SIOCDEVPRIVATE+2 +#define SET_ETH_DUPLEX_AUTO SIOCDEVPRIVATE+3 +#define SET_ETH_DUPLEX_HALF SIOCDEVPRIVATE+4 +#define SET_ETH_DUPLEX_FULL SIOCDEVPRIVATE+5 +#define SET_ETH_REG SIOCDEVPRIVATE+6 +#define VLAN_TOOLS SIOCDEVPRIVATE+7 +#define MAC_TABLE_TOOLS SIOCDEVPRIVATE+8 + + +/*===mac table commands==*/ +#define RESET_MAC_TABLE 0 +#define READ_MAC_ENTRY 1 +#define WRITE_MAC_ENTRY 2 +#define ADD_MAC_ENTRY 3 + +/*====vlan commands===*/ + +#define CHANGE_VLAN_CTRL 0 +#define READ_VLAN_ENTRY 1 +#define UPDATE_VLAN_ENTRY 2 +#define CLEAR_VLAN_ENTRY 3 +#define RESET_VLAN_TABLE 4 +#define ADD_VLAN_ENTRY 5 + +/* +** MDIO constants. +*/ + +#define MDIO_BASE_STATUS_REG 0x1 +#define MDIO_BASE_CONTROL_REG 0x0 +#define MDIO_PHY_ID_HIGH_REG 0x2 +#define MDIO_PHY_ID_LOW_REG 0x3 +#define MDIO_BC_NEGOTIATE 0x0200 +#define MDIO_BC_FULL_DUPLEX_MASK 0x0100 +#define MDIO_BC_AUTO_NEG_MASK 0x1000 +#define MDIO_BC_SPEED_SELECT_MASK 0x2000 +#define MDIO_STATUS_100_FD 0x4000 +#define MDIO_STATUS_100_HD 0x2000 +#define MDIO_STATUS_10_FD 0x1000 +#define MDIO_STATUS_10_HD 0x0800 +#define MDIO_STATUS_SPEED_DUPLEX_MASK 0x7800 +#define MDIO_ADVERTISMENT_REG 0x4 +#define MDIO_ADVERT_100_FD 0x100 +#define MDIO_ADVERT_100_HD 0x080 +#define MDIO_ADVERT_10_FD 0x040 +#define MDIO_ADVERT_10_HD 0x020 +#define MDIO_LINK_UP_MASK 0x4 +#define MDIO_START 0x1 +#define MDIO_READ 0x2 +#define MDIO_WRITE 0x1 +#define MDIO_PREAMBLE 0xfffffffful + +#define PHY_RESET 0x8000 +#define AUTO_NEGOTIATION_ENABLE 0X1000 +#define AUTO_NEGOTIATION_COMPLETE 0x20 +#define RESTART_AUTO_NEGOTIATION 0X200 + + +#define PHY0_ADDR 0 +#define PHY1_ADDR 1 +#define P1M 0 + +#define AMAZON_SW_REG32(reg_num) *((volatile u32*)(reg_num)) + +#define OK 0; + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +typedef struct mac_table_entry{ + u64 mac_address:48; + u64 p0:1; + u64 p1:1; + u64 p2:1; + u64 cr:1; + u64 ma_st:3; + u64 res:9; +}_mac_table_entry; + +typedef struct IFX_Switch_VLanTableEntry{ + u32 vlan_id:12; + u32 mp0:1; + u32 mp1:1; + u32 mp2:1; + u32 v:1; + u32 res:16; +}_IFX_Switch_VLanTableEntry; + +typedef struct mac_table_req{ + int cmd; + int index; + u32 data; + u64 entry_value; +}_mac_table_req; + +#else //not CONFIG_CPU_LITTLE_ENDIAN +typedef struct mac_table_entry{ + u64 mac_address:48; + u64 p0:1; + u64 p1:1; + u64 p2:1; + u64 cr:1; + u64 ma_st:3; + u64 res:9; +}_mac_table_entry; + +typedef struct IFX_Switch_VLanTableEntry{ + u32 vlan_id:12; + u32 mp0:1; + u32 mp1:1; + u32 mp2:1; + u32 v:1; + u32 res:16; +}_IFX_Switch_VLanTableEntry; + + +typedef struct mac_table_req{ + int cmd; + int index; + u32 data; + u64 entry_value; +}_mac_table_req; + +#endif //CONFIG_CPU_LITTLE_ENDIAN + + + +typedef struct vlan_req{ + int cmd; + int index; + u32 data; + u32 entry_value; +}_vlan_req; + +typedef struct data_req{ + int index; + u32 value; +}_data_req; + +enum duplex +{ + half, + full, + autoneg +}; + +struct switch_priv { + struct net_device_stats stats; + int rx_packetlen; + u8 *rx_packetdata; + int rx_status; + int tx_packetlen; +#ifdef CONFIG_NET_HW_FLOWCONTROL + int fc_bit; +#endif //CONFIG_NET_HW_FLOWCONTROL + u8 *tx_packetdata; + int tx_status; + struct dma_device_info *dma_device; + struct sk_buff *skb; + spinlock_t lock; + int mdio_phy_addr; + int current_speed; + int current_speed_selection; + int rx_queue_len; + int full_duplex; + enum duplex current_duplex; +}; + +#endif //AMAZON_SW_H + + + + + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_tpe.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_tpe.h new file mode 100644 index 0000000000..a64e6f9f80 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_tpe.h @@ -0,0 +1,258 @@ +#ifndef AMAZON_TPE_H +#define AMAZON_TPE_H +#include <linux/atm.h> +#include <linux/atmdev.h> +#include <linux/netdevice.h> +#include <linux/ioctl.h> + +#ifdef CONFIG_IFX_ATM_MIB +/* For ATM-MIB lists */ +#include <linux/list.h> +#endif +#include <asm/amazon/atm_mib.h> + +/* CBM Queue arranagement + * Q0: free cells pool + * Q1~ Q15: upstream queues + * Q16: QAM downstream + * Q17~Q31: downstream queues + */ +#define AMAZON_ATM_MAX_QUEUE_NUM 32 +#define AMAZON_ATM_PORT_NUM 2 +#define AMAZON_ATM_FREE_CELLS 4000 +#define AMAZON_ATM_MAX_VCC_NUM (AMAZON_ATM_MAX_QUEUE_NUM/2 - 1) +#define AMAZON_AAL0_SDU (ATM_AAL0_SDU+4) //one more word for status +#define CBM_RX_OFFSET 16 //offset from the same q for tx +#define AMAZON_ATM_OAM_Q_ID 16 +#define AMAZON_ATM_RM_Q_ID 16 +#define AMAZON_ATM_OTHER_Q_ID 16 +#define CBM_DEFAULT_Q_OFFSET 1 +#define HTUTIMEOUT 0xffff//timeoutofhtutocbm +#define QSB_WFQ_NONUBR_MAX 0x3f00 +#define QSB_WFQ_UBR_BYPASS 0x3fff +#define QSB_TP_TS_MAX 65472 +#define QSB_TAUS_MAX 64512 +#define QSB_GCR_MIN 18 +#define HTU_RAM_ACCESS_MAX 1024//maxium time for HTU RAM access + +#define SWIE_LOCK 1 +#define PROC_ATM 1 +#define PROC_MIB 2 +#define PROC_VCC 3 +#define PROC_AAL5 4 +#define PROC_CBM 5 +#define PROC_HTU 6 +#define PROC_QSB 7 +#define PROC_SWIE 8 + +/***************** internal data structure ********************/ +typedef int (*push_back_t)(struct atm_vcc *vcc,struct sk_buff *skb,int err) ; +/* Device private data */ +typedef struct{ + u8 padding_byte; + u32 tx_max_sdu; + u32 rx_max_sdu; + u32 cnt_cpy; //no. of packets that need a copy due to alignment +}amazon_aal5_dev_t; + +typedef struct{ + u32 max_q_off; //maxium queues used in real scenario + u32 nrt_thr; + u32 clp0_thr; + u32 clp1_thr; + u32 free_cell_cnt; +#ifdef CONFIG_USE_VENUS + u8 * qd_addr_free; //to work around a bug, bit15 of QDOFF address should be 1 +#endif + u8 * qd_addr; + u8 * mem_addr; + u8 allocated; +}amazon_cbm_dev_t; + +typedef struct{ + +}amazon_htu_dev_t; + +typedef struct{ + u32 tau; //cell delay variation due to concurrency(?) + u32 tstepc; //time step, all legal values are 1,2,4 + u32 sbl; //scheduler burse length (for PHY) +}amazon_qsb_dev_t; + +typedef struct{ + u32 qid; //QID of the current extraction queue + struct semaphore in_sem; // Software-Insertion semaphore + volatile long lock; //lock that avoids race contions between SWIN and SWEX + wait_queue_head_t sleep; //wait queue for SWIE and SWEX + u32 sw; //status word +}amazon_swie_dev_t; + +//AAL5 MIB Counter +typedef struct{ + u32 tx,rx; //number AAL5 CPCS PDU from/to higher-layer + u32 tx_err,rx_err; //ifInErrors and ifOutErros + u32 tx_drop,rx_drop; //discarded received packets due to mm shortage + u32 htu_unp; //number of unknown received cells + u32 rx_cnt_h; //number of octets received, high 32 bits + u32 rx_cnt_l; //number of octets received, low 32 bits + u32 tx_cnt_h; //number of octets transmitted, high 32 bits + u32 tx_cnt_l; //number of octets transmitted, low 32 bits + u32 tx_ppd; //number of cells for AAL5 upstream PPD discards + u64 rx_cells; //number of cells for downstream + u64 tx_cells; //number of cells for upstream + u32 rx_err_cells; //number of cells dropped due to uncorrectable HEC errors +}amazon_mib_counter_t; + + + +typedef enum {QS_PKT,QS_LEN,QS_ERR,QS_HW_DROP,QS_SW_DROP,QS_MAX} qs_t; +//queue statics no. of packet received / sent +//queue statics no. of bytes received / sent +//queue statics no. of packets with error +//queue statics no. of packets dropped by hw +//queue statics no. of packets dropped by sw + +typedef struct{ + push_back_t push; //call back function + struct atm_vcc * vcc; //opened vcc + struct timeval access_time; //time when last F4/F5 user cells arrive + int free; //whether this queue is occupied, 0: occupied, 1: free + u32 aal5VccCrcErrors; //MIB counter + u32 aal5VccOverSizedSDUs; //MIB counter + +#if defined(AMAZON_ATM_DEBUG) || defined (CONFIG_IFX_ATM_MIB) + u32 qs[QS_MAX]; +#endif +}amazon_atm_queue_t; + + +typedef struct{ + int enable; //enable / disable + u32 max_conn; //maximum number of connections per port + u32 tx_max_cr; //Remaining cellrate for this device for tx direction + u32 tx_rem_cr; //Remaining cellrate for this device for tx direction + u32 tx_cur_cr; //Current cellrate for this device for tx direction +}amazon_atm_port_t; + +typedef struct{ + amazon_aal5_dev_t aal5; + amazon_cbm_dev_t cbm; + amazon_htu_dev_t htu; + amazon_qsb_dev_t qsb; + amazon_swie_dev_t swie; + amazon_mib_counter_t mib_counter; + amazon_atm_queue_t queues[AMAZON_ATM_MAX_QUEUE_NUM]; + amazon_atm_port_t ports[AMAZON_ATM_PORT_NUM]; + atomic_t dma_tx_free_0;//TX_CH0 has availabe descriptors +} amazon_atm_dev_t; + +struct oam_last_activity{ + u8 vpi; //vpi for this connection + u16 vci; //vci for t his connection + struct timeval stamp; //time when last F4/F5 user cells arrive + struct oam_last_activity * next;//for link list purpose +}; + +typedef union{ +#ifdef CONFIG_CPU_LITTLE_ENDIAN + struct{ + u32 tprs :16; + u32 twfq :14; + u32 vbr :1; + u32 reserved :1; + }bit; + u32 w0; +#else + struct{ + u32 reserved :1; + u32 vbr :1; + u32 twfq :14; + u32 tprs :16; + }bit; + u32 w0; +#endif + +}qsb_qptl_t; + +typedef union{ +#ifdef CONFIG_CPU_LITTLE_ENDIAN + struct{ + u32 ts :16; + u32 taus :16; + }bit; + u32 w0; +#else + struct{ + u32 taus :16; + u32 ts :16; + }bit; + u32 w0; +#endif +}qsb_qvpt_t; + + + +struct amazon_atm_cell_header { +#ifdef CONFIG_CPU_LITTLE_ENDIAN + struct{ + u32 clp :1; // Cell Loss Priority + u32 pti :3; // Payload Type Identifier + u32 vci :16; // Virtual Channel Identifier + u32 vpi :8; // Vitual Path Identifier + u32 gfc :4; // Generic Flow Control + }bit; +#else + struct{ + u32 gfc :4; // Generic Flow Control + u32 vpi :8; // Vitual Path Identifier + u32 vci :16; // Virtual Channel Identifier + u32 pti :3; // Payload Type Identifier + u32 clp :1; // Cell Loss Priority + }bit; +#endif +}; + + +/************************ Function Declarations **************************/ +amazon_atm_dev_t * amazon_atm_create(void); +int amazon_atm_open(struct atm_vcc *vcc,push_back_t); +int amazon_atm_send(struct atm_vcc *vcc,struct sk_buff *skb); +int amazon_atm_send_oam(struct atm_vcc *vcc,void *cell, int flags); +void amazon_atm_close(struct atm_vcc *vcc); +void amazon_atm_cleanup(void); +const struct oam_last_activity* get_oam_time_stamp(void); + +//mib-related +int amazon_atm_cell_mib(atm_cell_ifEntry_t * to,u32 itf); +int amazon_atm_aal5_mib(atm_aal5_ifEntry_t * to); +int amazon_atm_vcc_mib(struct atm_vcc *vcc,atm_aal5_vcc_t * to); +int amazon_atm_vcc_mib_x(int vpi, int vci,atm_aal5_vcc_t* to); + +#define AMAZON_WRITE_REGISTER_L(data,addr) do{ *((volatile u32*)(addr)) = (u32)(data); wmb();} while (0) +#define AMAZON_READ_REGISTER_L(addr) (*((volatile u32*)(addr))) +/******************************* ioctl stuff****************************************/ +#define NUM(dev) (MINOR(dev) & 0xf) +/* + * Ioctl definitions + */ +/* Use 'o' as magic number */ +#define AMAZON_ATM_IOC_MAGIC 'o' +/* MIB_CELL: get atm cell level mib counter + * MIB_AAL5: get aal5 mib counter + * MIB_VCC: get vcc mib counter + */ +typedef struct{ + int vpi; + int vci; + atm_aal5_vcc_t mib_vcc; +}atm_aal5_vcc_x_t; +#define AMAZON_ATM_MIB_CELL _IOWR(AMAZON_ATM_IOC_MAGIC, 0, atm_cell_ifEntry_t) +#define AMAZON_ATM_MIB_AAL5 _IOWR(AMAZON_ATM_IOC_MAGIC, 1, atm_aal5_ifEntry_t) +#define AMAZON_ATM_MIB_VCC _IOWR(AMAZON_ATM_IOC_MAGIC, 2, atm_aal5_vcc_x_t) +#define AMAZON_ATM_IOC_MAXNR 3 + +//sockopt +#define SO_AMAZON_ATM_MIB_VCC __SO_ENCODE(SOL_ATM,5,atm_aal5_vcc_t) + +#endif // AMAZON_TPE_H + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/amazon_wdt.h b/target/linux/amazon/files/include/asm-mips/amazon/amazon_wdt.h new file mode 100644 index 0000000000..775dabccfb --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/amazon_wdt.h @@ -0,0 +1,23 @@ +#ifndef AMAZON_WDT_H +#define AMAZON_WDT_H +#ifdef __KERNEL__ +typedef struct wdt_dev{ + char name[16]; + int major; + int minor; + + int full; + char buff[10]; +}wdt_dev; +#define AMAZON_WDT_REG32(addr) (*((volatile u32*)(addr))) +#endif //__KERNEL__ + +//AMAZON_WDT_IOC_START: start the WDT timer (must provide a initial timeout value) +//AMAZON_WDT_IOC_STOP: stop the WDT +//AMAZON_WDT_IOC_PING: reload the timer to initial value (must happend after a AMAZON_WDT_IOC_START) +#define AMAZON_WDT_IOC_MAGIC 0xc0 +#define AMAZON_WDT_IOC_START _IOW( AMAZON_WDT_IOC_MAGIC,0, int) +#define AMAZON_WDT_IOC_STOP _IO( AMAZON_WDT_IOC_MAGIC,1) +#define AMAZON_WDT_IOC_PING _IO( AMAZON_WDT_IOC_MAGIC,2) + +#endif //AMAZON_WDT_H diff --git a/target/linux/amazon/files/include/asm-mips/amazon/atm_defines.h b/target/linux/amazon/files/include/asm-mips/amazon/atm_defines.h new file mode 100644 index 0000000000..8adda20051 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/atm_defines.h @@ -0,0 +1,540 @@ +#ifndef ATM_DEFINES_H +#define ATM_DEFINES_H + +//Registers Base Address +#define IO_BASE_ADDR 0xA0000000 +#define AAL5_BASE_ADDRESS 0x10104400+IO_BASE_ADDR +#define CBM_BASE_ADDRESS 0x10104000+IO_BASE_ADDR +#define HTU_BASE_ADDRESS 0x10105100+IO_BASE_ADDR +#define QSB_BASE_ADDRESS 0x10105000+IO_BASE_ADDR +#define SWIE_BASE_ADDRESS 0x10105200+IO_BASE_ADDR + +//AAL5 Registers +#define AAL5_SISR0_ADDR AAL5_BASE_ADDRESS+0x20 +#define AAL5_SIMR0_ADDR AAL5_BASE_ADDRESS+0x24 +#define AAL5_SISR1_ADDR AAL5_BASE_ADDRESS+0x28 +#define AAL5_SIMR1_ADDR AAL5_BASE_ADDRESS+0x2C +#define AAL5_SMFL_ADDR AAL5_BASE_ADDRESS+0x30 +#define AAL5_SATMHD_ADDR AAL5_BASE_ADDRESS+0x34 +#define AAL5_SCON_ADDR AAL5_BASE_ADDRESS+0x38 +#define AAL5_SCMD_ADDR AAL5_BASE_ADDRESS+0x3C +#define AAL5_RISR0_ADDR AAL5_BASE_ADDRESS+0x40 +#define AAL5_RIMR0_ADDR AAL5_BASE_ADDRESS+0x44 +#define AAL5_RISR1_ADDR AAL5_BASE_ADDRESS+0x48 +#define AAL5_RIMR1_ADDR AAL5_BASE_ADDRESS+0x4C +#define AAL5_RMFL_ADDR AAL5_BASE_ADDRESS+0x50 +#define AAL5_RINTINF0_ADDR AAL5_BASE_ADDRESS+0x54 +#define AAL5_RINTINF1_ADDR AAL5_BASE_ADDRESS+0x58 +#define AAL5_RES5C_ADDR AAL5_BASE_ADDRESS+0x5C +#define AAL5_RIOL_ADDR AAL5_BASE_ADDRESS+0x60 +#define AAL5_RIOM_ADDR AAL5_BASE_ADDRESS+0x64 +#define AAL5_SOOL_ADDR AAL5_BASE_ADDRESS+0x68 +#define AAL5_SOOM_ADDR AAL5_BASE_ADDRESS+0x6C +#define AAL5_RES70_ADDR AAL5_BASE_ADDRESS+0x70 +#define AAL5_RES74_ADDR AAL5_BASE_ADDRESS+0x74 +#define AAL5_RES78_ADDR AAL5_BASE_ADDRESS+0x78 +#define AAL5_RES7C_ADDR AAL5_BASE_ADDRESS+0x7C +#define AAL5_RES80_ADDR AAL5_BASE_ADDRESS+0x80 +#define AAL5_RES84_ADDR AAL5_BASE_ADDRESS+0x84 +#define AAL5_RES88_ADDR AAL5_BASE_ADDRESS+0x88 +#define AAL5_RES8C_ADDR AAL5_BASE_ADDRESS+0x8C +#define AAL5_RES90_ADDR AAL5_BASE_ADDRESS+0x90 +#define AAL5_RES94_ADDR AAL5_BASE_ADDRESS+0x94 +#define AAL5_RES98_ADDR AAL5_BASE_ADDRESS+0x98 +#define AAL5_RES9C_ADDR AAL5_BASE_ADDRESS+0x9C +#define AAL5_RESA0_ADDR AAL5_BASE_ADDRESS+0xA0 +#define AAL5_RESA4_ADDR AAL5_BASE_ADDRESS+0xA4 +#define AAL5_RESA8_ADDR AAL5_BASE_ADDRESS+0xA8 +#define AAL5_RESAC_ADDR AAL5_BASE_ADDRESS+0xAC +#define AAL5_RESB0_ADDR AAL5_BASE_ADDRESS+0xB0 +#define AAL5_RESB4_ADDR AAL5_BASE_ADDRESS+0xB4 +#define AAL5_RESB8_ADDR AAL5_BASE_ADDRESS+0xB8 +#define AAL5_RESBC_ADDR AAL5_BASE_ADDRESS+0xBC +#define AAL5_RESC0_ADDR AAL5_BASE_ADDRESS+0xC0 +#define AAL5_RESC4_ADDR AAL5_BASE_ADDRESS+0xC4 +#define AAL5_RESC8_ADDR AAL5_BASE_ADDRESS+0xC8 +#define AAL5_RESCC_ADDR AAL5_BASE_ADDRESS+0xCC +#define AAL5_RESD0_ADDR AAL5_BASE_ADDRESS+0xD0 +#define AAL5_RESD4_ADDR AAL5_BASE_ADDRESS+0xD4 +#define AAL5_RESD8_ADDR AAL5_BASE_ADDRESS+0xD8 +#define AAL5_RESDC_ADDR AAL5_BASE_ADDRESS+0xDC +#define AAL5_RESE0_ADDR AAL5_BASE_ADDRESS+0xE0 +#define AAL5_RESE4_ADDR AAL5_BASE_ADDRESS+0xE4 +#define AAL5_RESE8_ADDR AAL5_BASE_ADDRESS+0xE8 +#define AAL5_RESEC_ADDR AAL5_BASE_ADDRESS+0xEC +#define AAL5_SSRC0_ADDR AAL5_BASE_ADDRESS+0xF0 +#define AAL5_SSRC1_ADDR AAL5_BASE_ADDRESS+0xF4 +#define AAL5_RSRC0_ADDR AAL5_BASE_ADDRESS+0xF8 +#define AAL5_RSRC1_ADDR AAL5_BASE_ADDRESS+0xFC + +#define AAL5S_ISR_QID_MASK 0xFF000000 +#define AAL5S_ISR_SAB 0x00000100 +#define AAL5S_ISR_SE 0x00000080 +#define AAL5S_ISR_MFLE 0x00000040 +#define AAL5S_ISR_SBE0 0x00000020 +#define AAL5S_ISR_SEG0 0x00000010 +#define AAL5S_ISR_TAB 0x00000004 + +#define AAL5_SIMR_MASK 0x000001c7 +#define AAL5_SIMR_SAB 0x00000100 +#define AAL5_SIMR_SE 0x00000080 +#define AAL5_SIMR_MFLE 0x00000040 +#define AAL5_SIMR_TAB 0x00000004 +#define AAL5_SIMR_SBE0 0x00000002 +#define AAL5_SIMR_SEG0 0x00000001 + +#define AAL5_SCMD_SEQCOUNT_MASK 0x0000ff00 +#define AAL5_SCMD_MODE_POLL 0x00000008 +#define AAL5_SCMD_MODE_COUNT 0x00000000 +#define AAL5_SCMD_AS 0x00000004 +#define AAL5_SCMD_SS 0x00000002 +#define AAL5_SCMD_AR 0x00000001 + +#define AAL5R_ISR_CID_MASK 0xFF000000//ConnectionID +#define AAL5R_ISR_DBC_MASK 0x00FF0000//DiscardedByteCounter +#define AAL5R_ISR_END 0x00002000//End +#define AAL5R_ISR_ICID 0x00001000//InvalidConnectionID +#define AAL5R_ISR_CLP 0x00000800//CellLossPriority +#define AAL5R_ISR_CGST 0x00000400//Congestion +#define AAL5R_ISR_UUE 0x00000200//CPCSUUError +#define AAL5R_ISR_CPIE 0x00000100//CPIError +#define AAL5R_ISR_FE 0x00000080//FrameEnd +#define AAL5R_ISR_MFLE 0x00000040//MaximumFrameLengthExceeded +#define AAL5R_ISR_DBCE 0x00000020//DiscardedByteCounterExceeded +#define AAL5R_ISR_CRC 0x00000010//CRCError +#define AAL5R_ISR_ILEN 0x00000008//InvalidLength +#define AAL5R_ISR_RAB 0x00000004//ReceiveAbort + +#define AAL5_RIMR1_MASK 0x00003ffc +#define AAL5_RIMR1_END 0x00002000//End +#define AAL5_RIMR1_ICID 0x00001000//InvalidConnectionID +#define AAL5_RIMR1_CLP 0x00000800//CellLossPriority +#define AAL5_RIMR1_CGST 0x00000400//Congestion +#define AAL5_RIMR1_UUE 0x00000200//CPCSUUError +#define AAL5_RIMR1_CPIE 0x00000100//CPIError +#define AAL5_RIMR1_FE 0x00000080//FrameEnd +#define AAL5_RIMR1_MFLE 0x00000040//MaximumFrameLengthExceeded +#define AAL5_RIMR1_DBCE 0x00000020//DiscardedByteCounterExceeded +#define AAL5_RIMR1_CRC 0x00000010//CRCError +#define AAL5_RIMR1_ILEN 0x00000008//InvalidLength +#define AAL5_RIMR1_RAB 0x00000004//ReceiveAbort + +//AAL5 Reassambly Errors +#define AAL5_STW1_MASK 0x33//Error mask +#define AAL5_STW0_MASK 0x5c//Error mask +#define AAL5_STW0_BE 0x3//padding bytes mask +#define AAL5_STW1_CBM 0x20//Transfer from CBM to A5R abnormally ended +#define AAL5_STW1_CH 0x10//Invalid Channel number error +#define AAL5_STW1_CLP 0x8//CLP value of cells in packet is 1 +#define AAL5_STW1_CG 0x4//Cell in packet expired congestion +#define AAL5_STW1_UU 0x2//CPCS-UU value error +#define AAL5_STW1_CPI 0x1//CPI value error +#define AAL5_STW0_FE 0x80//Frame end +#define AAL5_STW0_MFL 0x40//Maximum frame length error +#define AAL5_STW0_CRC 0x10//CRC error +#define AAL5_STW0_IL 0x8//Invalid length +#define AAL5_STW0_RA 0x4//Received abort + + + +//CBM Registers +#define CBM_NRTTHR_ADDR CBM_BASE_ADDRESS+0x10//NonRealTimeThreshold +#define CBM_CLP0THR_ADDR CBM_BASE_ADDRESS+0x14//CLP0Threshold +#define CBM_CLP1THR_ADDR CBM_BASE_ADDRESS+0x18//CLP1Threshold +#define CBM_QDOFF_ADDR CBM_BASE_ADDRESS+0x1C//QueueDescriptorOffset +#define CBM_CFG_ADDR CBM_BASE_ADDRESS+0x20//Configuration +#define CBM_HWEXPAR0_ADDR CBM_BASE_ADDRESS+0x24//HWExtractParameter0 +#define CBM_RES28_ADDR CBM_BASE_ADDRESS+0x28 +#define CBM_WMSTAT0_ADDR CBM_BASE_ADDRESS+0x2C +#define CBM_HWEXCMD_ADDR CBM_BASE_ADDRESS+0x30//HWExtractCommand0 +#define CBM_RES34_ADDR CBM_BASE_ADDRESS+0x34 +#define CBM_HWEXSTAT0_ADDR CBM_BASE_ADDRESS+0x38//HWExtractStatus0 +#define CBM_RES3C_ADDR CBM_BASE_ADDRESS+0x3C +#define CBM_RES40_ADDR CBM_BASE_ADDRESS+0x40 +#define CBM_CNT_ADDR CBM_BASE_ADDRESS+0x44//CellCount +#define CBM_RES48_ADDR CBM_BASE_ADDRESS+0x48 +#define CBM_LFR_ADDR CBM_BASE_ADDRESS+0x4C//PointertolastCellinfreeCellQueue +#define CBM_FFR_ADDR CBM_BASE_ADDRESS+0x50//PointertofirstCellinfreeCellQueue +#define CBM_RES54_ADDR CBM_BASE_ADDRESS+0x54 +#define CBM_RES58_ADDR CBM_BASE_ADDRESS+0x58 +#define CBM_RES5C_ADDR CBM_BASE_ADDRESS+0x5C +#define CBM_RES60_ADDR CBM_BASE_ADDRESS+0x60 +#define CBM_RES64_ADDR CBM_BASE_ADDRESS+0x64 +#define CBM_RES68_ADDR CBM_BASE_ADDRESS+0x68 +#define CBM_RES6C_ADDR CBM_BASE_ADDRESS+0x6C +#define CBM_RES70_ADDR CBM_BASE_ADDRESS+0x70 +#define CBM_RES74_ADDR CBM_BASE_ADDRESS+0x74 +#define CBM_RES78_ADDR CBM_BASE_ADDRESS+0x78 +#define CBM_RES7C_ADDR CBM_BASE_ADDRESS+0x7C +#define CBM_RES80_ADDR CBM_BASE_ADDRESS+0x80 +#define CBM_RES84_ADDR CBM_BASE_ADDRESS+0x84 +#define CBM_RES88_ADDR CBM_BASE_ADDRESS+0x88 +#define CBM_RES8C_ADDR CBM_BASE_ADDRESS+0x8C +#define CBM_RES90_ADDR CBM_BASE_ADDRESS+0x90 +#define CBM_RES94_ADDR CBM_BASE_ADDRESS+0x94 +#define CBM_RES98_ADDR CBM_BASE_ADDRESS+0x98 +#define CBM_RES9C_ADDR CBM_BASE_ADDRESS+0x9C +#define CBM_RESA0_ADDR CBM_BASE_ADDRESS+0xA0 +#define CBM_RESA4_ADDR CBM_BASE_ADDRESS+0xA4 +#define CBM_RESA8_ADDR CBM_BASE_ADDRESS+0xA8 +#define CBM_RESAC_ADDR CBM_BASE_ADDRESS+0xAC +#define CBM_RESB0_ADDR CBM_BASE_ADDRESS+0xB0 +#define CBM_RESB4_ADDR CBM_BASE_ADDRESS+0xB4 +#define CBM_RESB8_ADDR CBM_BASE_ADDRESS+0xB8 +#define CBM_RESBC_ADDR CBM_BASE_ADDRESS+0xBC +#define CBM_INTINF0_ADDR CBM_BASE_ADDRESS+0xC0//InterruptInfo0 +#define CBM_INTCMD_ADDR CBM_BASE_ADDRESS+0xC4//InterruptCommand0 +#define CBM_IMR0_ADDR CBM_BASE_ADDRESS+0xC8//InterruptMask +#define CBM_SRC0_ADDR CBM_BASE_ADDRESS+0xCC//ServiceRequestControl +#define CBM_RESD0_ADDR CBM_BASE_ADDRESS+0xD0 +#define CBM_RESD4_ADDR CBM_BASE_ADDRESS+0xD4 +#define CBM_RESD8_ADDR CBM_BASE_ADDRESS+0xD8 +#define CBM_RESDC_ADDR CBM_BASE_ADDRESS+0xDC +#define CBM_RESE0_ADDR CBM_BASE_ADDRESS+0xE0 +#define CBM_AAL5IDIS_ADDR CBM_BASE_ADDRESS+0xE4//MIB-No.EPDdiscardedpacketsupstream +#define CBM_AAL5ODIS_ADDR CBM_BASE_ADDRESS+0xE8//MIB-No.PPDdiscardedpacketsupstream +#define CBM_RESEC_ADDR CBM_BASE_ADDRESS+0xEC +#define CBM_RESF0_ADDR CBM_BASE_ADDRESS+0xF0 +#define CBM_RESF4_ADDR CBM_BASE_ADDRESS+0xF4 +#define CBM_RESF8_ADDR CBM_BASE_ADDRESS+0xF8 +#define CBM_RESFC_ADDR CBM_BASE_ADDRESS+0xFC + +//CBMCFG +#define CBM_CFG_INTLCK0EN 0x00000008 +#define CBM_CFG_INT0HLT 0x00000004 +#define CBM_CFG_START 0x00000001 + +#define CBM_HWEXPAR_PN_A5 0x00002000 +#define CBM_HWEXPAR_PN_CM 0x00000000 +#define CBM_HWEXPAR_SUBADD_PORTMASK 0x00000070 +#define CBM_HWEXPAR_SUBADD_ADU 0x00000000 +#define CBM_HWEXPAR_SUBADD_AAL2 0x00000080 +#define CBM_HWEXPAR_SUBADD_SWIE 0x00000100 + +#define CBM_HWEXCMD_SFE2 0x00000100 +#define CBM_HWEXCMD_FE2 0x00000080 +#define CBM_HWEXCMD_SCE2 0x00000040 +#define CBM_HWEXCMD_SFE1 0x00000020 +#define CBM_HWEXCMD_FE1 0x00000010 +#define CBM_HWEXCMD_SCE1 0x00000008 +#define CBM_HWEXCMD_SFE0 0x00000004 +#define CBM_HWEXCMD_FE0 0x00000002 +#define CBM_HWEXCMD_SCE0 0x00000001 + +#define CBM_INTINF0_QID_MASK 0xFF000000 +#define CBM_INTINF0_ORIGIN_MASK 0x00F00000 +#define CBM_INTINF0_EF 0x00004000 +#define CBM_INTINF0_ACA 0x00002000 +#define CBM_INTINF0_ERR 0x00001000 +#define CBM_INTINF0_DISC 0x00000800 +#define CBM_INTINF0_QSBV 0x00000400 +#define CBM_INTINF0_Q0E 0x00000200 +#define CBM_INTINF0_Q0I 0x00000100 +#define CBM_INTINF0_RDE 0x00000080 +#define CBM_INTINF0_OPF 0x00000040 +#define CBM_INTINF0_NFCA 0x00000020 +#define CBM_INTINF0_CLP1TR 0x00000010 +#define CBM_INTINF0_CLP0TR 0x00000008 +#define CBM_INTINF0_NRTTR 0x00000004 +#define CBM_INTINF0_QFD 0x00000002 +#define CBM_INTINF0_QTR 0x00000001 +#define CBM_INTINF0_QID_SHIFT 24 +//CBM QD Word 3 +#define CBM_QD_W3_QOS_0 0x00000000 +#define CBM_QD_W3_QOS_1 0x40000000 +#define CBM_QD_W3_QOS_2 0x80000000 +#define CBM_QD_W3_QOS_3 0xc0000000 + +#define CBM_QD_W3_DIR_UP 0x20000000 +#define CBM_QD_W3_DIR_DOWN 0x00000000 + +#define CBM_QD_W3_CLPt 0x10000000 +#define CBM_QD_W3_RT 0x08000000 +#define CBM_QD_W3_AAL5 0x04000000 + +#define CBM_QD_W3_INT_NOINT 0x00000000 +#define CBM_QD_W3_INT_ACA 0x01000000 +#define CBM_QD_W3_INT_EOF 0x02000000 +#define CBM_QD_W3_INT_BOTH 0x03000000 + +#define CBM_QD_W3_THRESHOLD_MASK 0x00ff0000 +#define CBM_QD_W3_WM_EN 0x00000010 +#define CBM_QD_W3_HCR 0x00000008 +#define CBM_QD_W3_SBID_MASK 0x00000001 + +#define CBM_QD_W3_THRESHOLD_SHIFT 16 + +//WATER MARK STATUS +#define CBM_WM_NRT_MASK 0x00040000 +#define CBM_WM_CLP0_MASK 0x00020000 +#define CBM_WM_CLP1_MASK 0x00010000 + +//CBMNRTTHR, CBMCLP0THR, CBMCLP0THR +#define CBM_NRT_WM_NONE 0x00000000//no water mark +#define CBM_WM_3_1 0x00010000//3/4 to set, 1/4 to release +#define CBM_WM_3_2 0x00020000//3/4 to set, 2/4 to release +#define CBM_WM_2_1 0x00030000//2/4 to set, 1/4 to release +#define CBM_THR_MASK 0x0000FFFF + +#define CBM_IMR_MASK 0x0000fbff +#define CBM_IMR_reserved 0xFFFF0400 +#define CBM_IMR_RFULL 0x00008000//EndofFrame +#define CBM_IMR_EF 0x00004000//EndofFrame +#define CBM_IMR_ACA 0x00002000//AnyCellArrived +#define CBM_IMR_ERR 0x00001000//FPI Error +#define CBM_IMR_DISC 0x00000800//Discard +#define CBM_IMR_reserved1 0x00000400//reserved +#define CBM_IMR_Q0E 0x00000200//Queue0Extract +#define CBM_IMR_Q0I 0x00000100//Queue0Insert +#define CBM_IMR_RDE 0x00000080//ReadEmptyQueue +#define CBM_IMR_OPF 0x00000040//OncePerFrame +#define CBM_IMR_NFCA 0x00000020//NoFreeCellAvailable +#define CBM_IMR_CLP1TR 0x00000010//CLP1ThresholdReached +#define CBM_IMR_CLP0TR 0x00000008//CLP0ThresholdReached +#define CBM_IMR_NRTTR 0x00000004//NonRealTimeThresholdReached +#define CBM_IMR_QFD 0x00000002//QueueFrameDiscard +#define CBM_IMR_QTR 0x00000001//QueueThresholdReached + +#define CBM_EXSTAT_FB 0x00000010 +#define CBM_EXSTAT_SCB 0x00000008 +#define CBM_EXSTAT_Q0 0x00000004 +#define CBM_EXSTAT_RDE 0x00000002 +#define CBM_EXSTAT_QV 0x00000001 + +//HTU Registers +#define HTU_RX0_ADDR HTU_BASE_ADDRESS+0x10 +#define HTU_RX1_ADDR HTU_BASE_ADDRESS+0x14 +#define HTU_RES18_ADDR HTU_BASE_ADDRESS+0x18 +#define HTU_RES1C_ADDR HTU_BASE_ADDRESS+0x1C +#define HTU_RES20_ADDR HTU_BASE_ADDRESS+0x20 +#define HTU_RES24_ADDR HTU_BASE_ADDRESS+0x24 +#define HTU_RES28_ADDR HTU_BASE_ADDRESS+0x28 +#define HTU_RES2C_ADDR HTU_BASE_ADDRESS+0x2C +#define HTU_PCF0PAT_ADDR HTU_BASE_ADDRESS+0x30 +#define HTU_PCF1PAT_ADDR HTU_BASE_ADDRESS+0x34 +#define HTU_RES38_ADDR HTU_BASE_ADDRESS+0x38 +#define HTU_RES3C_ADDR HTU_BASE_ADDRESS+0x3C +#define HTU_RES40_ADDR HTU_BASE_ADDRESS+0x40 +#define HTU_RES44_ADDR HTU_BASE_ADDRESS+0x44 +#define HTU_RES48_ADDR HTU_BASE_ADDRESS+0x48 +#define HTU_RES4C_ADDR HTU_BASE_ADDRESS+0x4C +#define HTU_PCF0MASK_ADDR HTU_BASE_ADDRESS+0x50 +#define HTU_PCF1MASK_ADDR HTU_BASE_ADDRESS+0x54 +#define HTU_RES58_ADDR HTU_BASE_ADDRESS+0x58 +#define HTU_RES5C_ADDR HTU_BASE_ADDRESS+0x5C +#define HTU_RES60_ADDR HTU_BASE_ADDRESS+0x60 +#define HTU_RES64_ADDR HTU_BASE_ADDRESS+0x64 +#define HTU_RES68_ADDR HTU_BASE_ADDRESS+0x68 +#define HTU_RES6C_ADDR HTU_BASE_ADDRESS+0x6C +#define HTU_TIMEOUT_ADDR HTU_BASE_ADDRESS+0x70 +#define HTU_DESTOAM_ADDR HTU_BASE_ADDRESS+0x74 +#define HTU_DESTRM_ADDR HTU_BASE_ADDRESS+0x78 +#define HTU_DESTOTHER_ADDR HTU_BASE_ADDRESS+0x7C +#define HTU_CFG_ADDR HTU_BASE_ADDRESS+0x80 +#define HTU_RES84_ADDR HTU_BASE_ADDRESS+0x84 +#define HTU_RES88_ADDR HTU_BASE_ADDRESS+0x88 +#define HTU_RES8C_ADDR HTU_BASE_ADDRESS+0x8C +#define HTU_INFNOENTRY_ADDR HTU_BASE_ADDRESS+0x90 +#define HTU_INFTIMEOUT_ADDR HTU_BASE_ADDRESS+0x94 +#define HTU_RES98_STAT HTU_BASE_ADDRESS+0x98 +#define HTU_RES9C_ADDR HTU_BASE_ADDRESS+0x9C +#define HTU_MIBCIUP HTU_BASE_ADDRESS+0xA0//MIB Counter In Unknown Protoc Register +#define HTU_CNTTIMEOUT_ADDR HTU_BASE_ADDRESS+0xA4 +#define HTU_RESA8_ADDR HTU_BASE_ADDRESS+0xA8 +#define HTU_RESAC_ADDR HTU_BASE_ADDRESS+0xAC +#define HTU_RAMADDR_ADDR HTU_BASE_ADDRESS+0xB0 +#define HTU_RAMCMD_ADDR HTU_BASE_ADDRESS+0xB4 +#define HTU_RAMSTAT_ADDR HTU_BASE_ADDRESS+0xB8 +#define HTU_RESBC_ADDR HTU_BASE_ADDRESS+0xBC +#define HTU_RAMDAT1_ADDR HTU_BASE_ADDRESS+0xC0 +#define HTU_RAMDAT2_ADDR HTU_BASE_ADDRESS+0xC4 +#define HTU_RESCC_ADDR HTU_BASE_ADDRESS+0xCC +#define HTU_RESD0_ADDR HTU_BASE_ADDRESS+0xD0 +#define HTU_RESD4_ADDR HTU_BASE_ADDRESS+0xD4 +#define HTU_RESD8_ADDR HTU_BASE_ADDRESS+0xD8 +#define HTU_RESDC_ADDR HTU_BASE_ADDRESS+0xDC +#define HTU_RESE0_ADDR HTU_BASE_ADDRESS+0xE0 +#define HTU_RESE4_ADDR HTU_BASE_ADDRESS+0xE4 +#define HTU_IMR0_ADDR HTU_BASE_ADDRESS+0xE8 +#define HTU_RESEC_ADDR HTU_BASE_ADDRESS+0xEC +#define HTU_ISR0_ADDR HTU_BASE_ADDRESS+0xF0 +#define HTU_RESF4_ADDR HTU_BASE_ADDRESS+0xF4 +#define HTU_SRC0_ADDR HTU_BASE_ADDRESS+0xF8 +#define HTU_RESFC_ADDR HTU_BASE_ADDRESS+0xFC + +//HTU_CFG +#define HTU_CFG_START 0x00000001 + +#define HTU_RAMCMD_RMW 0x00000004 +#define HTU_RAMCMD_RD 0x00000002 +#define HTU_RAMCMD_WR 0x00000001 + +#define HTU_RAMDAT1_VCON 0x00000080//validconnection +#define HTU_RAMDAT1_VCT 0x00000040//vcivalueistransparent +#define HTU_RAMDAT1_QIDS 0x00000020//qid selects a cell in cbm +#define HTU_RAMDAT1_VCI3 0x00000010//vci3->oamqueue +#define HTU_RAMDAT1_VCI4 0x00000008//vci4->oamqueue +#define HTU_RAMDAT1_VCI6 0x00000004//vci6->rmqueue +#define HTU_RAMDAT1_PTI4 0x00000002//pti4->oamqueue +#define HTU_RAMDAT1_PTI5 0x00000001//pti5->oamqueue + +#define HTU_RAMDAT2_PTI6 0x00000800 +#define HTU_RAMDAT2_PTI7 0x00000400 +#define HTU_RAMDAT2_F4U 0x00000200 +#define HTU_RAMDAT2_F5U 0x00000100 +#define HTU_RAMDAT2_QID_MASK 0x000000ff + +#define HTU_ISR_NE 0x00000001 +#define HTU_ISR_TORD 0x00000002 +#define HTU_ISR_IT 0x00000008 +#define HTU_ISR_OTOC 0x00000010 +#define HTU_ISR_ONEC 0x00000020 +#define HTU_ISR_PNE 0x00000040 +#define HTU_ISR_PT 0x00000080 +#define HTU_ISR_MASK 0x000000ff + + +//QSB Registers +#define QSB_BIP0_ADDR QSB_BASE_ADDRESS+0x00 +#define QSB_BIP1_ADDR QSB_BASE_ADDRESS+0x04 +#define QSB_BIP2_ADDR QSB_BASE_ADDRESS+0x08 +#define QSB_BIP3_ADDR QSB_BASE_ADDRESS+0x0C +#define QSB_RSVP_ADDR QSB_BASE_ADDRESS+0x10 +#define QSB_TNOW_ADDR QSB_BASE_ADDRESS+0x14 +#define QSB_TNOWCYC_ADDR QSB_BASE_ADDRESS+0x18 +#define QSB_TAU_ADDR QSB_BASE_ADDRESS+0x1C +#define QSB_L1BRS_ADDR QSB_BASE_ADDRESS+0x20 +#define QSB_SBL_ADDR QSB_BASE_ADDRESS+0x24 +#define QSB_CONFIG_ADDR QSB_BASE_ADDRESS+0x28 +#define QSB_RTM_ADDR QSB_BASE_ADDRESS+0x2C +#define QSB_RTD_ADDR QSB_BASE_ADDRESS+0x30 +#define QSB_RAMAC_ADDR QSB_BASE_ADDRESS+0x34 +#define QSB_ISR_ADDR QSB_BASE_ADDRESS+0x38 +#define QSB_IMR_ADDR QSB_BASE_ADDRESS+0x3C +#define QSB_SRC_ADDR QSB_BASE_ADDRESS+0x40 + +#define QSB_TABLESEL_QVPT 8 +#define QSB_TABLESEL_QPT 1 +#define QSB_TABLESEL_SCT 2 +#define QSB_TABLESEL_SPT 3 +#define QSB_TABLESEL_CALENDARWFQ 4/*notusedbyFW*/ +#define QSB_TABLESEL_L2WFQ 5/*notusedbyFW*/ +#define QSB_TABLESEL_CALENDARRS 6/*notusedbyFW*/ +#define QSB_TABLESEL_L2BITMAPRS 7/*notusedbyFW*/ +#define QSB_TABLESEL_SHIFT 24 +#define QSB_TWFQ_MASK 0x3FFF0000 +#define QSB_TPRS_MASK 0x0000FFFF +#define QSB_SBID_MASK 0xF +#define QSB_TWFQ_SHIFT 16 +#define QSB_SCDRATE_MASK 0x00007FFF +#define QSB_SBVALID_MASK 0x80000000 + +#define QSB_ISR_WFQLE 0x00000001 +#define QSB_ISR_WFQBE 0x00000002 +#define QSB_ISR_RSLE 0x00000004 +#define QSB_ISR_RSBE 0x00000008 +#define QSB_ISR_MUXOV 0x00000010 +#define QSB_ISR_CDVOV 0x00000020 +#define QSB_ISR_PARAMI 0x00000040 +#define QSB_ISR_SLOSS 0x00000080 +#define QSB_ISR_IIPS 0x00000100 + +#define QSB_IMR_WFQLE 0x00000001 +#define QSB_IMR_WFQBE 0x00000002 +#define QSB_IMR_RSLE 0x00000004 +#define QSB_IMR_RSBE 0x00000008 +#define QSB_IMR_MUXOV 0x00000010 +#define QSB_IMR_CDVOV 0x00000020 +#define QSB_IMR_PARAMI 0x00000040 +#define QSB_IMR_SLOSS 0x00000080 +#define QSB_IMR_IIPS 0x00000100 + +#define QSB_READ 0x0 +#define QSB_WRITE 0x80000000 +#define QSB_READ_ALL 0xFFFFFFFF + +#if 1 //some bug with QSB access mask +#define QSB_QPT_SET_MASK 0x0 +#define QSB_QVPT_SET_MASK 0x0 +#define QSB_SET_SCT_MASK 0x0 +#define QSB_SET_SPT_MASK 0x0 +#define QSB_SET_SPT_SBVALID_MASK 0x7FFFFFFF +#else //some bug with QSB access mask +#define QSB_QPT_SET_MASK 0x80000000 +#define QSB_QVPT_SET_MASK 0x0 +#define QSB_SET_SCT_MASK 0xFFFFFFE0 +#define QSB_SET_SPT_MASK 0x7FF8C000 +#define QSB_SET_SPT_SBVALID_MASK 0x7FFFFFFF +#endif //some bug with QSB access mask + +#define QSB_SPT_SBVALID 0x80000000 + +#define QSB_RAMAC_REG_LOW 0x0 +#define QSB_RAMAC_REG_HIGH 0x00010000 + +#define SRC_SRE_ENABLE 0x1000 +#define SRC_CLRR 0x4000 //request clear bit + + + +//SWIE Registers +#define SWIE_IQID_ADDR SWIE_BASE_ADDRESS+0x0c//SWIEInsertQueueDescriptor +#define SWIE_ICMD_ADDR SWIE_BASE_ADDRESS+0x10//SWIEInsertCommand +#define SWIE_ISTAT_ADDR SWIE_BASE_ADDRESS+0x14//SWIEInsertStatus +#define SWIE_ESTAT_ADDR SWIE_BASE_ADDRESS+0x18//SWIEExtractStatus +#define SWIE_ISRC_ADDR SWIE_BASE_ADDRESS+0x74//SWIEInsertServiceRequestControl +#define SWIE_ESRC_ADDR SWIE_BASE_ADDRESS+0x78//SWIEExtractServiceRequestControl +#define SWIE_ICELL_ADDR SWIE_BASE_ADDRESS+0x80//SWIEInsertCell(0x80-0xb4) +#define SWIE_ECELL_ADDR SWIE_BASE_ADDRESS+0xc0//SWIEExtractCell(0xc0-0xf4) + +#define SWIE_ISTAT_DONE 0x1 +#define SWIE_ESTAT_DONE 0x1 +#define SWIE_ICMD_START 0x00000001//Startcommandforinsertion +#define SWIE_CBM_SCE0 CBM_HWEXCMD_SCE0//CBMcommandforSingle-Cell-Extract +#define SWIE_CBM_PID_SUBADDR 0x00001000//CBMPortIDandSubAddressforUTOPIA + +//Extracted cell format +//52bytes AAL0 PDU + "Input cell additional data"(14bits) +#define SWIE_ADDITION_DATA_MASK 0x7fff +#define SWIE_EPORT_MASK 0x7000//Source ID (000 AUB0, 001 AUB1) +#define SWIE_EF4USER_MASK 0x800 +#define SWIE_EF5USER_MASK 0x400 +#define SWIE_EOAM_MASK 0x200 +#define SWIE_EAUU_MASK 0x100 +#define SWIE_EVCI3_MASK 0x80 +#define SWIE_EVCI4_MASK 0x40 +#define SWIE_EVCI6_MASK 0x20 +#define SWIE_EPTI4_MASK 0x10 +#define SWIE_EPTI5_MASK 0x8 +#define SWIE_EPTI6_MASK 0x4 +#define SWIE_EPTI7_MASK 0x2 +#define SWIE_ECRC10ERROR_MASK 0x1 + +#define CBM_CELL_SIZE 0x40 +#define CBM_QD_SIZE 0x10 +#define AAL5R_TRAILER_LEN 12 +#define AAL5S_INBOUND_HEADER 8 + +//constants +//TODO: to be finalized by system guys +//DMA QOS defined by ATM QoS Service type +#define DMA_RX_CH0 0 +#define DMA_RX_CH1 1 +#define DMA_TX_CH0 0 +#define DMA_TX_CH1 1 +#define CBR_DMA_QOS CBM_QD_W3_QOS_0 +#define VBR_RT_DMA_QOS CBM_QD_W3_QOS_0 +#define VBR_NRT_DMA_QOS CBM_QD_W3_QOS_0 +#define UBR_PLUS_DMA_QOS CBM_QD_W3_QOS_0 +#define UBR_DMA_QOS CBM_QD_W3_QOS_0 + +#define SRC_TOS_MIPS 0 +#define AAL5R_SRPN 0x00000006//a5rneedshigherprioritythanDR +#define AAL5S_SRPN 0x00000005 +#define CBM_MIPS_SRPN 0x00000004 +#define QSB_SRPN 0x00000023 +#define HTU_SRPN1 0x00000022 +#define HTU_SRPN0 0x00000021 + +#endif //ATM_DEFINES_H + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/atm_mib.h b/target/linux/amazon/files/include/asm-mips/amazon/atm_mib.h new file mode 100644 index 0000000000..f863342580 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/atm_mib.h @@ -0,0 +1,142 @@ +#ifndef AMAZON_ATM_MIB_H +#define AMAZON_ATM_MIB_H + +#ifdef CONFIG_IFX_ATM_MIB +#include <asm/types.h> +#ifdef __KERNEL__ +#include <linux/list.h> +#endif +#endif /* CONFIG_IFX_ATM_MIB */ + +#ifndef __KERNEL__ +#include <atmMIB/local_list.h> +typedef unsigned int __u32; +#endif + +typedef struct{ + __u32 ifHCInOctets_h; + __u32 ifHCInOctets_l; + __u32 ifHCOutOctets_h; + __u32 ifHCOutOctets_l; + __u32 ifInErrors; + __u32 ifInUnknownProtos; + __u32 ifOutErrors; +}atm_cell_ifEntry_t; + +typedef struct{ + __u32 ifHCInOctets_h; + __u32 ifHCInOctets_l; + __u32 ifHCOutOctets_h; + __u32 ifHCOutOctets_l; + __u32 ifInUcastPkts; + __u32 ifOutUcastPkts; + __u32 ifInErrors; + __u32 ifInDiscards; + __u32 ifOutErros; + __u32 ifOutDiscards; +}atm_aal5_ifEntry_t; + +typedef struct{ + __u32 aal5VccCrcErrors; + __u32 aal5VccSarTimeOuts;//no timer support yet + __u32 aal5VccOverSizedSDUs; +}atm_aal5_vcc_t; + +#if defined(CONFIG_IFX_ATM_MIB) || defined(IFX_CONFIG_SNMP_ATM_MIB) +/* ATM-MIB data structures */ +typedef struct atmIfConfEntry { + int ifIndex; + int atmInterfaceMaxVpcs; + int atmInterfaceMaxVccs; + int atmInterfaceConfVpcs; + int atmInterfaceConfVccs; + int atmInterfaceMaxActiveVpiBits; + int atmInterfaceMaxActiveVciBits; + int atmInterfaceIlmiVpi; + int atmInterfaceIlmiVci; + int atmInterfaceAddressType; + char atmInterfaceAdminAddress[40]; + unsigned long atmInterfaceMyNeighborIpAddress; + char atmInterfaceMyNeighborIfName[20]; + int atmInterfaceCurrentMaxVpiBits; + int atmInterfaceCurrentMaxVciBits; + char atmInterfaceSubscrAddress[40]; + int flags; +}atmIfConfEntry; + +typedef struct atmTrafficDescParamEntry { + /* Following three parameters are used to update VCC QoS values */ + int ifIndex; + short atmVclvpi; + int atmVclvci; + + unsigned int atmTrafficParamIndex; + unsigned char traffic_class; + int max_pcr; + /* Subramani: Added min_pcr */ + int min_pcr; + int cdv; + int scr; + int mbs; + int atmTrafficRowStatus; + int atmTrafficFrameDiscard; + struct list_head vpivci_head; + struct list_head list; +}atmTrafficDescParamEntry; + + +typedef struct atmVclEntry { + int ifIndex; + short atmVclvpi; + int atmVclvci; + char vpivci[20]; + int atmVclAdminStatus; + int atmVclOperStatus; + unsigned long atmVclLastChange; + struct atmTrafficDescParamEntry *atmVclRxTrafficPtr; + struct atmTrafficDescParamEntry *atmVclTxTrafficPtr; + unsigned char atmVccAalType; + unsigned int atmVccAal5TxSduSize; + unsigned int atmVccAal5RxSduSize; + int atmVccAal5Encap; + int atmVclRowStatus; + int atmVclCastType; + int atmVclConnKind; + struct list_head list; + int flags; +}atmVclEntry; + + +typedef union union_atmptrs { + struct atmIfConfEntry *atmIfConfEntry_ptr; + struct atmTrafficDescParamEntry *atmTrafficDescParamEntry_ptr; + struct atmVclEntry *atmVclEntry_ptr; +}union_atmptrs; + +/* ATM Character device major number */ +#define ATM_MEI_MAJOR 107 + +/* Protocol Constants */ +#define IFX_PROTO_RAW 0 +#define IFX_PROTO_BR2684 1 +#define IFX_PROTO_PPPOATM 2 +#define IFX_PROTO_CLIP 3 + +/* IOCTL Command Set for ATM-MIB */ +#define GET_ATM_IF_CONF_DATA 0x0AB0 +#define SET_ATM_IF_CONF_DATA 0x0AB1 + +#define SET_ATM_QOS_DATA 0x0BC0 + +#define GET_ATM_VCL_DATA 0x0CD0 +#define SET_ATM_VCL_DATA 0x0CD1 + +#define FIND_VCC_IN_KERNEL 0x0DE0 + +/* User defined flags for VCL Table */ +#define ATMVCCAAL5CPCSTRANSMITSDUSIZE 9 +#define ATMVCCAAL5CPCSRECEIVESDUSIZE 10 + +#endif /* CONFIG_IFX_ATM_MIB || IFX_CONFIG_SNMP_ATM_MIB */ + +#endif //AMAZON_ATM_MIB_H diff --git a/target/linux/amazon/files/include/asm-mips/amazon/ifx_peripheral_definitions.h b/target/linux/amazon/files/include/asm-mips/amazon/ifx_peripheral_definitions.h new file mode 100644 index 0000000000..65f14e405f --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/ifx_peripheral_definitions.h @@ -0,0 +1,96 @@ +//************************************************************************* +//* Summary of definitions which are used in each peripheral * +//************************************************************************* + +#ifndef peripheral_definitions_h +#define peripheral_definitions_h + +typedef unsigned char UINT8; +typedef signed char INT8; +typedef unsigned short UINT16; +typedef signed short INT16; +typedef unsigned int UINT32; +typedef signed int INT32; +typedef unsigned long long UINT64; +typedef signed long long INT64; + +#define REG8( addr ) (*(volatile UINT8 *) (addr)) +#define REG16( addr ) (*(volatile UINT16 *)(addr)) +#define REG32( addr ) (*(volatile UINT32 *)(addr)) +#define REG64( addr ) (*(volatile UINT64 *)(addr)) + +/* define routine to set FPI access in Supervisor Mode */ +#define IFX_SUPERVISOR_ON() REG32(FB0_CFG) = 0x01 +/* Supervisor mode ends, following functions will be done in User mode */ +#define IFX_SUPERVISOR_OFF() REG32(FB0_CFG) = 0x00 +/* Supervisor mode ends, following functions will be done in User mode */ +#define IFX_SUPERVISOR_MODE() REG32(FB0_CFG) +/* Supervisor mode ends, following functions will be done in User mode */ +#define IFX_SUPERVISOR_SET(svm) REG32(FB0_CFG) = svm +/* enable all Interrupts in IIU */ +//#define IFX_ENABLE_IRQ(irq_mask, im_base) REG32(im_base | IIU_MASK) = irq_mask +///* get all high priority interrupt bits in IIU */ +//#define IFX_GET_IRQ_MASKED(im_base) REG32(im_base | IIU_IRMASKED) +///* signal ends of interrupt to IIU */ +//#define IFX_CLEAR_DIRECT_IRQ(irq_bit, im_base) REG32(im_base | IIU_IR) = irq_bit +///* force IIU interrupt register */ +//#define IFX_FORCE_IIU_REGISTER(data, im_base) REG32(im_base | IIU_IRDEBUG) = data +///* get all bits of interrupt register */ +//#define IFX_GET_IRQ_UNMASKED(im_base) REG32(im_base | IIU_IR) +/* insert a NOP instruction */ +#define NOP _nop() +/* CPU goes to power down mode until interrupt occurs */ +#define IFX_CPU_SLEEP _sleep() +/* enable all interrupts to CPU */ +#define IFX_CPU_ENABLE_ALL_INTERRUPT sys_enable_int() +/* get all low priority interrupt bits in peripheral */ +#define IFX_GET_LOW_PRIO_IRQ(int_reg) REG32(int_reg) +/* clear low priority interrupt bit in peripheral */ +#define IFX_CLEAR_LOW_PRIO_IRQ(irq_bit, int_reg) REG32(int_reg) = irq_bit +/* write FPI bus */ +#define WRITE_FPI_BYTE(data, addr) REG8(addr) = data +#define WRITE_FPI_16BIT(data, addr) REG16(addr) = data +#define WRITE_FPI_32BIT(data, addr) REG32(addr) = data +/* read FPI bus */ +#define READ_FPI_BYTE(addr) REG8(addr) +#define READ_FPI_16BIT(addr) REG16(addr) +#define READ_FPI_32BIT(addr) REG32(addr) +/* write peripheral register */ +#define WRITE_PERIPHERAL_REGISTER(data, addr) REG32(addr) = data + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +#define WRITE_PERIPHERAL_REGISTER_16(data, addr) REG16(addr) = data +#define WRITE_PERIPHERAL_REGISTER_8(data, addr) REG8(addr) = data +#else //not CONFIG_CPU_LITTLE_ENDIAN +#define WRITE_PERIPHERAL_REGISTER_16(data, addr) REG16(addr+2) = data +#define WRITE_PERIPHERAL_REGISTER_8(data, addr) REG8(addr+3) = data +#endif //CONFIG_CPU_LITTLE_ENDIAN + +/* read peripheral register */ +#define READ_PERIPHERAL_REGISTER(addr) REG32(addr) + +/* read/modify(or)/write peripheral register */ +#define RMW_OR_PERIPHERAL_REGISTER(data, addr) REG32(addr) = REG32(addr) | data +/* read/modify(and)/write peripheral register */ +#define RMW_AND_PERIPHERAL_REGISTER(data, addr) REG32(addr) = REG32(addr) & (UINT32)data + +/* CPU-independent mnemonic constants */ +/* CLC register bits */ +#define IFX_CLC_ENABLE 0x00000000 +#define IFX_CLC_DISABLE 0x00000001 +#define IFX_CLC_DISABLE_STATUS 0x00000002 +#define IFX_CLC_SUSPEND_ENABLE 0x00000004 +#define IFX_CLC_CLOCK_OFF_DISABLE 0x00000008 +#define IFX_CLC_OVERWRITE_SPEN_FSOE 0x00000010 +#define IFX_CLC_FAST_CLOCK_SWITCH_OFF 0x00000020 +#define IFX_CLC_RUN_DIVIDER_MASK 0x0000FF00 +#define IFX_CLC_RUN_DIVIDER_OFFSET 8 +#define IFX_CLC_SLEEP_DIVIDER_MASK 0x00FF0000 +#define IFX_CLC_SLEEP_DIVIDER_OFFSET 16 +#define IFX_CLC_SPECIFIC_DIVIDER_MASK 0x00FF0000 +#define IFX_CLC_SPECIFIC_DIVIDER_OFFSET 24 + +/* number of cycles to wait for interrupt service routine to be called */ +#define WAIT_CYCLES 50 + +#endif /* PERIPHERAL_DEFINITIONS_H not yet defined */ diff --git a/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc.h b/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc.h new file mode 100644 index 0000000000..e5d73ad4ec --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc.h @@ -0,0 +1,263 @@ +/* + * ifx_ssc.h defines some data sructures used in ifx_ssc.c + * + * Copyright (C) 2004 Michael Schoenenborn (IFX COM TI BT) + * + * + */ + +#ifndef __IFX_SSC_H +#define __IFX_SSC_H +#ifdef __KERNEL__ +#include <asm/amazon/ifx_ssc_defines.h> +#endif //__KERNEL__ + +#define PORT_CNT 1 // assume default value + +/* symbolic constants to be used in SSC routines */ + +// ### TO DO: bad performance +#define IFX_SSC_TXFIFO_ITL 1 +#define IFX_SSC_RXFIFO_ITL 1 + + + +struct ifx_ssc_statistics{ + unsigned int abortErr; /* abort error */ + unsigned int modeErr; /* master/slave mode error */ + unsigned int txOvErr; /* TX Overflow error */ + unsigned int txUnErr; /* TX Underrun error */ + unsigned int rxOvErr; /* RX Overflow error */ + unsigned int rxUnErr; /* RX Underrun error */ + unsigned int rxBytes; + unsigned int txBytes; +}; + + +struct ifx_ssc_hwopts { + unsigned int AbortErrDetect :1; /* Abort Error detection (in slave mode) */ + unsigned int rxOvErrDetect :1; /* Receive Overflow Error detection */ + unsigned int rxUndErrDetect :1; /* Receive Underflow Error detection */ + unsigned int txOvErrDetect :1; /* Transmit Overflow Error detection */ + unsigned int txUndErrDetect :1; /* Transmit Underflow Error detection */ + unsigned int echoMode :1; /* Echo mode */ + unsigned int loopBack :1; /* Loopback mode */ + unsigned int idleValue :1; /* Idle value */ + unsigned int clockPolarity :1; /* Idle clock is high or low */ + unsigned int clockPhase :1; /* Tx on trailing or leading edge*/ + unsigned int headingControl :1; /* LSB first or MSB first */ + unsigned int dataWidth :6; /* from 2 up to 32 bits */ + unsigned int masterSelect :1; /* Master or Slave mode */ + unsigned int modeRxTx :2; /* rx/tx mode */ + unsigned int gpoCs :8; /* choose outputs to use for chip select */ + unsigned int gpoInv :8; /* invert GPO outputs */ +}; + + +struct ifx_ssc_frm_opts { + bool FrameEnable; // SFCON.SFEN + unsigned int DataLength; // SFCON.DLEN + unsigned int PauseLength; // SFCON.PLEN + unsigned int IdleData; // SFCON.IDAT + unsigned int IdleClock; // SFCON.ICLK + bool StopAfterPause; // SFCON.STOP +}; + +struct ifx_ssc_frm_status { + bool DataBusy; // SFSTAT.DBSY + bool PauseBusy; // SFSTAT.PBSY + unsigned int DataCount; // SFSTAT.DCNT + unsigned int PauseCount; // SFSTAT.PCNT + bool EnIntAfterData; // SFCON.IBEN + bool EnIntAfterPause;// SFCON.IAEN +}; + +typedef struct { + char *buf; + size_t len; +} ifx_ssc_buf_item_t; + + +// data structures for batch execution +typedef union { + struct { + bool save_options; + } init; + ifx_ssc_buf_item_t read; + ifx_ssc_buf_item_t write; + ifx_ssc_buf_item_t rd_wr; + unsigned int set_baudrate; + struct ifx_ssc_frm_opts set_frm; + unsigned int set_gpo; + struct ifx_ssc_hwopts set_hwopts; +}ifx_ssc_batch_cmd_param; + +struct ifx_ssc_batch_list { + unsigned int cmd; + ifx_ssc_batch_cmd_param cmd_param; + struct ifx_ssc_batch_list *next; +}; + +#ifdef __KERNEL__ +#define IFX_SSC_IS_MASTER(p) ((p)->opts.masterSelect == SSC_MASTER_MODE) + + +struct ifx_ssc_port{ + unsigned long mapbase; + struct ifx_ssc_hwopts opts; + struct ifx_ssc_statistics stats; + struct ifx_ssc_frm_status frm_status; + struct ifx_ssc_frm_opts frm_opts; + /* wait queue for ifx_ssc_read() */ + wait_queue_head_t rwait, pwait; + int port_nr; + char port_is_open; /* exclusive open - boolean */ +// int no_of_bits; /* number of _valid_ bits */ +// int elem_size; /* shift for element (no of bytes)*/ + /* buffer and pointers to the read/write position */ + char *rxbuf; /* buffer for RX */ + char *rxbuf_end; /* buffer end pointer for RX */ + volatile char *rxbuf_ptr; /* buffer write pointer for RX */ + char *txbuf; /* buffer for TX */ + char *txbuf_end; /* buffer end pointer for TX */ + volatile char *txbuf_ptr; /* buffer read pointer for TX */ + unsigned int baud; + /* each channel has its own interrupts */ + /* (transmit/receive/error/frame) */ + unsigned int txirq, rxirq, errirq, frmirq; +}; +/* default values for SSC configuration */ +// values of CON +#define IFX_SSC_DEF_IDLE_DATA 1 /* enable */ +#define IFX_SSC_DEF_BYTE_VALID_CTL 1 /* enable */ +#define IFX_SSC_DEF_DATA_WIDTH 32 /* bits */ +#define IFX_SSC_DEF_ABRT_ERR_DETECT 0 /* disable */ +#define IFX_SSC_DEF_RO_ERR_DETECT 1 /* enable */ +#define IFX_SSC_DEF_RU_ERR_DETECT 0 /* disable */ +#define IFX_SSC_DEF_TO_ERR_DETECT 0 /* disable */ +#define IFX_SSC_DEF_TU_ERR_DETECT 0 /* disable */ +#define IFX_SSC_DEF_LOOP_BACK 0 /* disable */ +#define IFX_SSC_DEF_ECHO_MODE 0 /* disable */ +#define IFX_SSC_DEF_CLOCK_POLARITY 0 /* low */ +#define IFX_SSC_DEF_CLOCK_PHASE 1 /* 0: shift on leading edge, latch on trailling edge, 1, otherwise */ +#define IFX_SSC_DEF_HEADING_CONTROL IFX_SSC_MSB_FIRST +#define IFX_SSC_DEF_MODE_RXTX IFX_SSC_MODE_RXTX +// other values +#define IFX_SSC_DEF_MASTERSLAVE IFX_SSC_MASTER_MODE /* master */ +#define IFX_SSC_DEF_BAUDRATE 1000000 +#define IFX_SSC_DEF_RMC 0x10 + +#define IFX_SSC_DEF_TXFIFO_FL 8 +#define IFX_SSC_DEF_RXFIFO_FL 1 + +#if 1 //TODO +#define IFX_SSC_DEF_GPO_CS 2 /* no chip select */ +#define IFX_SSC_DEF_GPO_INV 0 /* no chip select */ +#else +#error "what is ur Chip Select???" +#endif +#define IFX_SSC_DEF_SFCON 0 /* no serial framing */ +#if 0 +#define IFX_SSC_DEF_IRNEN IFX_SSC_T_BIT | /* enable all int's */\ + IFX_SSC_R_BIT | IFX_SSC_E_BIT | IFX_SSC_F_BIT +#endif +#define IFX_SSC_DEF_IRNEN IFX_SSC_T_BIT | /* enable all int's */\ + IFX_SSC_R_BIT | IFX_SSC_E_BIT +#endif /* __KERNEL__ */ + +// batch execution commands +#define IFX_SSC_BATCH_CMD_INIT 1 +#define IFX_SSC_BATCH_CMD_READ 2 +#define IFX_SSC_BATCH_CMD_WRITE 3 +#define IFX_SSC_BATCH_CMD_RD_WR 4 +#define IFX_SSC_BATCH_CMD_SET_BAUDRATE 5 +#define IFX_SSC_BATCH_CMD_SET_HWOPTS 6 +#define IFX_SSC_BATCH_CMD_SET_FRM 7 +#define IFX_SSC_BATCH_CMD_SET_GPO 8 +#define IFX_SSC_BATCH_CMD_FIFO_FLUSH 9 +//#define IFX_SSC_BATCH_CMD_ +//#define IFX_SSC_BATCH_CMD_ +#define IFX_SSC_BATCH_CMD_END_EXEC 0 + +/* Macros to configure SSC hardware */ +/* headingControl: */ +#define IFX_SSC_LSB_FIRST 0 +#define IFX_SSC_MSB_FIRST 1 +/* dataWidth: */ +#define IFX_SSC_MIN_DATA_WIDTH 2 +#define IFX_SSC_MAX_DATA_WIDTH 32 +/* master/slave mode select */ +#define IFX_SSC_MASTER_MODE 1 +#define IFX_SSC_SLAVE_MODE 0 +/* rx/tx mode */ +// ### TO DO: !!! ATTENTION! Hardware dependency => move to ifx_ssc_defines.h +#define IFX_SSC_MODE_RXTX 0 +#define IFX_SSC_MODE_RX 1 +#define IFX_SSC_MODE_TX 2 +#define IFX_SSC_MODE_OFF 3 +#define IFX_SSC_MODE_MASK IFX_SSC_MODE_RX | IFX_SSC_MODE_TX + +/* GPO values */ +#define IFX_SSC_MAX_GPO_OUT 7 + +#define IFX_SSC_RXREQ_BLOCK_SIZE 32768 + +/***********************/ +/* defines for ioctl's */ +/***********************/ +#define IFX_SSC_IOCTL_MAGIC 'S' +/* read out the statistics */ +#define IFX_SSC_STATS_READ _IOR(IFX_SSC_IOCTL_MAGIC, 1, struct ifx_ssc_statistics) +/* clear the statistics */ +#define IFX_SSC_STATS_RESET _IO(IFX_SSC_IOCTL_MAGIC, 2) +/* set the baudrate */ +#define IFX_SSC_BAUD_SET _IOW(IFX_SSC_IOCTL_MAGIC, 3, unsigned int) +/* get the current baudrate */ +#define IFX_SSC_BAUD_GET _IOR(IFX_SSC_IOCTL_MAGIC, 4, unsigned int) +/* set hardware options */ +#define IFX_SSC_HWOPTS_SET _IOW(IFX_SSC_IOCTL_MAGIC, 5, struct ifx_ssc_hwopts) +/* get the current hardware options */ +#define IFX_SSC_HWOPTS_GET _IOR(IFX_SSC_IOCTL_MAGIC, 6, struct ifx_ssc_hwopts) +/* set transmission mode */ +#define IFX_SSC_RXTX_MODE_SET _IOW(IFX_SSC_IOCTL_MAGIC, 7, unsigned int) +/* get the current transmission mode */ +#define IFX_SSC_RXTX_MODE_GET _IOR(IFX_SSC_IOCTL_MAGIC, 8, unsigned int) +/* abort transmission */ +#define IFX_SSC_ABORT _IO(IFX_SSC_IOCTL_MAGIC, 9) +#define IFX_SSC_FIFO_FLUSH _IO(IFX_SSC_IOCTL_MAGIC, 9) + +/* set general purpose outputs */ +#define IFX_SSC_GPO_OUT_SET _IOW(IFX_SSC_IOCTL_MAGIC, 32, unsigned int) +/* clear general purpose outputs */ +#define IFX_SSC_GPO_OUT_CLR _IOW(IFX_SSC_IOCTL_MAGIC, 33, unsigned int) +/* get general purpose outputs */ +#define IFX_SSC_GPO_OUT_GET _IOR(IFX_SSC_IOCTL_MAGIC, 34, unsigned int) + +/*** serial framing ***/ +/* get status of serial framing */ +#define IFX_SSC_FRM_STATUS_GET _IOR(IFX_SSC_IOCTL_MAGIC, 48, struct ifx_ssc_frm_status) +/* get counter reload values and control bits */ +#define IFX_SSC_FRM_CONTROL_GET _IOR(IFX_SSC_IOCTL_MAGIC, 49, struct ifx_ssc_frm_opts) +/* set counter reload values and control bits */ +#define IFX_SSC_FRM_CONTROL_SET _IOW(IFX_SSC_IOCTL_MAGIC, 50, struct ifx_ssc_frm_opts) + + +/*** batch execution ***/ +/* do batch execution */ +#define IFX_SSC_BATCH_EXEC _IOW(IFX_SSC_IOCTL_MAGIC, 64, struct ifx_ssc_batch_list) + + +#ifdef __KERNEL__ +// routines from ifx_ssc.c +// ### TO DO +/* kernel interface for read and write */ +ssize_t ifx_ssc_kread(int, char *, size_t); +ssize_t ifx_ssc_kwrite(int, const char *, size_t); + +#ifdef CONFIG_IFX_VP_KERNEL_TEST +void ifx_ssc_tc(void); +#endif // CONFIG_IFX_VP_KERNEL_TEST + +#endif //__KERNEL__ +#endif // __IFX_SSC_H + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc_defines.h b/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc_defines.h new file mode 100644 index 0000000000..46157dcbd6 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/ifx_ssc_defines.h @@ -0,0 +1,552 @@ +#ifndef IFX_SSC_DEFINES_H +#define IFX_SSC_DEFINES_H + +#include "ifx_peripheral_definitions.h" + +/* maximum SSC FIFO size */ +#define IFX_SSC_MAX_FIFO_SIZE 32 + +/* register map of SSC */ + +/* address of the Clock Control Register of the SSC */ +#define IFX_SSC_CLC 0x00000000 +/* IFX_SSC_CLC register is significant in bits 23 downto 8 and in bits 5, 3, 2, 0 + bit 1 is hardware modified*/ +#define IFX_SSC_CLC_readmask 0x00FFFFEF +#define IFX_SSC_CLC_writemask 0x00FFFF3D +#define IFX_SSC_CLC_hwmask 0x00000002 +#define IFX_SSC_CLC_dontcare (IFX_SSC_CLC_readmask & IFX_SSC_CLC_writemask & ~IFX_SSC_CLC_hwmask) + +/* address of Port Input Select Register of the SSC */ +#define IFX_SSC_PISEL 0x00000004 +/* IFX_SSC_PISEL register is significant in lowest three bits only */ +#define IFX_SSC_PISEL_readmask 0x00000007 +#define IFX_SSC_PISEL_writemask 0x00000007 +#define IFX_SSC_PISEL_hwmask 0x00000000 +#define IFX_SSC_PISEL_dontcare (IFX_SSC_PISEL_readmask & IFX_SSC_PISEL_writemask & ~IFX_SSC_PISEL_hwmask) + +/* address of Identification Register of the SSC */ +#define IFX_SSC_ID 0x00000008 +/* IFX_SSC_ID register is significant in no bit */ +#define IFX_SSC_ID_readmask 0x0000FF3F +#define IFX_SSC_ID_writemask 0x00000000 +#define IFX_SSC_ID_hwmask 0x00000000 +#define IFX_SSC_ID_dontcare (IFX_SSC_ID_readmask & IFX_SSC_ID_writemask & ~IFX_SSC_ID_hwmask) + +/* address of the Control Register of the SSC */ +#define IFX_SSC_CON 0x00000010 +/* IFX_SSC_CON register is significant in bits 23:22, 20:16 and 12:0 */ +#define IFX_SSC_CON_readmask 0x01DF1FFF +#define IFX_SSC_CON_writemask 0x01DF1FFF +#define IFX_SSC_CON_hwmask 0x00000000 +#define IFX_SSC_CON_dontcare (IFX_SSC_CON_readmask & IFX_SSC_CON_writemask & ~IFX_SSC_CON_hwmask) + + +/* address of the Status Register of the SSC */ +#define IFX_SSC_STATE 0x00000014 +/* IFX_SSC_STATE register is readable in bits 30:28, 26:24, 20:16, 12:7 and 2:0 + all bits except 1:0 are hardware modified */ +#define IFX_SSC_STATE_readmask 0x771F3F87 +#define IFX_SSC_STATE_writemask 0x00000000 +#define IFX_SSC_STATE_hwmask 0x771F3F84 +#define IFX_SSC_STATE_dontcare (IFX_SSC_STATE_readmask & IFX_SSC_STATE_writemask & ~IFX_SSC_STATE_hwmask) + +/* address of the Write Hardware Modified Control Register Bits of the SSC */ +#define IFX_SSC_WHBSTATE 0x00000018 +/* IFX_SSC_WHBSTATE register is write only */ +#define IFX_SSC_WHBSTATE_readmask 0x00000000 +#define IFX_SSC_WHBSTATE_writemask 0x0000FFFF +#define IFX_SSC_WHBSTATE_hwmask 0x00000000 +#define IFX_SSC_WHBSTATE_dontcare (IFX_SSC_WHBSTATE_readmask & IFX_SSC_WHBSTATE_writemask & ~IFX_SSC_WHBSTATE_hwmask) + +/* address of the Baudrate Timer Reload Register of the SSC */ +#define IFX_SSC_BR 0x00000040 +/* IFX_SSC_BR register is significant in bit 15 downto 0*/ +#define IFX_SSC_BR_readmask 0x0000FFFF +#define IFX_SSC_BR_writemask 0x0000FFFF +#define IFX_SSC_BR_hwmask 0x00000000 +#define IFX_SSC_BR_dontcare (IFX_SSC_BR_readmask & IFX_SSC_BR_writemask & ~IFX_SSC_BR_hwmask) + +/* address of the Baudrate Timer Status Register of the SSC */ +#define IFX_SSC_BRSTAT 0x00000044 +/* IFX_SSC_BRSTAT register is significant in bit 15 downto 0*/ +#define IFX_SSC_BRSTAT_readmask 0x0000FFFF +#define IFX_SSC_BRSTAT_writemask 0x00000000 +#define IFX_SSC_BRSTAT_hwmask 0x0000FFFF +#define IFX_SSC_BRSTAT_dontcare (IFX_SSC_BRSTAT_readmask & IFX_SSC_BRSTAT_writemask & ~IFX_SSC_BRSTAT_hwmask) + +/* address of the Transmitter Buffer Register of the SSC */ +#define IFX_SSC_TB 0x00000020 +/* IFX_SSC_TB register is significant in bit 31 downto 0*/ +#define IFX_SSC_TB_readmask 0xFFFFFFFF +#define IFX_SSC_TB_writemask 0xFFFFFFFF +#define IFX_SSC_TB_hwmask 0x00000000 +#define IFX_SSC_TB_dontcare (IFX_SSC_TB_readmask & IFX_SSC_TB_writemask & ~IFX_SSC_TB_hwmask) + +/* address of the Reciver Buffer Register of the SSC */ +#define IFX_SSC_RB 0x00000024 +/* IFX_SSC_RB register is significant in no bits*/ +#define IFX_SSC_RB_readmask 0xFFFFFFFF +#define IFX_SSC_RB_writemask 0x00000000 +#define IFX_SSC_RB_hwmask 0xFFFFFFFF +#define IFX_SSC_RB_dontcare (IFX_SSC_RB_readmask & IFX_SSC_RB_writemask & ~IFX_SSC_RB_hwmask) + +/* address of the Receive FIFO Control Register of the SSC */ +#define IFX_SSC_RXFCON 0x00000030 +/* IFX_SSC_RXFCON register is significant in bit 13 downto 8 and bit 1 downto 0 */ +#define IFX_SSC_RXFCON_readmask 0x00003F03 +#define IFX_SSC_RXFCON_writemask 0x00003F03 +#define IFX_SSC_RXFCON_hwmask 0x00000000 +#define IFX_SSC_RXFCON_dontcare (IFX_SSC_RXFCON_readmask & IFX_SSC_RXFCON_writemask & ~IFX_SSC_RXFCON_hwmask) + +/* address of the Transmit FIFO Control Register of the SSC */ +#define IFX_SSC_TXFCON 0x00000034 +/* IFX_SSC_TXFCON register is significant in bit 13 downto 8 and bit 1 downto 0 */ +#define IFX_SSC_TXFCON_readmask 0x00003F03 +#define IFX_SSC_TXFCON_writemask 0x00003F03 +#define IFX_SSC_TXFCON_hwmask 0x00000000 +#define IFX_SSC_TXFCON_dontcare (IFX_SSC_TXFCON_readmask & IFX_SSC_TXFCON_writemask & ~IFX_SSC_TXFCON_hwmask) + +/* address of the FIFO Status Register of the SSC */ +#define IFX_SSC_FSTAT 0x00000038 +/* IFX_SSC_FSTAT register is significant in no bit*/ +#define IFX_SSC_FSTAT_readmask 0x00003F3F +#define IFX_SSC_FSTAT_writemask 0x00000000 +#define IFX_SSC_FSTAT_hwmask 0x00003F3F +#define IFX_SSC_FSTAT_dontcare (IFX_SSC_FSTAT_readmask & IFX_SSC_FSTAT_writemask & ~IFX_SSC_FSTAT_hwmask) + +/* address of the Data Frame Control register of the SSC */ +#define IFX_SSC_SFCON 0x00000060 +#define IFX_SSC_SFCON_readmask 0xFFDFFFFD +#define IFX_SSC_SFCON_writemask 0xFFDFFFFD +#define IFX_SSC_SFCON_hwmask 0x00000000 +#define IFX_SSC_SFCON_dontcare (IFX_SSC_SFCON_readmask & IFX_SSC_SFCON_writemask & ~IFX_SSC_SFCON_hwmask) + +/* address of the Data Frame Status register of the SSC */ +#define IFX_SSC_SFSTAT 0x00000064 +#define IFX_SSC_SFSTAT_readmask 0xFFC0FFF3 +#define IFX_SSC_SFSTAT_writemask 0x00000000 +#define IFX_SSC_SFSTAT_hwmask 0xFFC0FFF3 +#define IFX_SSC_SFSTAT_dontcare (IFX_SSC_SFSTAT_readmask & IFX_SSC_SFSTAT_writemask & ~IFX_SSC_SFSTAT_hwmask) + +/* address of the General Purpose Output Control register of the SSC */ +#define IFX_SSC_GPOCON 0x00000070 +#define IFX_SSC_GPOCON_readmask 0x0000FFFF +#define IFX_SSC_GPOCON_writemask 0x0000FFFF +#define IFX_SSC_GPOCON_hwmask 0x00000000 +#define IFX_SSC_GPOCON_dontcare (IFX_SSC_GPOCON_readmask & IFX_SSC_GPOCON_writemask & ~IFX_SSC_GPOCON_hwmask) + +/* address of the General Purpose Output Status register of the SSC */ +#define IFX_SSC_GPOSTAT 0x00000074 +#define IFX_SSC_GPOSTAT_readmask 0x000000FF +#define IFX_SSC_GPOSTAT_writemask 0x00000000 +#define IFX_SSC_GPOSTAT_hwmask 0x00000000 +#define IFX_SSC_GPOSTAT_dontcare (IFX_SSC_GPOSTAT_readmask & IFX_SSC_GPOSTAT_writemask & ~IFX_SSC_GPOSTAT_hwmask) + +/* address of the Force GPO Status register of the SSC */ +#define IFX_SSC_WHBGPOSTAT 0x00000078 +#define IFX_SSC_WHBGPOSTAT_readmask 0x00000000 +#define IFX_SSC_WHBGPOSTAT_writemask 0x0000FFFF +#define IFX_SSC_WHBGPOSTAT_hwmask 0x00000000 +#define IFX_SSC_WHBGPOSTAT_dontcare (IFX_SSC_WHBGPOSTAT_readmask & IFX_SSC_WHBGPOSTAT_writemask & ~IFX_SSC_WHBGPOSTAT_hwmask) + +/* address of the Receive Request Register of the SSC */ +#define IFX_SSC_RXREQ 0x00000080 +#define IFX_SSC_RXREQ_readmask 0x0000FFFF +#define IFX_SSC_RXREQ_writemask 0x0000FFFF +#define IFX_SSC_RXREQ_hwmask 0x00000000 +#define IFX_SSC_RXREQ_dontcare (IFX_SSC_RXREQ_readmask & IFX_SSC_RXREQ_writemask & ~IFX_SSC_RXREQ_hwmask) + +/* address of the Receive Count Register of the SSC */ +#define IFX_SSC_RXCNT 0x00000084 +#define IFX_SSC_RXCNT_readmask 0x0000FFFF +#define IFX_SSC_RXCNT_writemask 0x00000000 +#define IFX_SSC_RXCNT_hwmask 0x0000FFFF +#define IFX_SSC_RXCNT_dontcare (IFX_SSC_RXCNT_readmask & IFX_SSC_RXCNT_writemask & ~IFX_SSC_RXCNT_hwmask) + +/* address of the DMA Configuration Register of the SSC */ +#define IFX_SSC_DMACON 0x000000EC +#define IFX_SSC_DMACON_readmask 0x0000FFFF +#define IFX_SSC_DMACON_writemask 0x00000000 +#define IFX_SSC_DMACON_hwmask 0x0000FFFF +#define IFX_SSC_DMACON_dontcare (IFX_SSC_DMACON_readmask & IFX_SSC_DMACON_writemask & ~IFX_SSC_DMACON_hwmask) + +//------------------------------------------------------ +// interrupt register for enabling interrupts, mask register of irq_reg +#define IFX_SSC_IRN_EN 0xF4 +// read/write +#define IFX_SSC_IRN_EN_readmask 0x0000000F +#define IFX_SSC_IRN_EN_writemask 0x0000000F +#define IFX_SSC_IRN_EN_hwmask 0x00000000 +#define IFX_SSC_IRN_EN_dontcare (IFX_SSC_IRN_EN_readmask & IFX_SSC_IRN_EN_writemask & ~IFX_SSC_IRN_EN_hwmask) + +// interrupt register for accessing interrupts +#define IFX_SSC_IRN_CR 0xF8 +// read/write +#define IFX_SSC_IRN_CR_readmask 0x0000000F +#define IFX_SSC_IRN_CR_writemask 0x0000000F +#define IFX_SSC_IRN_CR_hwmask 0x0000000F +#define IFX_SSC_IRN_CR_dontcare (IFX_SSC_IRN_CR_readmask & IFX_SSC_IRN_CR_writemask & ~IFX_SSC_IRN_CR_hwmask) + +// interrupt register for stimulating interrupts +#define IFX_SSC_IRN_ICR 0xFC +// read/write +#define IFX_SSC_IRN_ICR_readmask 0x0000000F +#define IFX_SSC_IRN_ICR_writemask 0x0000000F +#define IFX_SSC_IRN_ICR_hwmask 0x00000000 +#define IFX_SSC_IRN_ICR_dontcare (IFX_SSC_IRN_ICR_readmask & IFX_SSC_IRN_ICR_writemask & ~IFX_SSC_IRN_ICR_hwmask) + +//--------------------------------------------------------------------- +// Number of IRQs and bitposition of IRQ +#define IFX_SSC_NUM_IRQ 4 +#define IFX_SSC_T_BIT 0x00000001 +#define IFX_SSC_R_BIT 0x00000002 +#define IFX_SSC_E_BIT 0x00000004 +#define IFX_SSC_F_BIT 0x00000008 + +/* bit masks for SSC registers */ + +/* ID register */ +#define IFX_SSC_PERID_REV_MASK 0x0000001F +#define IFX_SSC_PERID_CFG_MASK 0x00000020 +#define IFX_SSC_PERID_ID_MASK 0x0000FF00 +#define IFX_SSC_PERID_REV_OFFSET 0 +#define IFX_SSC_PERID_CFG_OFFSET 5 +#define IFX_SSC_PERID_ID_OFFSET 8 +#define IFX_SSC_PERID_ID 0x45 +#define IFX_SSC_PERID_DMA_ON 0x00000020 +#define IFX_SSC_PERID_RXFS_MASK 0x003F0000 +#define IFX_SSC_PERID_RXFS_OFFSET 16 +#define IFX_SSC_PERID_TXFS_MASK 0x3F000000 +#define IFX_SSC_PERID_TXFS_OFFSET 24 + +/* PISEL register */ +#define IFX_SSC_PISEL_MASTER_IN_A 0x0000 +#define IFX_SSC_PISEL_MASTER_IN_B 0x0001 +#define IFX_SSC_PISEL_SLAVE_IN_A 0x0000 +#define IFX_SSC_PISEL_SLAVE_IN_B 0x0002 +#define IFX_SSC_PISEL_CLOCK_IN_A 0x0000 +#define IFX_SSC_PISEL_CLOCK_IN_B 0x0004 + + +/* IFX_SSC_CON register */ +#define IFX_SSC_CON_ECHO_MODE_ON 0x01000000 +#define IFX_SSC_CON_ECHO_MODE_OFF 0x00000000 +#define IFX_SSC_CON_IDLE_HIGH 0x00800000 +#define IFX_SSC_CON_IDLE_LOW 0x00000000 +#define IFX_SSC_CON_ENABLE_BYTE_VALID 0x00400000 +#define IFX_SSC_CON_DISABLE_BYTE_VALID 0x00000000 +#define IFX_SSC_CON_DATA_WIDTH_OFFSET 16 +#define IFX_SSC_CON_DATA_WIDTH_MASK 0x001F0000 +#define IFX_SSC_ENCODE_DATA_WIDTH(width) (((width - 1) << IFX_SSC_CON_DATA_WIDTH_OFFSET) & IFX_SSC_CON_DATA_WIDTH_MASK) + +#define IFX_SSC_CON_RESET_ON_BAUDERR 0x00002000 +#define IFX_SSC_CON_GO_ON_ON_BAUDERR 0x00000000 + +#define IFX_SSC_CON_RX_UFL_CHECK 0x00001000 +#define IFX_SSC_CON_RX_UFL_IGNORE 0x00000000 +#define IFX_SSC_CON_TX_UFL_CHECK 0x00000800 +#define IFX_SSC_CON_TX_UFL_IGNORE 0x00000000 +#define IFX_SSC_CON_ABORT_ERR_CHECK 0x00000400 +#define IFX_SSC_CON_ABORT_ERR_IGNORE 0x00000000 +#define IFX_SSC_CON_RX_OFL_CHECK 0x00000200 +#define IFX_SSC_CON_RX_OFL_IGNORE 0x00000000 +#define IFX_SSC_CON_TX_OFL_CHECK 0x00000100 +#define IFX_SSC_CON_TX_OFL_IGNORE 0x00000000 +#define IFX_SSC_CON_ALL_ERR_CHECK 0x00001F00 +#define IFX_SSC_CON_ALL_ERR_IGNORE 0x00000000 + +#define IFX_SSC_CON_LOOPBACK_MODE 0x00000080 +#define IFX_SSC_CON_NO_LOOPBACK 0x00000000 +#define IFX_SSC_CON_HALF_DUPLEX 0x00000080 +#define IFX_SSC_CON_FULL_DUPLEX 0x00000000 +#define IFX_SSC_CON_CLOCK_FALL 0x00000040 +#define IFX_SSC_CON_CLOCK_RISE 0x00000000 +#define IFX_SSC_CON_SHIFT_THEN_LATCH 0x00000000 +#define IFX_SSC_CON_LATCH_THEN_SHIFT 0x00000020 +#define IFX_SSC_CON_MSB_FIRST 0x00000010 +#define IFX_SSC_CON_LSB_FIRST 0x00000000 +#define IFX_SSC_CON_ENABLE_CSB 0x00000008 +#define IFX_SSC_CON_DISABLE_CSB 0x00000000 +#define IFX_SSC_CON_INVERT_CSB 0x00000004 +#define IFX_SSC_CON_TRUE_CSB 0x00000000 +#define IFX_SSC_CON_RX_OFF 0x00000002 +#define IFX_SSC_CON_RX_ON 0x00000000 +#define IFX_SSC_CON_TX_OFF 0x00000001 +#define IFX_SSC_CON_TX_ON 0x00000000 + + +/* IFX_SSC_STATE register */ +#define IFX_SSC_STATE_RX_BYTE_VALID_OFFSET 28 +#define IFX_SSC_STATE_RX_BYTE_VALID_MASK 0x70000000 +#define IFX_SSC_DECODE_RX_BYTE_VALID(con_state) ((con_state & IFX_SSC_STATE_RX_BYTE_VALID_MASK) >> IFX_SSC_STATE_RX_BYTE_VALID_OFFSET) +#define IFX_SSC_STATE_TX_BYTE_VALID_OFFSET 24 +#define IFX_SSC_STATE_TX_BYTE_VALID_MASK 0x07000000 +#define IFX_SSC_DECODE_TX_BYTE_VALID(con_state) ((con_state & IFX_SSC_STATE_TX_BYTE_VALID_MASK) >> IFX_SSC_STATE_TX_BYTE_VALID_OFFSET) +#define IFX_SSC_STATE_BIT_COUNT_OFFSET 16 +#define IFX_SSC_STATE_BIT_COUNT_MASK 0x001F0000 +#define IFX_SSC_DECODE_DATA_WIDTH(con_state) (((con_state & IFX_SSC_STATE_BIT_COUNT_MASK) >> IFX_SSC_STATE_BIT_COUNT_OFFSET) + 1) +#define IFX_SSC_STATE_BUSY 0x00002000 +#define IFX_SSC_STATE_RX_UFL 0x00001000 +#define IFX_SSC_STATE_TX_UFL 0x00000800 +#define IFX_SSC_STATE_ABORT_ERR 0x00000400 +#define IFX_SSC_STATE_RX_OFL 0x00000200 +#define IFX_SSC_STATE_TX_OFL 0x00000100 +#define IFX_SSC_STATE_MODE_ERR 0x00000080 +#define IFX_SSC_STATE_SLAVE_IS_SELECTED 0x00000004 +#define IFX_SSC_STATE_IS_MASTER 0x00000002 +#define IFX_SSC_STATE_IS_ENABLED 0x00000001 + +/* WHBSTATE register */ +#define IFX_SSC_WHBSTATE_DISABLE_SSC 0x0001 +#define IFX_SSC_WHBSTATE_CONFIGURATION_MODE 0x0001 +#define IFX_SSC_WHBSTATE_CLR_ENABLE 0x0001 + +#define IFX_SSC_WHBSTATE_ENABLE_SSC 0x0002 +#define IFX_SSC_WHBSTATE_RUN_MODE 0x0002 +#define IFX_SSC_WHBSTATE_SET_ENABLE 0x0002 + +#define IFX_SSC_WHBSTATE_SLAVE_MODE 0x0004 +#define IFX_SSC_WHBSTATE_CLR_MASTER_SELECT 0x0004 + +#define IFX_SSC_WHBSTATE_MASTER_MODE 0x0008 +#define IFX_SSC_WHBSTATE_SET_MASTER_SELECT 0x0008 + +#define IFX_SSC_WHBSTATE_CLR_RX_UFL_ERROR 0x0010 +#define IFX_SSC_WHBSTATE_SET_RX_UFL_ERROR 0x0020 + +#define IFX_SSC_WHBSTATE_CLR_MODE_ERROR 0x0040 +#define IFX_SSC_WHBSTATE_SET_MODE_ERROR 0x0080 + +#define IFX_SSC_WHBSTATE_CLR_TX_OFL_ERROR 0x0100 +#define IFX_SSC_WHBSTATE_CLR_RX_OFL_ERROR 0x0200 +#define IFX_SSC_WHBSTATE_CLR_ABORT_ERROR 0x0400 +#define IFX_SSC_WHBSTATE_CLR_TX_UFL_ERROR 0x0800 +#define IFX_SSC_WHBSTATE_SET_TX_OFL_ERROR 0x1000 +#define IFX_SSC_WHBSTATE_SET_RX_OFL_ERROR 0x2000 +#define IFX_SSC_WHBSTATE_SET_ABORT_ERROR 0x4000 +#define IFX_SSC_WHBSTATE_SET_TX_UFL_ERROR 0x8000 +#define IFX_SSC_WHBSTATE_CLR_ALL_ERROR 0x0F50 +#define IFX_SSC_WHBSTATE_SET_ALL_ERROR 0xF0A0 + +/* BR register */ +#define IFX_SSC_BR_BAUDRATE_OFFSET 0 +#define IFX_SSC_BR_BAUDRATE_MASK 0xFFFF + +/* BR_STAT register */ +#define IFX_SSC_BRSTAT_BAUDTIMER_OFFSET 0 +#define IFX_SSC_BRSTAT_BAUDTIMER_MASK 0xFFFF + +/* TB register */ +#define IFX_SSC_TB_DATA_OFFSET 0 +#define IFX_SSC_TB_DATA_MASK 0xFFFFFFFF + +/* RB register */ +#define IFX_SSC_RB_DATA_OFFSET 0 +#define IFX_SSC_RB_DATA_MASK 0xFFFFFFFF + + +/* RXFCON and TXFCON registers */ +#define IFX_SSC_XFCON_FIFO_DISABLE 0x0000 +#define IFX_SSC_XFCON_FIFO_ENABLE 0x0001 +#define IFX_SSC_XFCON_FIFO_FLUSH 0x0002 +#define IFX_SSC_XFCON_ITL_MASK 0x00003F00 +#define IFX_SSC_XFCON_ITL_OFFSET 8 + +/* FSTAT register */ +#define IFX_SSC_FSTAT_RECEIVED_WORDS_OFFSET 0 +#define IFX_SSC_FSTAT_RECEIVED_WORDS_MASK 0x003F +#define IFX_SSC_FSTAT_TRANSMIT_WORDS_OFFSET 8 +#define IFX_SSC_FSTAT_TRANSMIT_WORDS_MASK 0x3F00 + +/* GPOCON register */ +#define IFX_SSC_GPOCON_INVOUT0_POS 0 +#define IFX_SSC_GPOCON_INV_OUT0 0x00000001 +#define IFX_SSC_GPOCON_TRUE_OUT0 0x00000000 +#define IFX_SSC_GPOCON_INVOUT1_POS 1 +#define IFX_SSC_GPOCON_INV_OUT1 0x00000002 +#define IFX_SSC_GPOCON_TRUE_OUT1 0x00000000 +#define IFX_SSC_GPOCON_INVOUT2_POS 2 +#define IFX_SSC_GPOCON_INV_OUT2 0x00000003 +#define IFX_SSC_GPOCON_TRUE_OUT2 0x00000000 +#define IFX_SSC_GPOCON_INVOUT3_POS 3 +#define IFX_SSC_GPOCON_INV_OUT3 0x00000008 +#define IFX_SSC_GPOCON_TRUE_OUT3 0x00000000 +#define IFX_SSC_GPOCON_INVOUT4_POS 4 +#define IFX_SSC_GPOCON_INV_OUT4 0x00000010 +#define IFX_SSC_GPOCON_TRUE_OUT4 0x00000000 +#define IFX_SSC_GPOCON_INVOUT5_POS 5 +#define IFX_SSC_GPOCON_INV_OUT5 0x00000020 +#define IFX_SSC_GPOCON_TRUE_OUT5 0x00000000 +#define IFX_SSC_GPOCON_INVOUT6_POS 6 +#define IFX_SSC_GPOCON_INV_OUT6 0x00000040 +#define IFX_SSC_GPOCON_TRUE_OUT6 0x00000000 +#define IFX_SSC_GPOCON_INVOUT7_POS 7 +#define IFX_SSC_GPOCON_INV_OUT7 0x00000080 +#define IFX_SSC_GPOCON_TRUE_OUT7 0x00000000 +#define IFX_SSC_GPOCON_INV_OUT_ALL 0x000000FF +#define IFX_SSC_GPOCON_TRUE_OUT_ALL 0x00000000 + +#define IFX_SSC_GPOCON_ISCSB0_POS 8 +#define IFX_SSC_GPOCON_IS_CSB0 0x00000100 +#define IFX_SSC_GPOCON_IS_GPO0 0x00000000 +#define IFX_SSC_GPOCON_ISCSB1_POS 9 +#define IFX_SSC_GPOCON_IS_CSB1 0x00000200 +#define IFX_SSC_GPOCON_IS_GPO1 0x00000000 +#define IFX_SSC_GPOCON_ISCSB2_POS 10 +#define IFX_SSC_GPOCON_IS_CSB2 0x00000400 +#define IFX_SSC_GPOCON_IS_GPO2 0x00000000 +#define IFX_SSC_GPOCON_ISCSB3_POS 11 +#define IFX_SSC_GPOCON_IS_CSB3 0x00000800 +#define IFX_SSC_GPOCON_IS_GPO3 0x00000000 +#define IFX_SSC_GPOCON_ISCSB4_POS 12 +#define IFX_SSC_GPOCON_IS_CSB4 0x00001000 +#define IFX_SSC_GPOCON_IS_GPO4 0x00000000 +#define IFX_SSC_GPOCON_ISCSB5_POS 13 +#define IFX_SSC_GPOCON_IS_CSB5 0x00002000 +#define IFX_SSC_GPOCON_IS_GPO5 0x00000000 +#define IFX_SSC_GPOCON_ISCSB6_POS 14 +#define IFX_SSC_GPOCON_IS_CSB6 0x00004000 +#define IFX_SSC_GPOCON_IS_GPO6 0x00000000 +#define IFX_SSC_GPOCON_ISCSB7_POS 15 +#define IFX_SSC_GPOCON_IS_CSB7 0x00008000 +#define IFX_SSC_GPOCON_IS_GPO7 0x00000000 +#define IFX_SSC_GPOCON_IS_CSB_ALL 0x0000FF00 +#define IFX_SSC_GPOCON_IS_GPO_ALL 0x00000000 + +/* GPOSTAT register */ +#define IFX_SSC_GPOSTAT_OUT0 0x00000001 +#define IFX_SSC_GPOSTAT_OUT1 0x00000002 +#define IFX_SSC_GPOSTAT_OUT2 0x00000004 +#define IFX_SSC_GPOSTAT_OUT3 0x00000008 +#define IFX_SSC_GPOSTAT_OUT4 0x00000010 +#define IFX_SSC_GPOSTAT_OUT5 0x00000020 +#define IFX_SSC_GPOSTAT_OUT6 0x00000040 +#define IFX_SSC_GPOSTAT_OUT7 0x00000080 +#define IFX_SSC_GPOSTAT_OUT_ALL 0x000000FF + +/* WHBGPOSTAT register */ +#define IFX_SSC_WHBGPOSTAT_CLROUT0_POS 0 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT0 0x00000001 +#define IFX_SSC_WHBGPOSTAT_CLROUT1_POS 1 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT1 0x00000002 +#define IFX_SSC_WHBGPOSTAT_CLROUT2_POS 2 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT2 0x00000004 +#define IFX_SSC_WHBGPOSTAT_CLROUT3_POS 3 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT3 0x00000008 +#define IFX_SSC_WHBGPOSTAT_CLROUT4_POS 4 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT4 0x00000010 +#define IFX_SSC_WHBGPOSTAT_CLROUT5_POS 5 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT5 0x00000020 +#define IFX_SSC_WHBGPOSTAT_CLROUT6_POS 6 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT6 0x00000040 +#define IFX_SSC_WHBGPOSTAT_CLROUT7_POS 7 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT7 0x00000080 +#define IFX_SSC_WHBGPOSTAT_CLR_OUT_ALL 0x000000FF + +#define IFX_SSC_WHBGPOSTAT_OUT0_POS 0 +#define IFX_SSC_WHBGPOSTAT_OUT1_POS 1 +#define IFX_SSC_WHBGPOSTAT_OUT2_POS 2 +#define IFX_SSC_WHBGPOSTAT_OUT3_POS 3 +#define IFX_SSC_WHBGPOSTAT_OUT4_POS 4 +#define IFX_SSC_WHBGPOSTAT_OUT5_POS 5 +#define IFX_SSC_WHBGPOSTAT_OUT6_POS 6 +#define IFX_SSC_WHBGPOSTAT_OUT7_POS 7 + + +#define IFX_SSC_WHBGPOSTAT_SETOUT0_POS 8 +#define IFX_SSC_WHBGPOSTAT_SET_OUT0 0x00000100 +#define IFX_SSC_WHBGPOSTAT_SETOUT1_POS 9 +#define IFX_SSC_WHBGPOSTAT_SET_OUT1 0x00000200 +#define IFX_SSC_WHBGPOSTAT_SETOUT2_POS 10 +#define IFX_SSC_WHBGPOSTAT_SET_OUT2 0x00000400 +#define IFX_SSC_WHBGPOSTAT_SETOUT3_POS 11 +#define IFX_SSC_WHBGPOSTAT_SET_OUT3 0x00000800 +#define IFX_SSC_WHBGPOSTAT_SETOUT4_POS 12 +#define IFX_SSC_WHBGPOSTAT_SET_OUT4 0x00001000 +#define IFX_SSC_WHBGPOSTAT_SETOUT5_POS 13 +#define IFX_SSC_WHBGPOSTAT_SET_OUT5 0x00002000 +#define IFX_SSC_WHBGPOSTAT_SETOUT6_POS 14 +#define IFX_SSC_WHBGPOSTAT_SET_OUT6 0x00004000 +#define IFX_SSC_WHBGPOSTAT_SETOUT7_POS 15 +#define IFX_SSC_WHBGPOSTAT_SET_OUT7 0x00008000 +#define IFX_SSC_WHBGPOSTAT_SET_OUT_ALL 0x0000FF00 + +/* SFCON register */ +#define IFX_SSC_SFCON_SF_ENABLE 0x00000001 +#define IFX_SSC_SFCON_SF_DISABLE 0x00000000 +#define IFX_SSC_SFCON_FIR_ENABLE_BEFORE_PAUSE 0x00000004 +#define IFX_SSC_SFCON_FIR_DISABLE_BEFORE_PAUSE 0x00000000 +#define IFX_SSC_SFCON_FIR_ENABLE_AFTER_PAUSE 0x00000008 +#define IFX_SSC_SFCON_FIR_DISABLE_AFTER_PAUSE 0x00000000 +#define IFX_SSC_SFCON_DATA_LENGTH_MASK 0x0000FFF0 +#define IFX_SSC_SFCON_DATA_LENGTH_OFFSET 4 +#define IFX_SSC_SFCON_PAUSE_DATA_MASK 0x00030000 +#define IFX_SSC_SFCON_PAUSE_DATA_OFFSET 16 +#define IFX_SSC_SFCON_PAUSE_DATA_0 0x00000000 +#define IFX_SSC_SFCON_PAUSE_DATA_1 0x00010000 +#define IFX_SSC_SFCON_PAUSE_DATA_IDLE 0x00020000 +#define IFX_SSC_SFCON_PAUSE_CLOCK_MASK 0x000C0000 +#define IFX_SSC_SFCON_PAUSE_CLOCK_OFFSET 18 +#define IFX_SSC_SFCON_PAUSE_CLOCK_0 0x00000000 +#define IFX_SSC_SFCON_PAUSE_CLOCK_1 0x00040000 +#define IFX_SSC_SFCON_PAUSE_CLOCK_IDLE 0x00080000 +#define IFX_SSC_SFCON_PAUSE_CLOCK_RUN 0x000C0000 +#define IFX_SSC_SFCON_STOP_AFTER_PAUSE 0x00100000 +#define IFX_SSC_SFCON_CONTINUE_AFTER_PAUSE 0x00000000 +#define IFX_SSC_SFCON_PAUSE_LENGTH_MASK 0xFFC00000 +#define IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET 22 +#define IFX_SSC_SFCON_DATA_LENGTH_MAX 4096 +#define IFX_SSC_SFCON_PAUSE_LENGTH_MAX 1024 + +#define IFX_SSC_SFCON_EXTRACT_DATA_LENGTH(sfcon) ((sfcon & IFX_SSC_SFCON_DATA_LENGTH_MASK) >> IFX_SSC_SFCON_DATA_LENGTH_OFFSET) +#define IFX_SSC_SFCON_EXTRACT_PAUSE_LENGTH(sfcon) ((sfcon & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) >> IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET) +#define IFX_SSC_SFCON_SET_DATA_LENGTH(value) ((value << IFX_SSC_SFCON_DATA_LENGTH_OFFSET) & IFX_SSC_SFCON_DATA_LENGTH_MASK) +#define IFX_SSC_SFCON_SET_PAUSE_LENGTH(value) ((value << IFX_SSC_SFCON_PAUSE_LENGTH_OFFSET) & IFX_SSC_SFCON_PAUSE_LENGTH_MASK) + +/* SFSTAT register */ +#define IFX_SSC_SFSTAT_IN_DATA 0x00000001 +#define IFX_SSC_SFSTAT_IN_PAUSE 0x00000002 +#define IFX_SSC_SFSTAT_DATA_COUNT_MASK 0x0000FFF0 +#define IFX_SSC_SFSTAT_DATA_COUNT_OFFSET 4 +#define IFX_SSC_SFSTAT_PAUSE_COUNT_MASK 0xFFF00000 +#define IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET 20 + +#define IFX_SSC_SFSTAT_EXTRACT_DATA_COUNT(sfstat) ((sfstat & IFX_SSC_SFSTAT_DATA_COUNT_MASK) >> IFX_SSC_SFSTAT_DATA_COUNT_OFFSET) +#define IFX_SSC_SFSTAT_EXTRACT_PAUSE_COUNT(sfstat) ((sfstat & IFX_SSC_SFSTAT_PAUSE_COUNT_MASK) >> IFX_SSC_SFSTAT_PAUSE_COUNT_OFFSET) + +/* RXREQ register */ +#define IFX_SSC_RXREQ_RXCOUNT_MASK 0x0000FFFF +#define IFX_SSC_RXREQ_RXCOUNT_OFFSET 0 + +/* RXCNT register */ +#define IFX_SSC_RXCNT_TODO_MASK 0x0000FFFF +#define IFX_SSC_RXCNT_TODO_OFFSET 0 + +/* DMACON register */ +#define IFX_SSC_DMACON_RXON 0x00000001 +#define IFX_SSC_DMACON_RXOFF 0x00000000 +#define IFX_SSC_DMACON_TXON 0x00000002 +#define IFX_SSC_DMACON_TXOFF 0x00000000 +#define IFX_SSC_DMACON_DMAON 0x00000003 +#define IFX_SSC_DMACON_DMAOFF 0x00000000 +#define IFX_SSC_DMACON_CLASS_MASK 0x0000000C +#define IFX_SSC_DMACON_CLASS_OFFSET 2 + +/* register access macros */ +#define ifx_ssc_fstat_received_words(status) (status & 0x003F) +#define ifx_ssc_fstat_words_to_transmit(status) ((status & 0x3F00) >> 8) + +#define ifx_ssc_change_status(data, addr) WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_WHBSTATE)) +#define ifx_ssc_set_config(data, addr) WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_CON)) +#define ifx_ssc_get_config(addr) READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_CON)) +#define ifx_ssc_get_status(addr) READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_STATE)) +#define ifx_ssc_receive(addr) READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_RB)) +#define ifx_ssc_transmit(data, addr) WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_TB)) +#define ifx_ssc_fifo_status(addr) READ_PERIPHERAL_REGISTER((PHYS_OFFSET + addr + IFX_SSC_FSTAT)) +#define ifx_ssc_set_baudrate(data, addr) WRITE_PERIPHERAL_REGISTER(data, (PHYS_OFFSET + addr + IFX_SSC_BR)) + +#define ifx_ssc_extract_rx_fifo_size(id) ((id & IFX_SSC_PERID_RXFS_MASK) >> IFX_SSC_PERID_RXFS_OFFSET) +#define ifx_ssc_extract_tx_fifo_size(id) ((id & IFX_SSC_PERID_TXFS_MASK) >> IFX_SSC_PERID_TXFS_OFFSET) + +#endif diff --git a/target/linux/amazon/files/include/asm-mips/amazon/irq.h b/target/linux/amazon/files/include/asm-mips/amazon/irq.h new file mode 100644 index 0000000000..c575dd64b2 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/irq.h @@ -0,0 +1,200 @@ +/* irq.h - AMAZON interrupts */ + +#ifndef __AMAZON_IRQ +#define __AMAZON_IRQ + +/************************************************************************ + * Interrupt information +*************************************************************************/ + +/* these vectors are to handle the interrupts from the internal AMAZON + interrupt controller. THe INT_NUM values are really just indices into + an array and are set up so that we can use the INT_NUM as a shift + to calculate a mask value. */ +#define INT_NUM_IRQ0 8 +#define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0) +#define INT_NUM_IM0_IRL1 (INT_NUM_IRQ0 + 1) +#define INT_NUM_IM0_IRL2 (INT_NUM_IRQ0 + 2) +#define INT_NUM_IM0_IRL3 (INT_NUM_IRQ0 + 3) +#define INT_NUM_IM0_IRL4 (INT_NUM_IRQ0 + 4) +#define INT_NUM_IM0_IRL5 (INT_NUM_IRQ0 + 5) +#define INT_NUM_IM0_IRL6 (INT_NUM_IRQ0 + 6) +#define INT_NUM_IM0_IRL7 (INT_NUM_IRQ0 + 7) +#define INT_NUM_IM0_IRL8 (INT_NUM_IRQ0 + 8) +#define INT_NUM_IM0_IRL9 (INT_NUM_IRQ0 + 9) +#define INT_NUM_IM0_IRL10 (INT_NUM_IRQ0 + 10) +#define INT_NUM_IM0_IRL11 (INT_NUM_IRQ0 + 11) +#define INT_NUM_IM0_IRL12 (INT_NUM_IRQ0 + 12) +#define INT_NUM_IM0_IRL13 (INT_NUM_IRQ0 + 13) +#define INT_NUM_IM0_IRL14 (INT_NUM_IRQ0 + 14) +#define INT_NUM_IM0_IRL15 (INT_NUM_IRQ0 + 15) +#define INT_NUM_IM0_IRL16 (INT_NUM_IRQ0 + 16) +#define INT_NUM_IM0_IRL17 (INT_NUM_IRQ0 + 17) +#define INT_NUM_IM0_IRL18 (INT_NUM_IRQ0 + 18) +#define INT_NUM_IM0_IRL19 (INT_NUM_IRQ0 + 19) +#define INT_NUM_IM0_IRL20 (INT_NUM_IRQ0 + 20) +#define INT_NUM_IM0_IRL21 (INT_NUM_IRQ0 + 21) +#define INT_NUM_IM0_IRL22 (INT_NUM_IRQ0 + 22) +#define INT_NUM_IM0_IRL23 (INT_NUM_IRQ0 + 23) +#define INT_NUM_IM0_IRL24 (INT_NUM_IRQ0 + 24) +#define INT_NUM_IM0_IRL25 (INT_NUM_IRQ0 + 25) +#define INT_NUM_IM0_IRL26 (INT_NUM_IRQ0 + 26) +#define INT_NUM_IM0_IRL27 (INT_NUM_IRQ0 + 27) +#define INT_NUM_IM0_IRL28 (INT_NUM_IRQ0 + 28) +#define INT_NUM_IM0_IRL29 (INT_NUM_IRQ0 + 29) +#define INT_NUM_IM0_IRL30 (INT_NUM_IRQ0 + 30) +#define INT_NUM_IM0_IRL31 (INT_NUM_IRQ0 + 31) + +#define INT_NUM_IM1_IRL0 (INT_NUM_IRQ0 + 32) +#define INT_NUM_IM1_IRL1 (INT_NUM_IM1_IRL0 + 1) +#define INT_NUM_IM1_IRL2 (INT_NUM_IM1_IRL0 + 2) +#define INT_NUM_IM1_IRL3 (INT_NUM_IM1_IRL0 + 3) +#define INT_NUM_IM1_IRL4 (INT_NUM_IM1_IRL0 + 4) +#define INT_NUM_IM1_IRL5 (INT_NUM_IM1_IRL0 + 5) +#define INT_NUM_IM1_IRL6 (INT_NUM_IM1_IRL0 + 6) +#define INT_NUM_IM1_IRL7 (INT_NUM_IM1_IRL0 + 7) +#define INT_NUM_IM1_IRL8 (INT_NUM_IM1_IRL0 + 8) +#define INT_NUM_IM1_IRL9 (INT_NUM_IM1_IRL0 + 9) +#define INT_NUM_IM1_IRL10 (INT_NUM_IM1_IRL0 + 10) +#define INT_NUM_IM1_IRL11 (INT_NUM_IM1_IRL0 + 11) +#define INT_NUM_IM1_IRL12 (INT_NUM_IM1_IRL0 + 12) +#define INT_NUM_IM1_IRL13 (INT_NUM_IM1_IRL0 + 13) +#define INT_NUM_IM1_IRL14 (INT_NUM_IM1_IRL0 + 14) +#define INT_NUM_IM1_IRL15 (INT_NUM_IM1_IRL0 + 15) +#define INT_NUM_IM1_IRL16 (INT_NUM_IM1_IRL0 + 16) +#define INT_NUM_IM1_IRL17 (INT_NUM_IM1_IRL0 + 17) +#define INT_NUM_IM1_IRL18 (INT_NUM_IM1_IRL0 + 18) +#define INT_NUM_IM1_IRL19 (INT_NUM_IM1_IRL0 + 19) +#define INT_NUM_IM1_IRL20 (INT_NUM_IM1_IRL0 + 20) +#define INT_NUM_IM1_IRL21 (INT_NUM_IM1_IRL0 + 21) +#define INT_NUM_IM1_IRL22 (INT_NUM_IM1_IRL0 + 22) +#define INT_NUM_IM1_IRL23 (INT_NUM_IM1_IRL0 + 23) +#define INT_NUM_IM1_IRL24 (INT_NUM_IM1_IRL0 + 24) +#define INT_NUM_IM1_IRL25 (INT_NUM_IM1_IRL0 + 25) +#define INT_NUM_IM1_IRL26 (INT_NUM_IM1_IRL0 + 26) +#define INT_NUM_IM1_IRL27 (INT_NUM_IM1_IRL0 + 27) +#define INT_NUM_IM1_IRL28 (INT_NUM_IM1_IRL0 + 28) +#define INT_NUM_IM1_IRL29 (INT_NUM_IM1_IRL0 + 29) +#define INT_NUM_IM1_IRL30 (INT_NUM_IM1_IRL0 + 30) +#define INT_NUM_IM1_IRL31 (INT_NUM_IM1_IRL0 + 31) + +#define INT_NUM_IM2_IRL0 (INT_NUM_IRQ0 + 64) +#define INT_NUM_IM2_IRL1 (INT_NUM_IM2_IRL0 + 1) +#define INT_NUM_IM2_IRL2 (INT_NUM_IM2_IRL0 + 2) +#define INT_NUM_IM2_IRL3 (INT_NUM_IM2_IRL0 + 3) +#define INT_NUM_IM2_IRL4 (INT_NUM_IM2_IRL0 + 4) +#define INT_NUM_IM2_IRL5 (INT_NUM_IM2_IRL0 + 5) +#define INT_NUM_IM2_IRL6 (INT_NUM_IM2_IRL0 + 6) +#define INT_NUM_IM2_IRL7 (INT_NUM_IM2_IRL0 + 7) +#define INT_NUM_IM2_IRL8 (INT_NUM_IM2_IRL0 + 8) +#define INT_NUM_IM2_IRL9 (INT_NUM_IM2_IRL0 + 9) +#define INT_NUM_IM2_IRL10 (INT_NUM_IM2_IRL0 + 10) +#define INT_NUM_IM2_IRL11 (INT_NUM_IM2_IRL0 + 11) +#define INT_NUM_IM2_IRL12 (INT_NUM_IM2_IRL0 + 12) +#define INT_NUM_IM2_IRL13 (INT_NUM_IM2_IRL0 + 13) +#define INT_NUM_IM2_IRL14 (INT_NUM_IM2_IRL0 + 14) +#define INT_NUM_IM2_IRL15 (INT_NUM_IM2_IRL0 + 15) +#define INT_NUM_IM2_IRL16 (INT_NUM_IM2_IRL0 + 16) +#define INT_NUM_IM2_IRL17 (INT_NUM_IM2_IRL0 + 17) +#define INT_NUM_IM2_IRL18 (INT_NUM_IM2_IRL0 + 18) +#define INT_NUM_IM2_IRL19 (INT_NUM_IM2_IRL0 + 19) +#define INT_NUM_IM2_IRL20 (INT_NUM_IM2_IRL0 + 20) +#define INT_NUM_IM2_IRL21 (INT_NUM_IM2_IRL0 + 21) +#define INT_NUM_IM2_IRL22 (INT_NUM_IM2_IRL0 + 22) +#define INT_NUM_IM2_IRL23 (INT_NUM_IM2_IRL0 + 23) +#define INT_NUM_IM2_IRL24 (INT_NUM_IM2_IRL0 + 24) +#define INT_NUM_IM2_IRL25 (INT_NUM_IM2_IRL0 + 25) +#define INT_NUM_IM2_IRL26 (INT_NUM_IM2_IRL0 + 26) +#define INT_NUM_IM2_IRL27 (INT_NUM_IM2_IRL0 + 27) +#define INT_NUM_IM2_IRL28 (INT_NUM_IM2_IRL0 + 28) +#define INT_NUM_IM2_IRL29 (INT_NUM_IM2_IRL0 + 29) +#define INT_NUM_IM2_IRL30 (INT_NUM_IM2_IRL0 + 30) +#define INT_NUM_IM2_IRL31 (INT_NUM_IM2_IRL0 + 31) + +#define INT_NUM_IM3_IRL0 (INT_NUM_IRQ0 + 96) +#define INT_NUM_IM3_IRL1 (INT_NUM_IM3_IRL0 + 1) +#define INT_NUM_IM3_IRL2 (INT_NUM_IM3_IRL0 + 2) +#define INT_NUM_IM3_IRL3 (INT_NUM_IM3_IRL0 + 3) +#define INT_NUM_IM3_IRL4 (INT_NUM_IM3_IRL0 + 4) +#define INT_NUM_IM3_IRL5 (INT_NUM_IM3_IRL0 + 5) +#define INT_NUM_IM3_IRL6 (INT_NUM_IM3_IRL0 + 6) +#define INT_NUM_IM3_IRL7 (INT_NUM_IM3_IRL0 + 7) +#define INT_NUM_IM3_IRL8 (INT_NUM_IM3_IRL0 + 8) +#define INT_NUM_IM3_IRL9 (INT_NUM_IM3_IRL0 + 9) +#define INT_NUM_IM3_IRL10 (INT_NUM_IM3_IRL0 + 10) +#define INT_NUM_IM3_IRL11 (INT_NUM_IM3_IRL0 + 11) +#define INT_NUM_IM3_IRL12 (INT_NUM_IM3_IRL0 + 12) +#define INT_NUM_IM3_IRL13 (INT_NUM_IM3_IRL0 + 13) +#define INT_NUM_IM3_IRL14 (INT_NUM_IM3_IRL0 + 14) +#define INT_NUM_IM3_IRL15 (INT_NUM_IM3_IRL0 + 15) +#define INT_NUM_IM3_IRL16 (INT_NUM_IM3_IRL0 + 16) +#define INT_NUM_IM3_IRL17 (INT_NUM_IM3_IRL0 + 17) +#define INT_NUM_IM3_IRL18 (INT_NUM_IM3_IRL0 + 18) +#define INT_NUM_IM3_IRL19 (INT_NUM_IM3_IRL0 + 19) +#define INT_NUM_IM3_IRL20 (INT_NUM_IM3_IRL0 + 20) +#define INT_NUM_IM3_IRL21 (INT_NUM_IM3_IRL0 + 21) +#define INT_NUM_IM3_IRL22 (INT_NUM_IM3_IRL0 + 22) +#define INT_NUM_IM3_IRL23 (INT_NUM_IM3_IRL0 + 23) +#define INT_NUM_IM3_IRL24 (INT_NUM_IM3_IRL0 + 24) +#define INT_NUM_IM3_IRL25 (INT_NUM_IM3_IRL0 + 25) +#define INT_NUM_IM3_IRL26 (INT_NUM_IM3_IRL0 + 26) +#define INT_NUM_IM3_IRL27 (INT_NUM_IM3_IRL0 + 27) +#define INT_NUM_IM3_IRL28 (INT_NUM_IM3_IRL0 + 28) +#define INT_NUM_IM3_IRL29 (INT_NUM_IM3_IRL0 + 29) +#define INT_NUM_IM3_IRL30 (INT_NUM_IM3_IRL0 + 30) +#define INT_NUM_IM3_IRL31 (INT_NUM_IM3_IRL0 + 31) + +#define INT_NUM_IM4_IRL0 (INT_NUM_IRQ0 + 128) +#define INT_NUM_IM4_IRL1 (INT_NUM_IM4_IRL0 + 1) +#define INT_NUM_IM4_IRL2 (INT_NUM_IM4_IRL0 + 2) +#define INT_NUM_IM4_IRL3 (INT_NUM_IM4_IRL0 + 3) +#define INT_NUM_IM4_IRL4 (INT_NUM_IM4_IRL0 + 4) +#define INT_NUM_IM4_IRL5 (INT_NUM_IM4_IRL0 + 5) +#define INT_NUM_IM4_IRL6 (INT_NUM_IM4_IRL0 + 6) +#define INT_NUM_IM4_IRL7 (INT_NUM_IM4_IRL0 + 7) +#define INT_NUM_IM4_IRL8 (INT_NUM_IM4_IRL0 + 8) +#define INT_NUM_IM4_IRL9 (INT_NUM_IM4_IRL0 + 9) +#define INT_NUM_IM4_IRL10 (INT_NUM_IM4_IRL0 + 10) +#define INT_NUM_IM4_IRL11 (INT_NUM_IM4_IRL0 + 11) +#define INT_NUM_IM4_IRL12 (INT_NUM_IM4_IRL0 + 12) +#define INT_NUM_IM4_IRL13 (INT_NUM_IM4_IRL0 + 13) +#define INT_NUM_IM4_IRL14 (INT_NUM_IM4_IRL0 + 14) +#define INT_NUM_IM4_IRL15 (INT_NUM_IM4_IRL0 + 15) +#define INT_NUM_IM4_IRL16 (INT_NUM_IM4_IRL0 + 16) +#define INT_NUM_IM4_IRL17 (INT_NUM_IM4_IRL0 + 17) +#define INT_NUM_IM4_IRL18 (INT_NUM_IM4_IRL0 + 18) +#define INT_NUM_IM4_IRL19 (INT_NUM_IM4_IRL0 + 19) +#define INT_NUM_IM4_IRL20 (INT_NUM_IM4_IRL0 + 20) +#define INT_NUM_IM4_IRL21 (INT_NUM_IM4_IRL0 + 21) +#define INT_NUM_IM4_IRL22 (INT_NUM_IM4_IRL0 + 22) +#define INT_NUM_IM4_IRL23 (INT_NUM_IM4_IRL0 + 23) +#define INT_NUM_IM4_IRL24 (INT_NUM_IM4_IRL0 + 24) +#define INT_NUM_IM4_IRL25 (INT_NUM_IM4_IRL0 + 25) +#define INT_NUM_IM4_IRL26 (INT_NUM_IM4_IRL0 + 26) +#define INT_NUM_IM4_IRL27 (INT_NUM_IM4_IRL0 + 27) +#define INT_NUM_IM4_IRL28 (INT_NUM_IM4_IRL0 + 28) +#define INT_NUM_IM4_IRL29 (INT_NUM_IM4_IRL0 + 29) +#define INT_NUM_IM4_IRL30 (INT_NUM_IM4_IRL0 + 30) +#define INT_NUM_IM4_IRL31 (INT_NUM_IM4_IRL0 + 31) + +/****** Interrupt Assigments ***********/ +#define AMAZON_DMA_INT INT_NUM_IM0_IRL0 +#define IFX_SSC_TIR INT_NUM_IM0_IRL29 +#define IFX_SSC_RIR INT_NUM_IM0_IRL30 +#define IFX_SSC_EIR INT_NUM_IM0_IRL31 + +#define AMAZON_MEI_INT INT_NUM_IM2_IRL8 + +#define AMAZONASC_TIR INT_NUM_IM4_IRL15/* TX interrupt */ +#define AMAZONASC_RIR INT_NUM_IM4_IRL16/* RX interrupt */ +#define AMAZONASC_EIR INT_NUM_IM4_IRL17/* ERROR interrupt */ + +#define AMAZON_TIMER6_INT INT_NUM_IM1_IRL23 + +#define AMAZON_SWIE_INT INT_NUM_IM3_IRL8 +#define AMAZON_CBM_INT INT_NUM_IM3_IRL9 +#define AMAZON_AAL5_INT INT_NUM_IM3_IRL10 +#define AMAZON_HTU_INT INT_NUM_IM3_IRL11 +#define AMAZON_QSB_INT INT_NUM_IM3_IRL12 +#define MIPS_CPU_TIMER_IRQ 7 +#endif /* __AMAZON_IRQ */ diff --git a/target/linux/amazon/files/include/asm-mips/amazon/model.h b/target/linux/amazon/files/include/asm-mips/amazon/model.h new file mode 100644 index 0000000000..4e43ab5f19 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/model.h @@ -0,0 +1,29 @@ +#ifndef AMAZON_MODEL_H +#define AMAZON_MODEL_H +/****************************************************************************** + Copyright (c) 2002, Infineon Technologies. All rights reserved. + + No Warranty + Because the program is licensed free of charge, there is no warranty for + the program, to the extent permitted by applicable law. Except when + otherwise stated in writing the copyright holders and/or other parties + provide the program "as is" without warranty of any kind, either + expressed or implied, including, but not limited to, the implied + warranties of merchantability and fitness for a particular purpose. The + entire risk as to the quality and performance of the program is with + you. should the program prove defective, you assume the cost of all + necessary servicing, repair or correction. + + In no event unless required by applicable law or agreed to in writing + will any copyright holder, or any other party who may modify and/or + redistribute the program as permitted above, be liable to you for + damages, including any general, special, incidental or consequential + damages arising out of the use or inability to use the program + (including but not limited to loss of data or data being rendered + inaccurate or losses sustained by you or third parties or a failure of + the program to operate with any other programs), even if such holder or + other party has been advised of the possibility of such damages. +******************************************************************************/ +#define BOARD_SYSTEM_TYPE "AMAZON" +#define SYSTEM_MODEL_NAME "Amazon Gateway Package 3.2 Version" +#endif diff --git a/target/linux/amazon/files/include/asm-mips/amazon/port.h b/target/linux/amazon/files/include/asm-mips/amazon/port.h new file mode 100644 index 0000000000..21825794c5 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/port.h @@ -0,0 +1,72 @@ +/* + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * port.h + * + * Global Amazon port driver header file + * + */ + +/* Modification history */ +/* 21Jun2004 btxu Generate from Inca_IP project */ + + +#ifndef PORT_H +#define PORT_H + +struct amazon_port_ioctl_parm { + int port; + int pin; + int value; +}; +#define AMAZON_PORT_IOC_MAGIC 0xbf +#define AMAZON_PORT_IOCOD _IOW( AMAZON_PORT_IOC_MAGIC,0,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCPUDSEL _IOW( AMAZON_PORT_IOC_MAGIC,1,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCPUDEN _IOW( AMAZON_PORT_IOC_MAGIC,2,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCSTOFF _IOW( AMAZON_PORT_IOC_MAGIC,3,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCDIR _IOW( AMAZON_PORT_IOC_MAGIC,4,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCOUTPUT _IOW( AMAZON_PORT_IOC_MAGIC,5,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCINPUT _IOWR(AMAZON_PORT_IOC_MAGIC,6,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCALTSEL0 _IOW( AMAZON_PORT_IOC_MAGIC,7,struct amazon_port_ioctl_parm) +#define AMAZON_PORT_IOCALTSEL1 _IOW( AMAZON_PORT_IOC_MAGIC,8,struct amazon_port_ioctl_parm) + +int amazon_port_reserve_pin(int port, int pin, int module_id); +int amazon_port_free_pin(int port, int pin, int module_id); +int amazon_port_set_open_drain(int port, int pin, int module_id); +int amazon_port_clear_open_drain(int port, int pin, int module_id); +int amazon_port_set_pudsel(int port, int pin, int module_id); +int amazon_port_clear_pudsel(int port, int pin, int module_id); +int amazon_port_set_puden(int port, int pin, int module_id); +int amazon_port_clear_puden(int port, int pin, int module_id); +int amazon_port_set_stoff(int port, int pin, int module_id); +int amazon_port_clear_stoff(int port, int pin, int module_id); +int amazon_port_set_dir_out(int port, int pin, int module_id); +int amazon_port_set_dir_in(int port, int pin, int module_id); +int amazon_port_set_output(int port, int pin, int module_id); +int amazon_port_clear_output(int port, int pin, int module_id); +int amazon_port_get_input(int port, int pin, int module_id); + +int amazon_port_set_altsel0(int port, int pin, int module_id); +int amazon_port_clear_altsel0(int port, int pin, int module_id); +int amazon_port_set_altsel1(int port, int pin, int module_id); +int amazon_port_clear_altsel1(int port, int pin, int module_id); + + +#endif /* PORT_H */ + + diff --git a/target/linux/amazon/files/include/asm-mips/amazon/serial.h b/target/linux/amazon/files/include/asm-mips/amazon/serial.h new file mode 100644 index 0000000000..3ff3efc28d --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/amazon/serial.h @@ -0,0 +1,146 @@ +/* incaAscSio.h - (AMAZON) ASC UART tty driver header */ + +#ifndef __AMAZON_ASC_H +#define __AMAZON_ASC_H + +/* channel operating modes */ +#define ASCOPT_CSIZE 0x00000003 +#define ASCOPT_CS7 0x00000001 +#define ASCOPT_CS8 0x00000002 +#define ASCOPT_PARENB 0x00000004 +#define ASCOPT_STOPB 0x00000008 +#define ASCOPT_PARODD 0x00000010 +#define ASCOPT_CREAD 0x00000020 + +#define ASC_OPTIONS (ASCOPT_CREAD | ASCOPT_CS8) + +/* ASC input select (0 or 1) */ +#define CONSOLE_TTY 0 + +/* use fractional divider for baudrate settings */ +#define AMAZONASC_USE_FDV + +#ifdef AMAZONASC_USE_FDV + #define AMAZONASC_FDV_LOW_BAUDRATE 71 +#ifdef CONFIG_USE_IKOS + #define AMAZONASC_FDV_HIGH_BAUDRATE 443 +#else + #define AMAZONASC_FDV_HIGH_BAUDRATE 498 +#endif //CONFIG_USE_IKOS +#endif /*AMAZONASC_USE_FDV*/ + + +#define AMAZONASC_TXFIFO_FL 1 +#define AMAZONASC_RXFIFO_FL 1 +#define AMAZONASC_TXFIFO_FULL 16 + +/* interrupt lines masks for the ASC device interrupts*/ +/* change these macroses if it's necessary */ +#define AMAZONASC_IRQ_LINE_ALL 0x000F0000 /* all IRQs */ + +#define AMAZONASC_IRQ_LINE_TIR 0x00010000 /* TIR - Tx */ +#define AMAZONASC_IRQ_LINE_RIR 0x00020000 /* RIR - Rx */ +#define AMAZONASC_IRQ_LINE_EIR 0x00040000 /* EIR - Err */ +#define AMAZONASC_IRQ_LINE_TBIR 0x00080000 /* TBIR - Tx Buf*/ + +/* CLC register's bits and bitfields */ +#define ASCCLC_DISR 0x00000001 +#define ASCCLC_DISS 0x00000002 +#define ASCCLC_RMCMASK 0x0000FF00 +#define ASCCLC_RMCOFFSET 8 + +/* CON register's bits and bitfields */ +#define ASCCON_MODEMASK 0x0007 + #define ASCCON_M_8SYNC 0x0 + #define ASCCON_M_8ASYNC 0x1 + #define ASCCON_M_8IRDAASYNC 0x2 + #define ASCCON_M_7ASYNCPAR 0x3 + #define ASCCON_M_9ASYNC 0x4 + #define ASCCON_M_8WAKEUPASYNC 0x5 + #define ASCCON_M_8ASYNCPAR 0x7 +#define ASCCON_STP 0x0008 +#define ASCCON_REN 0x0010 +#define ASCCON_PEN 0x0020 +#define ASCCON_FEN 0x0040 +#define ASCCON_OEN 0x0080 +#define ASCCON_PE 0x0100 +#define ASCCON_FE 0x0200 +#define ASCCON_OE 0x0400 +#define ASCCON_FDE 0x0800 +#define ASCCON_ODD 0x1000 +#define ASCCON_BRS 0x2000 +#define ASCCON_LB 0x4000 +#define ASCCON_R 0x8000 +#define ASCCON_ANY (ASCCON_PE|ASCCON_FE|ASCCON_OE) + +/* WHBCON register's bits and bitfields */ +#define ASCWHBCON_CLRREN 0x0010 +#define ASCWHBCON_SETREN 0x0020 +#define ASCWHBCON_CLRPE 0x0100 +#define ASCWHBCON_CLRFE 0x0200 +#define ASCWHBCON_CLROE 0x0400 +#define ASCWHBCON_SETPE 0x0800 +#define ASCWHBCON_SETFE 0x1000 +#define ASCWHBCON_SETOE 0x2000 + +/* ABCON register's bits and bitfields */ +#define ASCABCON_ABEN 0x0001 +#define ASCABCON_AUREN 0x0002 +#define ASCABCON_ABSTEN 0x0004 +#define ASCABCON_ABDETEN 0x0008 +#define ASCABCON_FCDETEN 0x0010 +#define ASCABCON_EMMASK 0x0300 + #define ASCABCON_EMOFF 8 + #define ASCABCON_EM_DISAB 0x0 + #define ASCABCON_EM_DURAB 0x1 + #define ASCABCON_EM_ALWAYS 0x2 +#define ASCABCON_TXINV 0x0400 +#define ASCABCON_RXINV 0x0800 + +/* FDV register mask, offset and bitfields*/ +#define ASCFDV_VALUE_MASK 0x000001FF + +/* WHBABCON register's bits and bitfields */ +#define ASCWHBABCON_SETABEN 0x0001 +#define ASCWHBABCON_CLRABEN 0x0002 + +/* ABSTAT register's bits and bitfields */ +#define ASCABSTAT_FCSDET 0x0001 +#define ASCABSTAT_FCCDET 0x0002 +#define ASCABSTAT_SCSDET 0x0004 +#define ASCABSTAT_SCCDET 0x0008 +#define ASCABSTAT_DETWAIT 0x0010 + +/* WHBABSTAT register's bits and bitfields */ +#define ASCWHBABSTAT_CLRFCSDET 0x0001 +#define ASCWHBABSTAT_SETFCSDET 0x0002 +#define ASCWHBABSTAT_CLRFCCDET 0x0004 +#define ASCWHBABSTAT_SETFCCDET 0x0008 +#define ASCWHBABSTAT_CLRSCSDET 0x0010 +#define ASCWHBABSTAT_SETSCSDET 0x0020 +#define ASCWHBABSTAT_SETSCCDET 0x0040 +#define ASCWHBABSTAT_CLRSCCDET 0x0080 +#define ASCWHBABSTAT_CLRDETWAIT 0x0100 +#define ASCWHBABSTAT_SETDETWAIT 0x0200 + +/* TXFCON register's bits and bitfields */ +#define ASCTXFCON_TXFEN 0x0001 +#define ASCTXFCON_TXFFLU 0x0002 +#define ASCTXFCON_TXTMEN 0x0004 +#define ASCTXFCON_TXFITLMASK 0x3F00 +#define ASCTXFCON_TXFITLOFF 8 + +/* RXFCON register's bits and bitfields */ +#define ASCRXFCON_RXFEN 0x0001 +#define ASCRXFCON_RXFFLU 0x0002 +#define ASCRXFCON_RXTMEN 0x0004 +#define ASCRXFCON_RXFITLMASK 0x3F00 +#define ASCRXFCON_RXFITLOFF 8 + +/* FSTAT register's bits and bitfields */ +#define ASCFSTAT_RXFFLMASK 0x003F +#define ASCFSTAT_TXFFLMASK 0x3F00 +#define ASCFSTAT_TXFFLOFF 8 + +#endif /* __AMAZON_ASC_H */ + diff --git a/target/linux/amazon/files/include/asm-mips/mach-amazon/irq.h b/target/linux/amazon/files/include/asm-mips/mach-amazon/irq.h new file mode 100644 index 0000000000..e72b7d5c11 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/mach-amazon/irq.h @@ -0,0 +1,7 @@ +#ifndef __AMAZON_IRQ_H +#define __AMAZON_IRQ_H + +#define NR_IRQS 256 +#include_next <irq.h> + +#endif diff --git a/target/linux/amazon/files/include/asm-mips/mach-amazon/mangle-port.h b/target/linux/amazon/files/include/asm-mips/mach-amazon/mangle-port.h new file mode 100644 index 0000000000..9aefebbe63 --- /dev/null +++ b/target/linux/amazon/files/include/asm-mips/mach-amazon/mangle-port.h @@ -0,0 +1,52 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003, 2004 Ralf Baechle + */ +#ifndef __ASM_MACH_GENERIC_MANGLE_PORT_H +#define __ASM_MACH_GENERIC_MANGLE_PORT_H + +#define __swizzle_addr_b(port) (port) +#define __swizzle_addr_w(port) ((port) ^ 2) +#define __swizzle_addr_l(port) (port) +#define __swizzle_addr_q(port) (port) + +/* + * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware; + * less sane hardware forces software to fiddle with this... + * + * Regardless, if the host bus endianness mismatches that of PCI/ISA, then + * you can't have the numerical value of data and byte addresses within + * multibyte quantities both preserved at the same time. Hence two + * variations of functions: non-prefixed ones that preserve the value + * and prefixed ones that preserve byte addresses. The latters are + * typically used for moving raw data between a peripheral and memory (cf. + * string I/O functions), hence the "__mem_" prefix. + */ +#if defined(CONFIG_SWAP_IO_SPACE) + +# define ioswabb(a,x) (x) +# define __mem_ioswabb(a,x) (x) +# define ioswabw(a,x) le16_to_cpu(x) +# define __mem_ioswabw(a,x) (x) +# define ioswabl(a,x) le32_to_cpu(x) +# define __mem_ioswabl(a,x) (x) +# define ioswabq(a,x) le64_to_cpu(x) +# define __mem_ioswabq(a,x) (x) + +#else + +# define ioswabb(a,x) (x) +# define __mem_ioswabb(a,x) (x) +# define ioswabw(a,x) (x) +# define __mem_ioswabw(a,x) cpu_to_le16(x) +# define ioswabl(a,x) (x) +# define __mem_ioswabl(a,x) cpu_to_le32(x) +# define ioswabq(a,x) (x) +# define __mem_ioswabq(a,x) cpu_to_le32(x) + +#endif + +#endif /* __ASM_MACH_GENERIC_MANGLE_PORT_H */ |