SOURCES (LINUX_2_6): kernel-tahoe9xx.patch (NEW) - from http://www...

paszczus paszczus at pld-linux.org
Sat Jan 21 14:11:56 CET 2006


Author: paszczus                     Date: Sat Jan 21 13:11:56 2006 GMT
Module: SOURCES                       Tag: LINUX_2_6
---- Log message:
- from http://www.tahoe.pl/drivers/tahoe9xx-2.6.4-5.patch

---- Files affected:
SOURCES:
   kernel-tahoe9xx.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/kernel-tahoe9xx.patch
diff -u /dev/null SOURCES/kernel-tahoe9xx.patch:1.1.2.1
--- /dev/null	Sat Jan 21 14:11:56 2006
+++ SOURCES/kernel-tahoe9xx.patch	Sat Jan 21 14:11:51 2006
@@ -0,0 +1,872 @@
+--- linux/drivers/net/wan/Makefile	2003-03-06 14:56:13.000000000 +0100
++++ linux/drivers/net/wan/Makefile	2003-03-30 22:37:04.000000000 +0200
+@@ -66,6 +66,7 @@
+ endif
+ obj-$(CONFIG_N2)		+= n2.o
+ obj-$(CONFIG_C101)		+= c101.o
++obj-$(CONFIG_TAHOE9XX)		+= tahoe9xx.o
+ obj-$(CONFIG_WANXL)		+= wanxl.o
+ obj-$(CONFIG_PCI200SYN)		+= pci200syn.o
+ 
+--- linux/drivers/net/wan/tahoe9xx.c	2003-04-07 14:18:45.000000000 +0200
++++ linux/drivers/net/wan/tahoe9xx.c	2003-04-07 13:47:45.000000000 +0200
+@@ -0,0 +1,824 @@
++/*
++ * Tahoe 9xx synchronous serial card driver for Linux
++ *
++ * Copyright (C) 2002-2003 Krzysztof Halasa <khc at pm.waw.pl>
++ * Copyright (C) 2003 Piotr Kaczmarzyk <piotr at tahoe.pl>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License
++ * as published by the Free Software Foundation.
++ *
++ * For information see http://hq.pm.waw.pl/hdlc/
++ *
++ * Sources of information:
++ *    Hitachi HD64570 SCA User's Manual
++ *    PLX Technology Inc. PCI9052 Data Book
++ *    Dallas Semiconductor DS21554 Datasheet
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++#include <linux/fcntl.h>
++#include <linux/in.h>
++#include <linux/string.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/moduleparam.h>
++#include <linux/netdevice.h>
++#include <linux/hdlc.h>
++#include <linux/pci.h>
++#include <asm/delay.h>
++#include <asm/io.h>
++
++#include "hd64570.h"
++
++static const char* version = "Tahoe 9xx driver version: 1.16t";
++static const char* devname = "TAHOE9XX";
++
++#define	TAHOE9XX_PLX_SIZE	0x80	/* PLX control window size (128b) */
++#define	TAHOE9XX_SCA_SIZE	0x100	/* SCA window size (256b) */
++#define ALL_PAGES_ALWAYS_MAPPED
++#define NEED_DETECT_RAM
++#define NEED_SCA_MSCI_INTR
++#define MAX_TX_BUFFERS		10
++
++#define CLOCK_BASE 9216000
++
++#define G703_AMI		0
++#define G703_HDB3		1
++
++#define DEFAULT_LICR    0x80
++
++#define PCI_VENDOR_ID_TAHOE		0x8246
++#define PCI_DEVICE_ID_TAHOE931	0x0931
++#define PCI_DEVICE_ID_TAHOE932	0x0932
++#define PCI_DEVICE_ID_TAHOE971	0x0971
++#define PCI_DEVICE_ID_TAHOE972	0x0972
++
++/*
++ *      PLX PCI9052 local configuration and shared runtime registers.
++ *	This structure can be used to access 9052 registers (memory mapped).
++ */
++typedef struct {
++	u32 loc_addr_range[4];	/* 00-0Ch : Local Address Ranges */
++	u32 loc_rom_range;	/* 10h : Local ROM Range */
++	u32 loc_addr_base[4];	/* 14-20h : Local Address Base Addrs */
++	u32 loc_rom_base;	/* 24h : Local ROM Base */
++	u32 loc_bus_descr[4];	/* 28-34h : Local Bus Descriptors */
++	u32 rom_bus_descr;	/* 38h : ROM Bus Descriptor */
++	u32 cs_base[4];		/* 3C-48h : Chip Select Base Addrs */
++	u32 intr_ctrl_stat;	/* 4Ch : Interrupt Control/Status */
++	u32 init_ctrl;		/* 50h : EEPROM ctrl, Init Ctrl, etc */
++}plx9052;
++
++
++
++
++
++typedef struct ds21554_s {
++	u8	vcr1;		/* Counter:	Violation Error */
++	u8	vcr2;
++	u8	crccr1;		/* Counter:	CRC4 Error */
++	u8	crccr2;
++	u8	ebcr1;		/* Counter:	E-bit Error (FEBE) */
++	u8	ebcr2;
++	u8	sr1;		/* Status:	Status Register 1 */
++	u8	sr2;		/* Status:	Status Register 2 */
++	u8	rir;		/* Status:	Receive Information */
++	u8	reserved1[6];
++	u8	idr;		/* Misc:	Device Indentification */
++	u8	rcr1;		/* Control:	Receive Control 1 */
++	u8	rcr2;		/* Control:	Receive Control 2 */
++	u8	tcr1;		/* Control:	Transmit Control 1 */
++	u8	tcr2;		/* Control:	Transmit Control 2 */
++	u8	ccr1;		/* Control:	Common Control 1 */
++	u8	test1;
++	u8	imr1;		/* Interrupt Mask 1 */
++	u8	imr2;		/* Interrupt Mask 2 */
++	u8	licr;		/* Control: Line interface */
++	u8	test2;
++	u8	ccr2;		/* Control: Common Control 2 */
++	u8	ccr3;		/* Control: Common Control 3 */
++	u8	tsacr;		/* Control: Transmit Sa bit */
++	u8	ccr6;		/* Control: Common Control 6 */
++	u8	ssr;		/* Status: 	Synchronizer Status */
++	u8	rnaf;		/* Receive non-align frame */
++	u8	taf;		/* Transmit align frame */
++	u8	tnaf;		/* Transmit non-align frame */
++	u8	tcbr1;		/* Transmit channel blocking */
++	u8	tcbr2;
++	u8	tcbr3;
++	u8	tcbr4;
++	u8	tir1;		/* Transmit idle */
++	u8	tir2;
++	u8	tir3;
++	u8	tir4;
++	u8	tidr;		/* Transmit idle definition */
++	u8	rcbr1;		/* Receive channel blocking */
++	u8	rcbr2;
++	u8	rcbr3;
++	u8	rcbr4;
++	u8	raf;		/* Receive align frame */
++	u8	rs1;		/* Receive signalling */
++	u8	rs2;
++	u8	rs3;
++	u8	rs4;
++	u8	rs5;
++	u8	rs6;
++	u8	rs7;
++	u8	rs8;
++	u8	rs9;
++	u8	rs10;
++	u8	rs11;
++	u8	rs12;
++	u8	rs13;
++	u8	rs14;
++	u8	rs15;
++	u8	rs16;
++	u8	ts1;		/* Transmit signaling */
++	u8	ts2;
++	u8	ts3;
++	u8	ts4;
++	u8	ts5;
++	u8	ts6;
++	u8	ts7;
++	u8	ts8;
++	u8	ts9;
++	u8	ts10;
++	u8	ts11;
++	u8	ts12;
++	u8	ts13;
++	u8	ts14;
++	u8	ts15;
++	u8	ts16;
++	u8	tsiaf;		/* Transmit Si Bits Align Frame */
++	u8	tsinaf;		/* Transmit Si Bits Non-align Frame */
++	u8	tra;		/* Transmit Remote Alarm Bits */
++	u8	tsa4;		/* Transmit Sa Bits */
++	u8	tsa5;
++	u8	tsa6;
++	u8	tsa7;
++	u8	tsa8;
++	u8	rsiaf;		/* Receive Si Bits Align Frame */
++	u8	rsinaf;		/* Receive Si Bits Non-Align Frame */
++	u8	rra;		/* Receive Remote Alarm Bits */
++	u8	rsa4;		/* Receive Sa Bits */
++	u8	rsa5;
++	u8	rsa6;
++	u8	rsa7;
++	u8	rsa8;
++	u8	tc1;		/* Transmit channel */
++	u8	tc2;
++	u8	tc3;
++	u8	tc4;
++	u8	tc5;
++	u8	tc6;
++	u8	tc7;
++	u8	tc8;
++	u8	tc9;
++	u8	tc10;
++	u8	tc11;
++	u8	tc12;
++	u8	tc13;
++	u8	tc14;
++	u8	tc15;
++	u8	tc16;
++	u8	tc17;
++	u8	tc18;
++	u8	tc19;
++	u8	tc20;
++	u8	tc21;
++	u8	tc22;
++	u8	tc23;
++	u8	tc24;
++	u8	tc25;
++	u8	tc26;
++	u8	tc27;
++	u8	tc28;
++	u8	tc29;
++	u8	tc30;
++	u8	tc31;
++	u8	tc32;
++	u8	rc1;		/* Receive channel */
++	u8	rc2;
++	u8	rc3;
++	u8	rc4;
++	u8	rc5;
++	u8	rc6;
++	u8	rc7;
++	u8	rc8;
++	u8	rc9;
++	u8	rc10;
++	u8	rc11;
++	u8	rc12;
++	u8	rc13;
++	u8	rc14;
++	u8	rc15;
++	u8	rc16;
++	u8	rc17;
++	u8	rc18;
++	u8	rc19;
++	u8	rc20;
++	u8	rc21;
++	u8	rc22;
++	u8	rc23;
++	u8	rc24;
++	u8	rc25;
++	u8	rc26;
++	u8	rc27;
++	u8	rc28;
++	u8	rc29;
++	u8	rc30;
++	u8	rc31;
++	u8	rc32;
++	u8	tcc1;		/* Transmit channel control */
++	u8	tcc2;
++	u8	tcc3;
++	u8	tcc4;
++	u8	rcc1;		/* Receive channel control */
++	u8	rcc2;
++	u8	rcc3;
++	u8	rcc4;
++	u8	ccr4;		/* Control:	Common Control 4 */
++	u8	tds0m;		/* Transmit DS0 Monitor */
++	u8	ccr5;		/* Control:	Common Control 5 */
++	u8	rds0m;		/* Receive DS0 Monitor */
++	u8	test3;
++	u8	reserved2[3];
++	u8	hcr;		/* HDLC Control */
++	u8	hsr;		/* HDLC Status */
++	u8	himr;		/* HDLC Interrupt Mask */
++	u8	rhir;		/* Receive HDLC Information */
++	u8	rhfr;		/* Receive HDLC FIFO */
++	u8	ibo;		/* Interleave Bus Operation */
++	u8	thir;		/* Transmit HDLC Information */
++	u8	thfr;		/* Transmit HDLC FIFO */
++	u8	rdc1;		/* Receive HDLC DS0 Control 1 */
++	u8	rdc2;		/* Receive HDLC DS0 Control 2 */
++	u8	tdc1;		/* Transmit HDLC DS0 Control 1 */
++	u8	tdc2;		/* Transmit HDLC DS0 Control 2 */
++	u8	reserved3[4];
++} ds21554_t;
++
++typedef struct port_s {
++	struct net_device *dev;
++    struct card_s *card;
++	spinlock_t lock;	/* TX lock */
++	te1_settings settings;
++	int rxpart;		/* partial frame received, next frame invalid*/
++	unsigned short encoding;
++	unsigned short parity;
++	u16 rxin;		/* rx ring buffer 'in' pointer */
++	u16 txin;		/* tx ring buffer 'in' and 'last' pointers */
++	u16 txlast;
++	u8 rxs, txs, tmc;	/* SCA registers */
++	u8 phy_node;		/* physical port # - 0 or 1 */
++	u32 dsphys;			/* DS21544 memory base (physical) */
++	ds21554_t* dsbase;	/* DS21544 memory base (virtual) */
++	u8	g703_on;		/* Enable/disable G.703 transceiver */
++	u8	g703_coding;	/* G.703 line coding */
++	u8	g703_idlecode;	/* G.703 idle timeslots contents */
++}port_t;
++
++typedef struct card_s {
++	u8* rambase;		/* buffer memory base (virtual) */
++	u8* scabase;		/* SCA memory base (virtual) */
++	plx9052* plxbase;	/* PLX registers memory base (virtual) */
++	u16 rx_ring_buffers;	/* number of buffers in a ring */
++	u16 tx_ring_buffers;
++	u16 buff_offset;	/* offset of first buffer of first channel */
++	u8 irq;				/* interrupt request level */
++	u8 no_ports;		/* number of ports */
++	char dev_name[10];	/* device name */
++	port_t ports[2];
++}card_t;
++
++#define sca_in(reg, card)	     readb(card->scabase + (reg))
++#define sca_out(value, reg, card)    writeb(value, card->scabase + (reg))
++#define sca_inw(reg, card)	     readw(card->scabase + (reg))
++#define sca_outw(value, reg, card)   writew(value, card->scabase + (reg))
++#define sca_inl(reg, card)	     readl(card->scabase + (reg))
++#define sca_outl(value, reg, card)   writel(value, card->scabase + (reg))
++
++#define port_to_card(port)	     (port->card)
++#define log_node(port)		     (port->phy_node)
++#define phy_node(port)		     (port->phy_node)
++#define winbase(card)      	     (card->rambase)
++#define get_port(card, port)	     (&card->ports[port])
++#define sca_flush(card)		     (sca_in(IER0, card));
++
++static inline void new_memcpy_toio(char *dest, char *src, int length)
++{
++	int len;
++	
++	do {
++		len = length > 64 ? 64 : length; /* 32 */
++		memcpy_toio(dest, src, len);
++		dest += len;
++		src += len;
++		length -= len;
++		readb(dest);
++	} while (len);
++}
++
++#undef memcpy_toio
++#define memcpy_toio new_memcpy_toio
++
++#include "hd6457x.c"
++
++void init_ds21554(port_t *port);
++
++static void t9xx_set_iface(port_t *port)
++{
++	card_t *card = port->card;
++	u8 msci = get_msci(port);
++	u8 rxs = port->rxs & CLK_BRG_MASK;
++	u8 txs = port->txs & CLK_BRG_MASK;
++	
++	if (port->dsbase) {
++		init_ds21554(port);
++	}
++	
++	rxs |= CLK_LINE_RX; /* RXC input */
++	txs |= CLK_LINE_TX; /* TXC input */
++
++	port->rxs = rxs;
++	port->txs = txs;
++	sca_out(rxs, msci + RXS, card);
++	sca_out(txs, msci + TXS, card);
++	sca_set_port(port);
++}
++
++
++
++static int t9xx_open(struct net_device *dev)
++{
++	port_t *port = dev_to_port(dev);
++
++	int result = hdlc_open(dev);
++	if (result)
++		return result;
++
++	sca_open(dev);
++	t9xx_set_iface(port);
++	sca_flush(port_to_card(port));
++	return 0;
++}
++
++
++
++static int t9xx_close(struct net_device *dev)
++{
++	sca_close(dev);
++	sca_flush(port_to_card(dev_to_port(dev)));
++	hdlc_close(dev);
++	return 0;
++}
++
++
++
++static int t9xx_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
++{
++	const size_t size = sizeof(te1_settings);
++	te1_settings new_line, *line = ifr->ifr_settings.ifs_ifsu.te1;
++	port_t *port = dev_to_port(dev);
++
++#ifdef DEBUG_RINGS
++	if (cmd == SIOCDEVPRIVATE) {
++		sca_dump_rings(dev);
++		return 0;
++	}
++#endif
++	if (cmd != SIOCWANDEV)
++		return hdlc_ioctl(dev, ifr, cmd);
++
++	switch(ifr->ifr_settings.type) {
++	case IF_GET_IFACE:
++		if (port->dsbase)
++			ifr->ifr_settings.type = IF_IFACE_E1;
++		else
++			ifr->ifr_settings.type = IF_IFACE_V35;
++		if (ifr->ifr_settings.size < size) {
++			ifr->ifr_settings.size = size; /* data size wanted */
++			return -ENOBUFS;
++		}
++		if (copy_to_user(line, &port->settings, size))
++			return -EFAULT;
++		return 0;
++
++	case IF_IFACE_E1:
++	case IF_IFACE_V35:
++		if (!capable(CAP_NET_ADMIN))
++			return -EPERM;
++
++		if (copy_from_user(&new_line, line, size))
++			return -EFAULT;
++
++		if (new_line.clock_type != CLOCK_EXT)
++			return -EINVAL;	/* No such clock setting */
++
++		if (new_line.loopback > 3)
++			return -EINVAL;
++
++		memcpy(&port->settings, &new_line, size); /* Update settings */
++		t9xx_set_iface(port);
++		sca_flush(port_to_card(port));
++		return 0;
++
++	default:
++		return hdlc_ioctl(dev, ifr, cmd);
++	}
++}
++
++
++
++static void t9xx_pci_remove_one(struct pci_dev *pdev)
++{
++	int i, ports;
++	card_t *card = pci_get_drvdata(pdev);
++
++	if ((pdev->subsystem_device == PCI_DEVICE_ID_TAHOE932) ||
++	    (pdev->subsystem_device == PCI_DEVICE_ID_TAHOE972))
++		ports = 2;
++	else
++		ports = 1;
++	for(i = 0; i < ports; i++)
++		if (card->ports[i].card) {
++			struct net_device *dev = port_to_dev(&card->ports[i]);
++			unregister_hdlc_device(dev);
++		}
++
++	if (card->rambase)
++		iounmap(card->rambase);
++	if (card->scabase)
++		iounmap(card->scabase);
++	if (card->plxbase)
++		iounmap(card->plxbase);
++
++	pci_release_regions(pdev);
++	pci_disable_device(pdev);
++	pci_set_drvdata(pdev, NULL);
++	if (card->ports[0].dev)
++		free_netdev(card->ports[0].dev);
++	if ((ports == 2) && (card->ports[1].dev))
++		free_netdev(card->ports[1].dev);
++	kfree(card);
++}
++
++static void ds21554_update_licr(port_t *port)
++{
++	port->dsbase->licr = DEFAULT_LICR | (port->settings.egl << 4) | (port->g703_on == 0);
++}
++
++static void ds21554_update_registers(port_t *port)
++{
++	ds21554_t	*ds = port->dsbase;
++
++	if (port->settings.slot_map == 0xffffffff) {
++		/* Unframed */
++		ds->ccr1 = 0x08 | (port->g703_coding << 6) | (port->g703_coding << 2);
++		ds->tcr1 = 0x40;
++		ds->tcr2 = 0x00;
++		ds->ccr2 = 0x80; //84
++		ds->tir1 = 0; ds->tir2 = 0; ds->tir3 = 0; ds->tir4 = 0;
++		ds->tcc1 = 0; ds->tcc2 = 0; ds->tcc3 = 0; ds->tcc4 = 0;
++		ds->rcc1 = 0; ds->rcc2 = 0; ds->rcc3 = 0; ds->rcc4 = 0;
++		ds->rcbr1 = 0xff; ds->rcbr2 = 0xff; 
++		ds->rcbr3 = 0xff; ds->rcbr4 = 0xff; 
++		ds->tcbr1 = 0xff; ds->tcbr2 = 0xff; 
++		ds->tcbr3 = 0xff; ds->tcbr4 = 0xff; 
++		ds->tsacr = 0x00;
++		ds->tdc1 = 0x00;
++
++		ds->rcr2 = 0x04;
++		ds->ccr3 = 0x02;
++
++		ds->ccr6 = 0x03;	/* elastic buffers reset */
++		udelay(1000);
++		ds->ccr6 = 0x00;	/* elastic buffers reset */
++
++		ds->ccr5 = 0x60;	/* elastic buffers align */
++		udelay(1000);
++		ds->ccr5 = 0x00;
++	} else {
++		ds->ccr1 = 0x08 | (port->g703_coding << 6) | (port->g703_coding << 2)
++		                | (port->settings.crc4 << 4) | (port->settings.crc4);
++		ds->tcr1 = 0x00;
++		ds->ccr2 = 0x94;	/* Automatic alarm generation */
++
++		/* Receive channels */
++		ds->rcbr1 = port->settings.slot_map & 0xff;
++		ds->rcbr2 = (port->settings.slot_map >> 8) & 0xff;
++		ds->rcbr3 = (port->settings.slot_map >> 16) & 0xff;
++		ds->rcbr4 = (port->settings.slot_map >> 24) & 0xff;
++	
++		/* Transmit channels */
++		ds->tcbr1 = port->settings.slot_map & 0xff;
++		ds->tcbr2 = (port->settings.slot_map >> 8) & 0xff;
++		ds->tcbr3 = (port->settings.slot_map >> 16) & 0xff;
++		ds->tcbr4 = (port->settings.slot_map >> 24) & 0xff;
++
++		/* Transmit idle */
++		/* (remaining timeslots are filled with idle code) */
++		ds->tir1 = ~port->settings.slot_map & 0xfe;	/* Slot 0 is never idle */
++		ds->tir2 = (~port->settings.slot_map >> 8) & 0xff;
++		ds->tir3 = (~port->settings.slot_map >> 16) & 0xff;
++		ds->tir4 = (~port->settings.slot_map >> 24) & 0xff;
++		ds->rcr2 = 0x06;	/* RSYSCLK = 2048, rx elastic store enabled */
++		ds->ccr3 = 0x82;	/* TSYSCLK = 2048, tx elastic store enabled */
++
++		ds->ccr6 = 0x07;	/* elastic buffers reset */
++		udelay(1000);
++		ds->ccr6 = 0x04;	/* elastic buffers reset */
++
++		ds->ccr5 = 0x60;	/* elastic buffers align */
++		udelay(1000);
++		ds->ccr5 = 0x00;
++	}
++}
++
++void init_ds21554(port_t *port)
++{
++	ds21554_t	*ds = port->dsbase;
++	
++	ds->ccr2 = 0x04;
++	udelay(1000);
++	ds->ccr5 = 0x80;	/* Line Interface Reset */
++	udelay(1000);
++
++	ds->ccr5 = 0xe0;	/* Elastic Buffers Reset */
++	udelay(1000);
++	ds->ccr5 = 0x00;
++	ds->ccr6 = 0x04;	/* TCLK from RCLK */
++	ds->tcr2 = 0x00;
++	ds21554_update_licr(port);
++
++	/* Setup HDB3, CRC4, CAS/CCS, G.802 */
++	ds21554_update_registers(port);
++
++	ds->ccr2 = 0x94;	/* Automatic alarm generation */
++
++	ds->taf = 0x1b;
++	ds->tnaf = 0x40;
++
++	ds21554_update_registers(port);
++
++	ds->tidr = port->g703_idlecode;
++
++//	ds->ccr4 |= 0x40;
++}
++
++
++static int __devinit t9xx_pci_init_one(struct pci_dev *pdev,
++					 const struct pci_device_id *ent)
++{
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list