*/
-#include <linux/config.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
#undef USE_RBPL_POOL /* if memory is tight try this */
#define USE_TPD_POOL
/* #undef CONFIG_ATM_HE_USE_SUNI */
-
-/* compatibility */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
-typedef void irqreturn_t;
-#define IRQ_NONE
-#define IRQ_HANDLED
-#define IRQ_RETVAL(x)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
-#define __devexit_p(func) func
-#endif
-
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(x)
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
-#define pci_set_drvdata(pci_dev, data) (pci_dev)->driver_data = (data)
-#define pci_get_drvdata(pci_dev) (pci_dev)->driver_data
-#endif
+/* #undef HE_DEBUG */
#include "he.h"
-
#include "suni.h"
-
#include <linux/atm_he.h>
#define hprintk(fmt,args...) printk(KERN_ERR DEV_LABEL "%d: " fmt, he_dev->number , ##args)
-#undef DEBUG
-#ifdef DEBUG
+#ifdef HE_DEBUG
#define HPRINTK(fmt,args...) printk(KERN_DEBUG DEV_LABEL "%d: " fmt, he_dev->number , ##args)
-#else
+#else /* !HE_DEBUG */
#define HPRINTK(fmt,args...) do { } while (0)
-#endif /* DEBUG */
-
+#endif /* HE_DEBUG */
/* version definition */
static void he_close(struct atm_vcc *vcc);
static int he_send(struct atm_vcc *vcc, struct sk_buff *skb);
static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg);
-static irqreturn_t he_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t he_irq_handler(int irq, void *dev_id);
static void he_tasklet(unsigned long data);
static int he_proc_read(struct atm_dev *dev,loff_t *pos,char *page);
static int he_start(struct atm_dev *dev);
/* globals */
-struct he_dev *he_devs = NULL;
-static short disable64 = -1;
+static struct he_dev *he_devs;
+static int disable64;
static short nvpibits = -1;
static short nvcibits = -1;
static short rx_skb_reserve = 16;
-static short irq_coalesce = 1;
-static short sdh = 0;
+static int irq_coalesce = 1;
+static int sdh = 0;
+
+/* Read from EEPROM = 0000 0011b */
+static unsigned int readtab[] = {
+ CS_HIGH | CLK_HIGH,
+ CS_LOW | CLK_LOW,
+ CLK_HIGH, /* 0 */
+ CLK_LOW,
+ CLK_HIGH, /* 0 */
+ CLK_LOW,
+ CLK_HIGH, /* 0 */
+ CLK_LOW,
+ CLK_HIGH, /* 0 */
+ CLK_LOW,
+ CLK_HIGH, /* 0 */
+ CLK_LOW,
+ CLK_HIGH, /* 0 */
+ CLK_LOW | SI_HIGH,
+ CLK_HIGH | SI_HIGH, /* 1 */
+ CLK_LOW | SI_HIGH,
+ CLK_HIGH | SI_HIGH /* 1 */
+};
+
+/* Clock to read from/write to the EEPROM */
+static unsigned int clocktab[] = {
+ CLK_LOW,
+ CLK_HIGH,
+ CLK_LOW,
+ CLK_HIGH,
+ CLK_LOW,
+ CLK_HIGH,
+ CLK_LOW,
+ CLK_HIGH,
+ CLK_LOW,
+ CLK_HIGH,
+ CLK_LOW,
+ CLK_HIGH,
+ CLK_LOW,
+ CLK_HIGH,
+ CLK_LOW,
+ CLK_HIGH,
+ CLK_LOW
+};
static struct atmdev_ops he_ops =
{
if (pci_enable_device(pci_dev))
return -EIO;
- if (pci_set_dma_mask(pci_dev, HE_DMA_MASK) != 0) {
+ if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK) != 0) {
printk(KERN_WARNING "he: no suitable dma available\n");
err = -EIO;
goto init_one_failure;
}
- atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, 0);
+ atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, NULL);
if (!atm_dev) {
err = -ENODEV;
goto init_one_failure;
}
pci_set_drvdata(pci_dev, atm_dev);
- he_dev = (struct he_dev *) kmalloc(sizeof(struct he_dev),
+ he_dev = kzalloc(sizeof(struct he_dev),
GFP_KERNEL);
if (!he_dev) {
err = -ENOMEM;
goto init_one_failure;
}
- memset(he_dev, 0, sizeof(struct he_dev));
-
he_dev->pci_dev = pci_dev;
he_dev->atm_dev = atm_dev;
he_dev->atm_dev->dev_data = he_dev;
init_one_failure:
if (atm_dev)
atm_dev_deregister(atm_dev);
- if (he_dev)
- kfree(he_dev);
+ kfree(he_dev);
pci_disable_device(pci_dev);
return err;
}
return (NONZERO | (exp << 9) | (rate & 0x1ff));
}
-static void __init
+static void __devinit
he_init_rx_lbfp0(struct he_dev *he_dev)
{
unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
he_writel(he_dev, he_dev->r0_numbuffs, RLBF0_C);
}
-static void __init
+static void __devinit
he_init_rx_lbfp1(struct he_dev *he_dev)
{
unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
he_writel(he_dev, he_dev->r1_numbuffs, RLBF1_C);
}
-static void __init
+static void __devinit
he_init_tx_lbfp(struct he_dev *he_dev)
{
unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
he_writel(he_dev, lbufd_index - 1, TLBF_T);
}
-static int __init
+static int __devinit
he_init_tpdrq(struct he_dev *he_dev)
{
he_dev->tpdrq_base = pci_alloc_consistent(he_dev->pci_dev,
return 0;
}
-static void __init
+static void __devinit
he_init_cs_block(struct he_dev *he_dev)
{
unsigned clock, rate, delta;
}
-static int __init
+static int __devinit
he_init_cs_block_rcm(struct he_dev *he_dev)
{
unsigned (*rategrid)[16][16];
return 0;
}
-static int __init
+static int __devinit
he_init_group(struct he_dev *he_dev, int group)
{
int i;
void *cpuaddr;
#ifdef USE_RBPS_POOL
- cpuaddr = pci_pool_alloc(he_dev->rbps_pool, SLAB_KERNEL|SLAB_DMA, &dma_handle);
+ cpuaddr = pci_pool_alloc(he_dev->rbps_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
if (cpuaddr == NULL)
return -ENOMEM;
#else
void *cpuaddr;
#ifdef USE_RBPL_POOL
- cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, SLAB_KERNEL|SLAB_DMA, &dma_handle);
+ cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
if (cpuaddr == NULL)
return -ENOMEM;
#else
return 0;
}
-static int __init
+static int __devinit
he_init_irq(struct he_dev *he_dev)
{
int i;
he_writel(he_dev, 0x0, GRP_54_MAP);
he_writel(he_dev, 0x0, GRP_76_MAP);
- if (request_irq(he_dev->pci_dev->irq, he_irq_handler, SA_INTERRUPT|SA_SHIRQ, DEV_LABEL, he_dev)) {
+ if (request_irq(he_dev->pci_dev->irq, he_irq_handler, IRQF_DISABLED|IRQF_SHARED, DEV_LABEL, he_dev)) {
hprintk("irq %d already in use\n", he_dev->pci_dev->irq);
return -EINVAL;
}
return 0;
}
-static int __init
+static int __devinit
he_start(struct atm_dev *dev)
{
struct he_dev *he_dev;
struct pci_dev *pci_dev;
+ unsigned long membase;
u16 command;
u32 gen_cntl_0, host_cntl, lb_swap;
he_dev = HE_DEV(dev);
pci_dev = he_dev->pci_dev;
- he_dev->membase = pci_dev->resource[0].start;
- HPRINTK("membase = 0x%lx irq = %d.\n", he_dev->membase, pci_dev->irq);
+ membase = pci_resource_start(pci_dev, 0);
+ HPRINTK("membase = 0x%lx irq = %d.\n", membase, pci_dev->irq);
/*
* pci bus controller initialization
hprintk("can't set latency timer to %d\n", timer);
}
- if (!(he_dev->membase = (unsigned long) ioremap(he_dev->membase, HE_REGMAP_SIZE))) {
+ if (!(he_dev->membase = ioremap(membase, HE_REGMAP_SIZE))) {
hprintk("can't set up page mapping\n");
return -EINVAL;
}
}
if (he_dev->membase)
- iounmap((void *) he_dev->membase);
+ iounmap(he_dev->membase);
}
static struct he_tpd *
struct he_tpd *tpd;
dma_addr_t dma_handle;
- tpd = pci_pool_alloc(he_dev->tpd_pool, SLAB_ATOMIC|SLAB_DMA, &dma_handle);
+ tpd = pci_pool_alloc(he_dev->tpd_pool, GFP_ATOMIC|GFP_DMA, &dma_handle);
if (tpd == NULL)
return NULL;
if (rx_skb_reserve > 0)
skb_reserve(skb, rx_skb_reserve);
- do_gettimeofday(&skb->stamp);
+ __net_timestamp(skb);
for (iov = he_vcc->iov_head;
iov < he_vcc->iov_tail; ++iov) {
skb->tail = skb->data + skb->len;
#ifdef USE_CHECKSUM_HW
if (vcc->vpi == 0 && vcc->vci >= ATM_NOT_RSV_VCI) {
- skb->ip_summed = CHECKSUM_HW;
+ skb->ip_summed = CHECKSUM_COMPLETE;
skb->csum = TCP_CKSUM(skb->data,
he_vcc->pdu_len);
}
#ifdef notdef
ATM_SKB(skb)->vcc = vcc;
#endif
+ spin_unlock(&he_dev->global_lock);
vcc->push(vcc, skb);
+ spin_lock(&he_dev->global_lock);
atomic_inc(&vcc->stats->rx);
struct he_tpd *tpd;
int slot, updated = 0;
#ifdef USE_TPD_POOL
- struct list_head *p;
+ struct he_tpd *__tpd;
#endif
/* 2.1.6 transmit buffer return queue */
TBRQ_MULTIPLE(he_dev->tbrq_head) ? " MULTIPLE" : "");
#ifdef USE_TPD_POOL
tpd = NULL;
- list_for_each(p, &he_dev->outstanding_tpds) {
- struct he_tpd *__tpd = list_entry(p, struct he_tpd, entry);
+ list_for_each_entry(__tpd, &he_dev->outstanding_tpds, entry) {
if (TPD_ADDR(__tpd->status) == TBRQ_TPD(he_dev->tbrq_head)) {
tpd = __tpd;
list_del(&__tpd->entry);
}
static irqreturn_t
-he_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+he_irq_handler(int irq, void *dev_id)
{
unsigned long flags;
struct he_dev *he_dev = (struct he_dev * )dev_id;
TPDRQ_MASK(he_readl(he_dev, TPDRQ_B_H)));
if (new_tail == he_dev->tpdrq_head) {
+ int slot;
+
hprintk("tpdrq full (cid 0x%x)\n", cid);
/*
* FIXME
* after service_tbrq, service the backlog
* for now, we just drop the pdu
*/
+ for (slot = 0; slot < TPD_MAXIOV; ++slot) {
+ if (tpd->iovec[slot].addr)
+ pci_unmap_single(he_dev->pci_dev,
+ tpd->iovec[slot].addr,
+ tpd->iovec[slot].len & TPD_LEN_MASK,
+ PCI_DMA_TODEVICE);
+ }
if (tpd->skb) {
if (tpd->vcc->pop)
tpd->vcc->pop(tpd->vcc, tpd->skb);
cid = he_mkcid(he_dev, vpi, vci);
- he_vcc = (struct he_vcc *) kmalloc(sizeof(struct he_vcc), GFP_ATOMIC);
+ he_vcc = kmalloc(sizeof(struct he_vcc), GFP_ATOMIC);
if (he_vcc == NULL) {
hprintk("unable to allocate he_vcc during open\n");
return -ENOMEM;
open_failed:
if (err) {
- if (he_vcc)
- kfree(he_vcc);
+ kfree(he_vcc);
clear_bit(ATM_VF_ADDR, &vcc->flags);
}
else
udelay(250);
}
- add_wait_queue(&he_vcc->rx_waitq, &wait);
set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(&he_vcc->rx_waitq, &wait);
he_writel_rsr0(he_dev, RSR0_CLOSE_CONN, cid);
(void) he_readl_rsr0(he_dev, cid); /* flush posted writes */
* TBRQ, the host issues the close command to the adapter.
*/
- while (((tx_inuse = atomic_read(&vcc->sk->sk_wmem_alloc)) > 0) &&
+ while (((tx_inuse = atomic_read(&sk_atm(vcc)->sk_wmem_alloc)) > 0) &&
(retry < MAX_RETRY)) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- (void) schedule_timeout(sleep);
- if (sleep < HZ)
+ msleep(sleep);
+ if (sleep < 250)
sleep = sleep * 2;
++retry;
tpd->vcc = vcc;
wmb();
- add_wait_queue(&he_vcc->tx_waitq, &wait);
set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(&he_vcc->tx_waitq, &wait);
__enqueue_tpd(he_dev, tpd, cid);
spin_unlock_irqrestore(&he_dev->global_lock, flags);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
MODULE_DESCRIPTION("ForeRunnerHE ATM Adapter driver");
-MODULE_PARM(disable64, "h");
+module_param(disable64, bool, 0);
MODULE_PARM_DESC(disable64, "disable 64-bit pci bus transfers");
-MODULE_PARM(nvpibits, "i");
+module_param(nvpibits, short, 0);
MODULE_PARM_DESC(nvpibits, "numbers of bits for vpi (default 0)");
-MODULE_PARM(nvcibits, "i");
+module_param(nvcibits, short, 0);
MODULE_PARM_DESC(nvcibits, "numbers of bits for vci (default 12)");
-MODULE_PARM(rx_skb_reserve, "i");
+module_param(rx_skb_reserve, short, 0);
MODULE_PARM_DESC(rx_skb_reserve, "padding for receive skb (default 16)");
-MODULE_PARM(irq_coalesce, "i");
+module_param(irq_coalesce, bool, 0);
MODULE_PARM_DESC(irq_coalesce, "use interrupt coalescing (default 1)");
-MODULE_PARM(sdh, "i");
+module_param(sdh, bool, 0);
MODULE_PARM_DESC(sdh, "use SDH framing (default 0)");
static struct pci_device_id he_pci_tbl[] = {
{ 0, }
};
+MODULE_DEVICE_TABLE(pci, he_pci_tbl);
+
static struct pci_driver he_driver = {
.name = "he",
.probe = he_init_one,
static int __init he_init(void)
{
- return pci_module_init(&he_driver);
+ return pci_register_driver(&he_driver);
}
static void __exit he_cleanup(void)