Skip to content
Snippets Groups Projects
Commit c1378fe9 authored by John Crispin's avatar John Crispin
Browse files

adds atm driver for ifxmips, code ported from wippies 2.6.16 gpl release. it...

adds atm driver for ifxmips, code ported from wippies 2.6.16 gpl release. it compiles but throws ioctl -EINVAL during bring up of atm device, hence marked as broken

SVN-Revision: 17819
parent 7f3ed114
No related branches found
No related tags found
No related merge requests found
# Copyright (C) 2009 OpenWrt.org
# All rights reserved.
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
# blogic@openwrt.org
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=ifxmips-atm
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define KernelPackage/ifxmips-atm
SUBMENU:=Network Devices
DEPENDS:=@BROKEN @TARGET_ifxmips +kmod-atm
TITLE:=ifxmips atm driver
FILES:=$(PKG_BUILD_DIR)/ifx-atm.$(LINUX_KMOD_SUFFIX)
AUTOLOAD:=$(call AutoLoad,50,ifx-atm)
endef
define Kernel/Package/ifxmips-atm/description
This package provides the atm driver needed to make dsl work on ifxmips based boards
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
SUBDIRS="$(PKG_BUILD_DIR)" \
modules
endef
define KernelPackage/ifxmips-atm/install
$(INSTALL_DIR) $(1)/lib/modules/$(LINUX_VERSION)
$(CP) $(PKG_BUILD_DIR)/ifx-atm.ko $(1)/lib/modules/$(LINUX_VERSION)
endef
$(eval $(call KernelPackage,ifxmips-atm))
obj-m += ifx-atm.o
ifx-atm-objs := skb.o irq.o proc.o core.o ppe.o
EXTRA_CFLAGS += -DENABLE_RX_QOS=1
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include <linux/atm.h>
#include <linux/proc_fs.h>
#include "proc.h"
#include "common.h"
struct proc_dir_entry *ppe_proc_dir;
int proc_read_idle_counter(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int len = 0;
len += sprintf(page + off, "Channel 0\n");
len += sprintf(page + off + len, " TX\n");
len += sprintf(page + off + len,
" DREG_AT_CELL0 = %d\n", *DREG_AT_CELL0 & 0xFFFF);
len += sprintf(page + off + len,
" DREG_AT_IDLE_CNT0 = %d\n", *DREG_AT_IDLE_CNT0 & 0xFFFF);
len += sprintf(page + off + len, " RX\n");
len += sprintf(page + off + len,
" DREG_AR_CELL0 = %d\n", *DREG_AR_CELL0 & 0xFFFF);
len += sprintf(page + off + len,
" DREG_AR_IDLE_CNT0 = %d\n", *DREG_AR_IDLE_CNT0 & 0xFFFF);
len += sprintf(page + off + len,
" DREG_AR_AIIDLE_CNT0 = %d\n", *DREG_AR_AIIDLE_CNT0 & 0xFFFF);
len += sprintf(page + off + len,
" DREG_AR_BE_CNT0 = %d\n", *DREG_AR_BE_CNT0 & 0xFFFF);
len += sprintf(page + off + len, "Channel 1\n");
len += sprintf(page + off + len, " TX\n");
len += sprintf(page + off + len,
" DREG_AT_CELL1 = %d\n", *DREG_AT_CELL1 & 0xFFFF);
len += sprintf(page + off + len,
" DREG_AT_IDLE_CNT1 = %d\n", *DREG_AT_IDLE_CNT1 & 0xFFFF);
len += sprintf(page + off + len, " RX\n");
len += sprintf(page + off + len,
" DREG_AR_CELL1 = %d\n", *DREG_AR_CELL1 & 0xFFFF);
len += sprintf(page + off + len,
" DREG_AR_IDLE_CNT1 = %d\n", *DREG_AR_IDLE_CNT1 & 0xFFFF);
len += sprintf(page + off + len,
" DREG_AR_AIIDLE_CNT1 = %d\n", *DREG_AR_AIIDLE_CNT1 & 0xFFFF);
len += sprintf(page + off + len,
" DREG_AR_BE_CNT1 = %d\n", *DREG_AR_BE_CNT1 & 0xFFFF);
return len;
}
int proc_read_stats(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int len = 0;
int i, j;
struct connection *connection;
struct port *port;
int base;
len += sprintf(page + off, "ATM Stats:\n");
connection = ppe_dev.connection;
port = ppe_dev.port;
for ( i = 0; i < ATM_PORT_NUMBER; i++, port++ )
{
base = port->connection_base;
for ( j = 0; j < port->max_connections; j++, base++ )
if ( (port->connection_table & (1 << j))
&& connection[base].vcc != NULL )
{
if ( connection[base].vcc->stats )
{
struct k_atm_aal_stats *stats = connection[base].vcc->stats;
len += sprintf(page + off + len, " VCC %d.%d.%d (stats)\n", i, connection[base].vcc->vpi, connection[base].vcc->vci);
len += sprintf(page + off + len, " rx = %d\n", stats->rx.counter);
len += sprintf(page + off + len, " rx_err = %d\n", stats->rx_err.counter);
len += sprintf(page + off + len, " rx_drop = %d\n", stats->rx_drop.counter);
len += sprintf(page + off + len, " tx = %d\n", stats->tx.counter);
len += sprintf(page + off + len, " tx_err = %d\n", stats->tx_err.counter);
}
else
len += sprintf(page + off + len, " VCC %d.%d.%d\n", i, connection[base].vcc->vpi, connection[base].vcc->vci);
}
}
return len;
}
void proc_file_create(void)
{
ppe_proc_dir = proc_mkdir("ppe", NULL);
create_proc_read_entry("idle_counter", 0, ppe_proc_dir, proc_read_idle_counter, NULL);
create_proc_read_entry("stats", 0, ppe_proc_dir, proc_read_stats, NULL);
}
void proc_file_delete(void)
{
remove_proc_entry("idle_counter", ppe_proc_dir);
remove_proc_entry("stats", ppe_proc_dir);
remove_proc_entry("ppe", NULL);
}
#ifndef _IFXMIPS_PPE_PROC_H__
#define _IFXMIPS_PPE_PROC_H__
void proc_file_create(void);
void proc_file_delete(void);
int proc_read_idle_counter(char *page, char **start, off_t off, int count, int *eof, void *data);
int proc_read_stats(char *page, char **start, off_t off, int count, int *eof, void *data);
#endif
#include <linux/skbuff.h>
#include "common.h"
void resize_skb_rx(struct sk_buff *skb, unsigned int size, int is_cell)
{
if((u32)skb < 0x80000000)
{
int key = 0;
printk("resize_skb_rx problem: skb = %08X, size = %d, is_cell = %d\n", (u32)skb, size, is_cell);
while(!key){}
}
skb->data = (unsigned char*)(((u32)skb->head + 16 + (DMA_ALIGNMENT - 1)) & ~(DMA_ALIGNMENT - 1));
skb->tail = skb->data;
/* Set up other state */
skb->len = 0;
skb->cloned = 0;
#if defined(CONFIG_IMQ) || defined (CONFIG_IMQ_MODULE)
skb->imq_flags = 0;
skb->nf_info = NULL;
#endif
skb->data_len = 0;
}
struct sk_buff* alloc_skb_rx(void)
{
struct sk_buff *skb;
/* allocate memroy including trailer and padding */
skb = dev_alloc_skb(ppe_dev.aal5.rx_buffer_size + DMA_ALIGNMENT);
if (skb)
{
/* must be burst length alignment */
if ( ((u32)skb->data & (DMA_ALIGNMENT - 1)) != 0 )
skb_reserve(skb, ~((u32)skb->data + (DMA_ALIGNMENT - 1)) & (DMA_ALIGNMENT - 1));
/* put skb in reserved area "skb->data - 4" */
*((u32*)skb->data - 1) = (u32)skb;
/* invalidate cache */
dma_cache_inv((unsigned long)skb->head, (u32)skb->end - (u32)skb->head);
}
return skb;
}
void atm_free_tx_skb_vcc(struct sk_buff *skb)
{
struct atm_vcc* vcc;
if ( (u32)skb <= 0x80000000 )
{
volatile int key = 0;
printk("atm_free_tx_skb_vcc: skb = %08X\n", (u32)skb);
for ( ; !key; );
}
vcc = ATM_SKB(skb)->vcc;
if ( vcc != NULL && vcc->pop != NULL )
{
if ( atomic_read(&skb->users) == 0 )
{
volatile int key = 0;
printk("atm_free_tx_skb_vcc(vcc->pop): skb->users == 0, skb = %08X\n", (u32)skb);
for ( ; !key; );
}
vcc->pop(vcc, skb);
}
else
{
if ( atomic_read(&skb->users) == 0 )
{
volatile int key = 0;
printk("atm_free_tx_skb_vcc(dev_kfree_skb_any): skb->users == 0, skb = %08X\n", (u32)skb);
for ( ; !key; );
}
dev_kfree_skb_any(skb);
}
}
struct sk_buff* alloc_skb_tx(unsigned int size)
{
struct sk_buff *skb;
/* allocate memory including header and padding */
size += TX_INBAND_HEADER_LENGTH + MAX_TX_PACKET_ALIGN_BYTES + MAX_TX_PACKET_PADDING_BYTES;
size &= ~(DMA_ALIGNMENT - 1);
skb = dev_alloc_skb(size + DMA_ALIGNMENT);
/* must be burst length alignment */
if ( skb )
skb_reserve(skb, (~((u32)skb->data + (DMA_ALIGNMENT - 1)) & (DMA_ALIGNMENT - 1)) + TX_INBAND_HEADER_LENGTH);
return skb;
}
struct sk_buff* atm_alloc_tx(struct atm_vcc *vcc, unsigned int size)
{
int conn;
struct sk_buff *skb;
/* oversize packet */
if ( ((size + TX_INBAND_HEADER_LENGTH + MAX_TX_PACKET_ALIGN_BYTES + MAX_TX_PACKET_PADDING_BYTES) & ~(DMA_ALIGNMENT - 1)) > ppe_dev.aal5.tx_max_packet_size )
{
printk("atm_alloc_tx: oversize packet\n");
return NULL;
}
/* send buffer overflow */
if ( atomic_read(&vcc->sk.sk_wmem_alloc) && !atm_may_send(vcc, size) )
{
printk("atm_alloc_tx: send buffer overflow\n");
return NULL;
}
conn = find_vcc(vcc);
if ( conn < 0 )
{
printk("atm_alloc_tx: unknown VCC\n");
return NULL;
}
skb = dev_alloc_skb(size);
if ( skb == NULL )
{
printk("atm_alloc_tx: sk buffer is used up\n");
return NULL;
}
#define ATM_PDU_OVHD 0
atomic_add(skb->truesize + ATM_PDU_OVHD, &vcc->sk.sk_wmem_alloc);
return skb;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment