#include <linux/atmdev.h>
#include <linux/atm.h>
#include <linux/pci.h>
+#include <linux/dma-mapping.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/slab.h>
+#include <linux/idr.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include "idt77105.h"
#endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */
-#if BITS_PER_LONG != 32
-# error FIXME: this driver requires a 32-bit platform
-#endif
-
/* Additional code */
#include "nicstarmac.c"
#define NS_DELAY mdelay(1)
-#define ALIGN_BUS_ADDR(addr, alignment) \
- ((((u32) (addr)) + (((u32) (alignment)) - 1)) & ~(((u32) (alignment)) - 1))
-#define ALIGN_ADDRESS(addr, alignment) \
- bus_to_virt(ALIGN_BUS_ADDR(virt_to_bus(addr), alignment))
-
-#undef CEIL
+#define PTR_DIFF(a, b) ((u32)((unsigned long)(a) - (unsigned long)(b)))
#ifndef ATM_SKB
#define ATM_SKB(s) (&(s)->atm)
#endif
+#define scq_virt_to_bus(scq, p) \
+ (scq->dma + ((unsigned long)(p) - (unsigned long)(scq)->org))
+
/* Function declarations */
static u32 ns_read_sram(ns_dev * card, u32 sram_address);
int count);
static int __devinit ns_init_card(int i, struct pci_dev *pcidev);
static void __devinit ns_init_card_error(ns_dev * card, int error);
-static scq_info *get_scq(int size, u32 scd);
-static void free_scq(scq_info * scq, struct atm_vcc *vcc);
+static scq_info *get_scq(ns_dev *card, int size, u32 scd);
+static void free_scq(ns_dev *card, scq_info * scq, struct atm_vcc *vcc);
static void push_rxbufs(ns_dev *, struct sk_buff *);
static irqreturn_t ns_irq_handler(int irq, void *dev_id);
static int ns_open(struct atm_vcc *vcc);
static void dequeue_lg_buf(ns_dev * card, struct sk_buff *lb);
static int ns_proc_read(struct atm_dev *dev, loff_t * pos, char *page);
static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg);
+#ifdef EXTRA_DEBUG
static void which_list(ns_dev * card, struct sk_buff *skb);
+#endif
static void ns_poll(unsigned long arg);
static int ns_parse_mac(char *mac, unsigned char *esi);
static short ns_h2i(char c);
dev_kfree_skb_any(lb);
while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL)
dev_kfree_skb_any(sb);
- free_scq(card->scq0, NULL);
+ free_scq(card, card->scq0, NULL);
for (j = 0; j < NS_FRSCD_NUM; j++) {
if (card->scd2vc[j] != NULL)
- free_scq(card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc);
- }
- kfree(card->rsq.org);
- kfree(card->tsq.org);
+ free_scq(card, card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc);
+ }
+ idr_remove_all(&card->idr);
+ idr_destroy(&card->idr);
+ pci_free_consistent(card->pcidev, NS_RSQSIZE + NS_RSQ_ALIGNMENT,
+ card->rsq.org, card->rsq.dma);
+ pci_free_consistent(card->pcidev, NS_TSQSIZE + NS_TSQ_ALIGNMENT,
+ card->tsq.org, card->tsq.dma);
free_irq(card->pcidev->irq, card);
iounmap(card->membase);
kfree(card);
ns_init_card_error(card, error);
return error;
}
+ if ((pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)) != 0) ||
+ (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32)) != 0)) {
+ printk(KERN_WARNING
+ "nicstar%d: No suitable DMA available.\n", i);
+ error = 2;
+ ns_init_card_error(card, error);
+ return error;
+ }
if ((card = kmalloc(sizeof(ns_dev), GFP_KERNEL)) == NULL) {
printk
ns_init_card_error(card, error);
return error;
}
- PRINTK("nicstar%d: membase at 0x%x.\n", i, card->membase);
+ PRINTK("nicstar%d: membase at 0x%p.\n", i, card->membase);
pci_set_master(pcidev);
writel(0x00000000, card->membase + VPM);
/* Initialize TSQ */
- card->tsq.org = kmalloc(NS_TSQSIZE + NS_TSQ_ALIGNMENT, GFP_KERNEL);
+ card->tsq.org = pci_alloc_consistent(card->pcidev,
+ NS_TSQSIZE + NS_TSQ_ALIGNMENT,
+ &card->tsq.dma);
if (card->tsq.org == NULL) {
printk("nicstar%d: can't allocate TSQ.\n", i);
error = 10;
ns_init_card_error(card, error);
return error;
}
- card->tsq.base =
- (ns_tsi *) ALIGN_ADDRESS(card->tsq.org, NS_TSQ_ALIGNMENT);
+ card->tsq.base = PTR_ALIGN(card->tsq.org, NS_TSQ_ALIGNMENT);
card->tsq.next = card->tsq.base;
card->tsq.last = card->tsq.base + (NS_TSQ_NUM_ENTRIES - 1);
for (j = 0; j < NS_TSQ_NUM_ENTRIES; j++)
ns_tsi_init(card->tsq.base + j);
writel(0x00000000, card->membase + TSQH);
- writel((u32) virt_to_bus(card->tsq.base), card->membase + TSQB);
- PRINTK("nicstar%d: TSQ base at 0x%x 0x%x 0x%x.\n", i,
- (u32) card->tsq.base, (u32) virt_to_bus(card->tsq.base),
- readl(card->membase + TSQB));
+ writel(ALIGN(card->tsq.dma, NS_TSQ_ALIGNMENT), card->membase + TSQB);
+ PRINTK("nicstar%d: TSQ base at 0x%p.\n", i, card->tsq.base);
/* Initialize RSQ */
- card->rsq.org = kmalloc(NS_RSQSIZE + NS_RSQ_ALIGNMENT, GFP_KERNEL);
+ card->rsq.org = pci_alloc_consistent(card->pcidev,
+ NS_RSQSIZE + NS_RSQ_ALIGNMENT,
+ &card->rsq.dma);
if (card->rsq.org == NULL) {
printk("nicstar%d: can't allocate RSQ.\n", i);
error = 11;
ns_init_card_error(card, error);
return error;
}
- card->rsq.base =
- (ns_rsqe *) ALIGN_ADDRESS(card->rsq.org, NS_RSQ_ALIGNMENT);
+ card->rsq.base = PTR_ALIGN(card->rsq.org, NS_RSQ_ALIGNMENT);
card->rsq.next = card->rsq.base;
card->rsq.last = card->rsq.base + (NS_RSQ_NUM_ENTRIES - 1);
for (j = 0; j < NS_RSQ_NUM_ENTRIES; j++)
ns_rsqe_init(card->rsq.base + j);
writel(0x00000000, card->membase + RSQH);
- writel((u32) virt_to_bus(card->rsq.base), card->membase + RSQB);
- PRINTK("nicstar%d: RSQ base at 0x%x.\n", i, (u32) card->rsq.base);
+ writel(ALIGN(card->rsq.dma, NS_RSQ_ALIGNMENT), card->membase + RSQB);
+ PRINTK("nicstar%d: RSQ base at 0x%p.\n", i, card->rsq.base);
/* Initialize SCQ0, the only VBR SCQ used */
card->scq1 = NULL;
card->scq2 = NULL;
- card->scq0 = get_scq(VBR_SCQSIZE, NS_VRSCD0);
+ card->scq0 = get_scq(card, VBR_SCQSIZE, NS_VRSCD0);
if (card->scq0 == NULL) {
printk("nicstar%d: can't get SCQ0.\n", i);
error = 12;
ns_init_card_error(card, error);
return error;
}
- u32d[0] = (u32) virt_to_bus(card->scq0->base);
+ u32d[0] = scq_virt_to_bus(card->scq0, card->scq0->base);
u32d[1] = (u32) 0x00000000;
u32d[2] = (u32) 0xffffffff;
u32d[3] = (u32) 0x00000000;
ns_write_sram(card, NS_VRSCD1, u32d, 4); /* These last two won't be used */
ns_write_sram(card, NS_VRSCD2, u32d, 4); /* but are initialized, just in case... */
card->scq0->scd = NS_VRSCD0;
- PRINTK("nicstar%d: VBR-SCQ0 base at 0x%x.\n", i,
- (u32) card->scq0->base);
+ PRINTK("nicstar%d: VBR-SCQ0 base at 0x%p.\n", i, card->scq0->base);
/* Initialize TSTs */
card->tst_addr = NS_TST0;
card->efbie = 1; /* To prevent push_rxbufs from enabling the interrupt */
+ idr_init(&card->idr);
+
/* Pre-allocate some huge buffers */
skb_queue_head_init(&card->hbpool.queue);
card->hbpool.count = 0;
ns_init_card_error(card, error);
return error;
}
- NS_SKB_CB(hb)->buf_type = BUF_NONE;
+ NS_PRV_BUFTYPE(hb) = BUF_NONE;
skb_queue_tail(&card->hbpool.queue, hb);
card->hbpool.count++;
}
ns_init_card_error(card, error);
return error;
}
- NS_SKB_CB(lb)->buf_type = BUF_LG;
+ NS_PRV_BUFTYPE(lb) = BUF_LG;
skb_queue_tail(&card->lbpool.queue, lb);
skb_reserve(lb, NS_SMBUFSIZE);
push_rxbufs(card, lb);
/* Due to the implementation of push_rxbufs() this is 1, not 0 */
if (j == 1) {
card->rcbuf = lb;
- card->rawch = (u32) virt_to_bus(lb->data);
+ card->rawcell = (struct ns_rcqe *) lb->data;
+ card->rawch = NS_PRV_DMA(lb);
}
}
/* Test for strange behaviour which leads to crashes */
ns_init_card_error(card, error);
return error;
}
- NS_SKB_CB(sb)->buf_type = BUF_SM;
+ NS_PRV_BUFTYPE(sb) = BUF_SM;
skb_queue_tail(&card->sbpool.queue, sb);
skb_reserve(sb, NS_AAL0_HEADER);
push_rxbufs(card, sb);
ns_init_card_error(card, error);
return error;
}
- NS_SKB_CB(iovb)->buf_type = BUF_NONE;
+ NS_PRV_BUFTYPE(iovb) = BUF_NONE;
skb_queue_tail(&card->iovpool.queue, iovb);
card->iovpool.count++;
}
struct sk_buff *sb;
while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL)
dev_kfree_skb_any(sb);
- free_scq(card->scq0, NULL);
+ free_scq(card, card->scq0, NULL);
}
if (error >= 14) {
struct sk_buff *lb;
}
}
-static scq_info *get_scq(int size, u32 scd)
+static scq_info *get_scq(ns_dev *card, int size, u32 scd)
{
scq_info *scq;
int i;
return NULL;
scq = kmalloc(sizeof(scq_info), GFP_KERNEL);
- if (scq == NULL)
+ if (!scq)
return NULL;
- scq->org = kmalloc(2 * size, GFP_KERNEL);
- if (scq->org == NULL) {
+ scq->org = pci_alloc_consistent(card->pcidev, 2 * size, &scq->dma);
+ if (!scq->org) {
kfree(scq);
return NULL;
}
scq->skb = kmalloc(sizeof(struct sk_buff *) *
(size / NS_SCQE_SIZE), GFP_KERNEL);
- if (scq->skb == NULL) {
+ if (!scq->skb) {
kfree(scq->org);
kfree(scq);
return NULL;
}
scq->num_entries = size / NS_SCQE_SIZE;
- scq->base = (ns_scqe *) ALIGN_ADDRESS(scq->org, size);
+ scq->base = PTR_ALIGN(scq->org, size);
scq->next = scq->base;
scq->last = scq->base + (scq->num_entries - 1);
scq->tail = scq->last;
}
/* For variable rate SCQ vcc must be NULL */
-static void free_scq(scq_info * scq, struct atm_vcc *vcc)
+static void free_scq(ns_dev *card, scq_info *scq, struct atm_vcc *vcc)
{
int i;
}
}
kfree(scq->skb);
- kfree(scq->org);
+ pci_free_consistent(card->pcidev,
+ 2 * (scq->num_entries == VBR_SCQ_NUM_ENTRIES ?
+ VBR_SCQSIZE : CBR_SCQSIZE),
+ scq->org, scq->dma);
kfree(scq);
}
or large buffer(s) cast to u32. */
static void push_rxbufs(ns_dev * card, struct sk_buff *skb)
{
- struct ns_skb_cb *cb = NS_SKB_CB(skb);
- u32 handle1, addr1;
- u32 handle2, addr2;
+ struct sk_buff *handle1, *handle2;
+ u32 id1 = 0, id2 = 0;
+ u32 addr1, addr2;
u32 stat;
unsigned long flags;
+ int err;
/* *BARF* */
- handle2 = addr2 = 0;
- handle1 = (u32) skb;
- addr1 = (u32) virt_to_bus(skb->data);
+ handle2 = NULL;
+ addr2 = 0;
+ handle1 = skb;
+ addr1 = pci_map_single(card->pcidev,
+ skb->data,
+ (NS_PRV_BUFTYPE(skb) == BUF_SM
+ ? NS_SMSKBSIZE : NS_LGSKBSIZE),
+ PCI_DMA_TODEVICE);
+ NS_PRV_DMA(skb) = addr1; /* save so we can unmap later */
#ifdef GENERAL_DEBUG
if (!addr1)
stat = readl(card->membase + STAT);
card->sbfqc = ns_stat_sfbqc_get(stat);
card->lbfqc = ns_stat_lfbqc_get(stat);
- if (cb->buf_type == BUF_SM) {
+ if (NS_PRV_BUFTYPE(skb) == BUF_SM) {
if (!addr2) {
if (card->sm_addr) {
addr2 = card->sm_addr;
}
if (addr2) {
- if (cb->buf_type == BUF_SM) {
+ if (NS_PRV_BUFTYPE(skb) == BUF_SM) {
if (card->sbfqc >= card->sbnr.max) {
- skb_unlink((struct sk_buff *)handle1,
- &card->sbpool.queue);
- dev_kfree_skb_any((struct sk_buff *)handle1);
- skb_unlink((struct sk_buff *)handle2,
- &card->sbpool.queue);
- dev_kfree_skb_any((struct sk_buff *)handle2);
+ skb_unlink(handle1, &card->sbpool.queue);
+ dev_kfree_skb_any(handle1);
+ skb_unlink(handle2, &card->sbpool.queue);
+ dev_kfree_skb_any(handle2);
return;
} else
card->sbfqc += 2;
} else { /* (buf_type == BUF_LG) */
if (card->lbfqc >= card->lbnr.max) {
- skb_unlink((struct sk_buff *)handle1,
- &card->lbpool.queue);
- dev_kfree_skb_any((struct sk_buff *)handle1);
- skb_unlink((struct sk_buff *)handle2,
- &card->lbpool.queue);
- dev_kfree_skb_any((struct sk_buff *)handle2);
+ skb_unlink(handle1, &card->lbpool.queue);
+ dev_kfree_skb_any(handle1);
+ skb_unlink(handle2, &card->lbpool.queue);
+ dev_kfree_skb_any(handle2);
return;
} else
card->lbfqc += 2;
}
- spin_lock_irqsave(&card->res_lock, flags);
+ do {
+ if (!idr_pre_get(&card->idr, GFP_ATOMIC)) {
+ printk(KERN_ERR
+ "nicstar%d: no free memory for idr\n",
+ card->index);
+ goto out;
+ }
+
+ if (!id1)
+ err = idr_get_new_above(&card->idr, handle1, 0, &id1);
+
+ if (!id2 && err == 0)
+ err = idr_get_new_above(&card->idr, handle2, 0, &id2);
+
+ } while (err == -EAGAIN);
+ if (err)
+ goto out;
+
+ spin_lock_irqsave(&card->res_lock, flags);
while (CMD_BUSY(card)) ;
writel(addr2, card->membase + DR3);
- writel(handle2, card->membase + DR2);
+ writel(id2, card->membase + DR2);
writel(addr1, card->membase + DR1);
- writel(handle1, card->membase + DR0);
- writel(NS_CMD_WRITE_FREEBUFQ | cb->buf_type,
+ writel(id1, card->membase + DR0);
+ writel(NS_CMD_WRITE_FREEBUFQ | NS_PRV_BUFTYPE(skb),
card->membase + CMD);
-
spin_unlock_irqrestore(&card->res_lock, flags);
XPRINTK("nicstar%d: Pushing %s buffers at 0x%x and 0x%x.\n",
card->index,
- (cb->buf_type == BUF_SM ? "small" : "large"), addr1,
- addr2);
+ (NS_PRV_BUFTYPE(skb) == BUF_SM ? "small" : "large"),
+ addr1, addr2);
}
if (!card->efbie && card->sbfqc >= card->sbnr.min &&
card->membase + CFG);
}
+out:
return;
}
next interrupt. As this preliminary support is only meant to
avoid buffer leakage, this is not an issue. */
while (readl(card->membase + RAWCT) != card->rawch) {
- ns_rcqe *rawcell;
- rawcell = (ns_rcqe *) bus_to_virt(card->rawch);
- if (ns_rcqe_islast(rawcell)) {
+ if (ns_rcqe_islast(card->rawcell)) {
struct sk_buff *oldbuf;
oldbuf = card->rcbuf;
- card->rcbuf =
- (struct sk_buff *)
- ns_rcqe_nextbufhandle(rawcell);
- card->rawch =
- (u32) virt_to_bus(card->rcbuf->data);
+ card->rcbuf = idr_find(&card->idr,
+ ns_rcqe_nextbufhandle(card->rawcell));
+ card->rawch = NS_PRV_DMA(card->rcbuf);
+ card->rawcell = (struct ns_rcqe *)
+ card->rcbuf->data;
recycle_rx_buf(card, oldbuf);
- } else
+ } else {
card->rawch += NS_RCQE_SIZE;
+ card->rawcell++;
+ }
}
}
card->efbie = 0;
break;
}
- NS_SKB_CB(sb)->buf_type = BUF_SM;
+ NS_PRV_BUFTYPE(sb) = BUF_SM;
skb_queue_tail(&card->sbpool.queue, sb);
skb_reserve(sb, NS_AAL0_HEADER);
push_rxbufs(card, sb);
card->efbie = 0;
break;
}
- NS_SKB_CB(lb)->buf_type = BUF_LG;
+ NS_PRV_BUFTYPE(lb) = BUF_LG;
skb_queue_tail(&card->lbpool.queue, lb);
skb_reserve(lb, NS_SMBUFSIZE);
push_rxbufs(card, lb);
vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE;
- scq = get_scq(CBR_SCQSIZE, vc->cbr_scd);
+ scq = get_scq(card, CBR_SCQSIZE, vc->cbr_scd);
if (scq == NULL) {
PRINTK("nicstar%d: can't get fixed rate SCQ.\n",
card->index);
return -ENOMEM;
}
vc->scq = scq;
- u32d[0] = (u32) virt_to_bus(scq->base);
+ u32d[0] = scq_virt_to_bus(scq, scq->base);
u32d[1] = (u32) 0x00000000;
u32d[2] = (u32) 0xffffffff;
u32d[3] = (u32) 0x00000000;
card->index);
iovb = vc->rx_iov;
recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
- NS_SKB(iovb)->iovcnt);
- NS_SKB(iovb)->iovcnt = 0;
- NS_SKB(iovb)->vcc = NULL;
+ NS_PRV_IOVCNT(iovb));
+ NS_PRV_IOVCNT(iovb) = 0;
spin_lock_irqsave(&card->int_lock, flags);
recycle_iov_buf(card, iovb);
spin_unlock_irqrestore(&card->int_lock, flags);
scq->next = scq->base;
else
scq->next++;
- data = (u32) virt_to_bus(scq->next);
+ data = scq_virt_to_bus(scq, scq->next);
ns_write_sram(card, scq->scd, &data, 1);
}
spin_unlock_irqrestore(&scq->lock, flags);
}
card->scd2vc[(vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE] = NULL;
- free_scq(vc->scq, vcc);
+ free_scq(card, vc->scq, vcc);
}
/* remove all references to vcc before deleting it */
cfg = readl(card->membase + CFG);
printk("STAT = 0x%08X CFG = 0x%08X \n", stat, cfg);
printk
- ("TSQ: base = 0x%08X next = 0x%08X last = 0x%08X TSQT = 0x%08X \n",
- (u32) card->tsq.base, (u32) card->tsq.next,
- (u32) card->tsq.last, readl(card->membase + TSQT));
+ ("TSQ: base = 0x%p next = 0x%p last = 0x%p TSQT = 0x%08X \n",
+ card->tsq.base, card->tsq.next,
+ card->tsq.last, readl(card->membase + TSQT));
printk
- ("RSQ: base = 0x%08X next = 0x%08X last = 0x%08X RSQT = 0x%08X \n",
- (u32) card->rsq.base, (u32) card->rsq.next,
- (u32) card->rsq.last, readl(card->membase + RSQT));
+ ("RSQ: base = 0x%p next = 0x%p last = 0x%p RSQT = 0x%08X \n",
+ card->rsq.base, card->rsq.next,
+ card->rsq.last, readl(card->membase + RSQT));
printk("Empty free buffer queue interrupt %s \n",
card->efbie ? "enabled" : "disabled");
printk("SBCNT = %d count = %d LBCNT = %d count = %d \n",
ATM_SKB(skb)->vcc = vcc;
+ NS_PRV_DMA(skb) = pci_map_single(card->pcidev, skb->data,
+ skb->len, PCI_DMA_TODEVICE);
+
if (vcc->qos.aal == ATM_AAL5) {
buflen = (skb->len + 47 + 8) / 48 * 48; /* Multiple of 48 */
flags = NS_TBD_AAL5;
- scqe.word_2 = cpu_to_le32((u32) virt_to_bus(skb->data));
- scqe.word_3 = cpu_to_le32((u32) skb->len);
+ scqe.word_2 = cpu_to_le32(NS_PRV_DMA(skb));
+ scqe.word_3 = cpu_to_le32(skb->len);
scqe.word_4 =
ns_tbd_mkword_4(0, (u32) vcc->vpi, (u32) vcc->vci, 0,
ATM_SKB(skb)->
buflen = ATM_CELL_PAYLOAD; /* i.e., 48 bytes */
flags = NS_TBD_AAL0;
- scqe.word_2 =
- cpu_to_le32((u32) virt_to_bus(skb->data) + NS_AAL0_HEADER);
+ scqe.word_2 = cpu_to_le32(NS_PRV_DMA(skb) + NS_AAL0_HEADER);
scqe.word_3 = cpu_to_le32(0x00000000);
if (*skb->data & 0x02) /* Payload type 1 - end of pdu */
flags |= NS_TBD_EOPDU;
*scq->next = *tbd;
index = (int)(scq->next - scq->base);
scq->skb[index] = skb;
- XPRINTK("nicstar%d: sending skb at 0x%x (pos %d).\n",
- card->index, (u32) skb, index);
- XPRINTK("nicstar%d: TBD written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%x.\n",
+ XPRINTK("nicstar%d: sending skb at 0x%p (pos %d).\n",
+ card->index, skb, index);
+ XPRINTK("nicstar%d: TBD written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%p.\n",
card->index, le32_to_cpu(tbd->word_1), le32_to_cpu(tbd->word_2),
le32_to_cpu(tbd->word_3), le32_to_cpu(tbd->word_4),
- (u32) scq->next);
+ scq->next);
if (scq->next == scq->last)
scq->next = scq->base;
else
while (scq->tail == scq->next) {
if (in_interrupt()) {
- data = (u32) virt_to_bus(scq->next);
+ data = scq_virt_to_bus(scq, scq->next);
ns_write_sram(card, scq->scd, &data, 1);
spin_unlock_irqrestore(&scq->lock, flags);
printk("nicstar%d: Error pushing TSR.\n",
index = (int)scqi;
scq->skb[index] = NULL;
XPRINTK
- ("nicstar%d: TSR written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%x.\n",
+ ("nicstar%d: TSR written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%p.\n",
card->index, le32_to_cpu(tsr.word_1),
le32_to_cpu(tsr.word_2), le32_to_cpu(tsr.word_3),
- le32_to_cpu(tsr.word_4), (u32) scq->next);
+ le32_to_cpu(tsr.word_4), scq->next);
if (scq->next == scq->last)
scq->next = scq->base;
else
PRINTK("nicstar%d: Timeout pushing TSR.\n",
card->index);
}
- data = (u32) virt_to_bus(scq->next);
+ data = scq_virt_to_bus(scq, scq->next);
ns_write_sram(card, scq->scd, &data, 1);
spin_unlock_irqrestore(&scq->lock, flags);
two_ahead = one_ahead + 1;
}
- if (serviced_entries) {
- writel((((u32) previous) - ((u32) card->tsq.base)),
+ if (serviced_entries)
+ writel(PTR_DIFF(previous, card->tsq.base),
card->membase + TSQH);
- }
}
static void drain_scq(ns_dev * card, scq_info * scq, int pos)
int i;
unsigned long flags;
- XPRINTK("nicstar%d: drain_scq() called, scq at 0x%x, pos %d.\n",
- card->index, (u32) scq, pos);
+ XPRINTK("nicstar%d: drain_scq() called, scq at 0x%p, pos %d.\n",
+ card->index, scq, pos);
if (pos >= scq->num_entries) {
printk("nicstar%d: Bad index on drain_scq().\n", card->index);
return;
i = 0;
while (i != pos) {
skb = scq->skb[i];
- XPRINTK("nicstar%d: freeing skb at 0x%x (index %d).\n",
- card->index, (u32) skb, i);
+ XPRINTK("nicstar%d: freeing skb at 0x%p (index %d).\n",
+ card->index, skb, i);
if (skb != NULL) {
+ pci_unmap_single(card->pcidev,
+ NS_PRV_DMA(skb),
+ skb->len,
+ PCI_DMA_TODEVICE);
vcc = ATM_SKB(skb)->vcc;
if (vcc && vcc->pop != NULL) {
vcc->pop(vcc, skb);
else
card->rsq.next++;
} while (ns_rsqe_valid(card->rsq.next));
- writel((((u32) previous) - ((u32) card->rsq.base)),
- card->membase + RSQH);
+ writel(PTR_DIFF(previous, card->rsq.base), card->membase + RSQH);
}
static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe)
unsigned short aal5_len;
int len;
u32 stat;
+ u32 id;
stat = readl(card->membase + STAT);
card->sbfqc = ns_stat_sfbqc_get(stat);
card->lbfqc = ns_stat_lfbqc_get(stat);
- skb = (struct sk_buff *)le32_to_cpu(rsqe->buffer_handle);
+ id = le32_to_cpu(rsqe->buffer_handle);
+ skb = idr_find(&card->idr, id);
+ if (!skb) {
+ RXPRINTK(KERN_ERR
+ "nicstar%d: idr_find() failed!\n", card->index);
+ return;
+ }
+ idr_remove(&card->idr, id);
+ pci_dma_sync_single_for_cpu(card->pcidev,
+ NS_PRV_DMA(skb),
+ (NS_PRV_BUFTYPE(skb) == BUF_SM
+ ? NS_SMSKBSIZE : NS_LGSKBSIZE),
+ PCI_DMA_FROMDEVICE);
+ pci_unmap_single(card->pcidev,
+ NS_PRV_DMA(skb),
+ (NS_PRV_BUFTYPE(skb) == BUF_SM
+ ? NS_SMSKBSIZE : NS_LGSKBSIZE),
+ PCI_DMA_FROMDEVICE);
vpi = ns_rsqe_vpi(rsqe);
vci = ns_rsqe_vci(rsqe);
if (vpi >= 1UL << card->vpibits || vci >= 1UL << card->vcibits) {
recycle_rx_buf(card, skb);
return;
}
- NS_SKB_CB(iovb)->buf_type = BUF_NONE;
+ NS_PRV_BUFTYPE(iovb) = BUF_NONE;
} else if (--card->iovpool.count < card->iovnr.min) {
struct sk_buff *new_iovb;
if ((new_iovb =
alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC)) != NULL) {
- NS_SKB_CB(iovb)->buf_type = BUF_NONE;
+ NS_PRV_BUFTYPE(iovb) = BUF_NONE;
skb_queue_tail(&card->iovpool.queue, new_iovb);
card->iovpool.count++;
}
}
vc->rx_iov = iovb;
- NS_SKB(iovb)->iovcnt = 0;
+ NS_PRV_IOVCNT(iovb) = 0;
iovb->len = 0;
iovb->data = iovb->head;
skb_reset_tail_pointer(iovb);
- NS_SKB(iovb)->vcc = vcc;
/* IMPORTANT: a pointer to the sk_buff containing the small or large
buffer is stored as iovec base, NOT a pointer to the
small or large buffer itself. */
- } else if (NS_SKB(iovb)->iovcnt >= NS_MAX_IOVECS) {
+ } else if (NS_PRV_IOVCNT(iovb) >= NS_MAX_IOVECS) {
printk("nicstar%d: received too big AAL5 SDU.\n", card->index);
atomic_inc(&vcc->stats->rx_err);
recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
NS_MAX_IOVECS);
- NS_SKB(iovb)->iovcnt = 0;
+ NS_PRV_IOVCNT(iovb) = 0;
iovb->len = 0;
iovb->data = iovb->head;
skb_reset_tail_pointer(iovb);
- NS_SKB(iovb)->vcc = vcc;
}
- iov = &((struct iovec *)iovb->data)[NS_SKB(iovb)->iovcnt++];
+ iov = &((struct iovec *)iovb->data)[NS_PRV_IOVCNT(iovb)++];
iov->iov_base = (void *)skb;
iov->iov_len = ns_rsqe_cellcount(rsqe) * 48;
iovb->len += iov->iov_len;
- if (NS_SKB(iovb)->iovcnt == 1) {
- if (NS_SKB_CB(skb)->buf_type != BUF_SM) {
+#ifdef EXTRA_DEBUG
+ if (NS_PRV_IOVCNT(iovb) == 1) {
+ if (NS_PRV_BUFTYPE(skb) != BUF_SM) {
printk
("nicstar%d: Expected a small buffer, and this is not one.\n",
card->index);
recycle_iov_buf(card, iovb);
return;
}
- } else { /* NS_SKB(iovb)->iovcnt >= 2 */
+ } else { /* NS_PRV_IOVCNT(iovb) >= 2 */
- if (NS_SKB_CB(skb)->buf_type != BUF_LG) {
+ if (NS_PRV_BUFTYPE(skb) != BUF_LG) {
printk
("nicstar%d: Expected a large buffer, and this is not one.\n",
card->index);
which_list(card, skb);
atomic_inc(&vcc->stats->rx_err);
recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
- NS_SKB(iovb)->iovcnt);
+ NS_PRV_IOVCNT(iovb));
vc->rx_iov = NULL;
recycle_iov_buf(card, iovb);
return;
}
}
+#endif /* EXTRA_DEBUG */
if (ns_rsqe_eopdu(rsqe)) {
/* This works correctly regardless of the endianness of the host */
- unsigned char *L1L2 = (unsigned char *)((u32) skb->data +
- iov->iov_len - 6);
+ unsigned char *L1L2 = (unsigned char *)
+ (skb->data + iov->iov_len - 6);
aal5_len = L1L2[0] << 8 | L1L2[1];
len = (aal5_len == 0x0000) ? 0x10000 : aal5_len;
if (ns_rsqe_crcerr(rsqe) ||
printk(".\n");
atomic_inc(&vcc->stats->rx_err);
recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
- NS_SKB(iovb)->iovcnt);
+ NS_PRV_IOVCNT(iovb));
vc->rx_iov = NULL;
recycle_iov_buf(card, iovb);
return;
/* By this point we (hopefully) have a complete SDU without errors. */
- if (NS_SKB(iovb)->iovcnt == 1) { /* Just a small buffer */
+ if (NS_PRV_IOVCNT(iovb) == 1) { /* Just a small buffer */
/* skb points to a small buffer */
if (!atm_charge(vcc, skb->truesize)) {
push_rxbufs(card, skb);
vcc->push(vcc, skb);
atomic_inc(&vcc->stats->rx);
}
- } else if (NS_SKB(iovb)->iovcnt == 2) { /* One small plus one large buffer */
+ } else if (NS_PRV_IOVCNT(iovb) == 2) { /* One small plus one large buffer */
struct sk_buff *sb;
sb = (struct sk_buff *)(iov - 1)->iov_base;
recycle_iovec_rx_bufs(card,
(struct iovec *)
iovb->data,
- NS_SKB(iovb)->
- iovcnt);
+ NS_PRV_IOVCNT(iovb));
vc->rx_iov = NULL;
recycle_iov_buf(card, iovb);
return;
card->hbpool.count++;
}
}
- NS_SKB_CB(hb)->buf_type = BUF_NONE;
+ NS_PRV_BUFTYPE(hb) = BUF_NONE;
} else if (--card->hbpool.count < card->hbnr.min) {
struct sk_buff *new_hb;
if ((new_hb =
dev_alloc_skb(NS_HBUFSIZE)) != NULL) {
- NS_SKB_CB(new_hb)->buf_type = BUF_NONE;
+ NS_PRV_BUFTYPE(new_hb) = BUF_NONE;
skb_queue_tail(&card->hbpool.queue,
new_hb);
card->hbpool.count++;
if ((new_hb =
dev_alloc_skb(NS_HBUFSIZE)) !=
NULL) {
- NS_SKB_CB(new_hb)->buf_type =
+ NS_PRV_BUFTYPE(new_hb) =
BUF_NONE;
skb_queue_tail(&card->hbpool.
queue, new_hb);
if (!atm_charge(vcc, hb->truesize)) {
recycle_iovec_rx_bufs(card, iov,
- NS_SKB(iovb)->iovcnt);
+ NS_PRV_IOVCNT(iovb));
if (card->hbpool.count < card->hbnr.max) {
skb_queue_tail(&card->hbpool.queue, hb);
card->hbpool.count++;
push_rxbufs(card, sb);
/* Copy all large buffers to the huge buffer and free them */
- for (j = 1; j < NS_SKB(iovb)->iovcnt; j++) {
+ for (j = 1; j < NS_PRV_IOVCNT(iovb); j++) {
lb = (struct sk_buff *)iov->iov_base;
tocopy =
min_t(int, remaining, iov->iov_len);
sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
if (sb == NULL)
break;
- NS_SKB_CB(sb)->buf_type = BUF_SM;
+ NS_PRV_BUFTYPE(sb) = BUF_SM;
skb_queue_tail(&card->sbpool.queue, sb);
skb_reserve(sb, NS_AAL0_HEADER);
push_rxbufs(card, sb);
lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
if (lb == NULL)
break;
- NS_SKB_CB(lb)->buf_type = BUF_LG;
+ NS_PRV_BUFTYPE(lb) = BUF_LG;
skb_queue_tail(&card->lbpool.queue, lb);
skb_reserve(lb, NS_SMBUFSIZE);
push_rxbufs(card, lb);
hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
if (hb == NULL)
break;
- NS_SKB_CB(hb)->buf_type = BUF_NONE;
+ NS_PRV_BUFTYPE(hb) = BUF_NONE;
skb_queue_tail(&card->hbpool.queue, hb);
card->hbpool.count++;
}
static void recycle_rx_buf(ns_dev * card, struct sk_buff *skb)
{
- struct ns_skb_cb *cb = NS_SKB_CB(skb);
-
- if (unlikely(cb->buf_type == BUF_NONE)) {
+ if (unlikely(NS_PRV_BUFTYPE(skb) == BUF_NONE)) {
printk("nicstar%d: What kind of rx buffer is this?\n",
card->index);
dev_kfree_skb_any(skb);
if (card->sbfqc < card->sbnr.init) {
struct sk_buff *new_sb;
if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) {
- NS_SKB_CB(new_sb)->buf_type = BUF_SM;
+ NS_PRV_BUFTYPE(new_sb) = BUF_SM;
skb_queue_tail(&card->sbpool.queue, new_sb);
skb_reserve(new_sb, NS_AAL0_HEADER);
push_rxbufs(card, new_sb);
{
struct sk_buff *new_sb;
if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) {
- NS_SKB_CB(new_sb)->buf_type = BUF_SM;
+ NS_PRV_BUFTYPE(new_sb) = BUF_SM;
skb_queue_tail(&card->sbpool.queue, new_sb);
skb_reserve(new_sb, NS_AAL0_HEADER);
push_rxbufs(card, new_sb);
if (card->lbfqc < card->lbnr.init) {
struct sk_buff *new_lb;
if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) {
- NS_SKB_CB(new_lb)->buf_type = BUF_LG;
+ NS_PRV_BUFTYPE(new_lb) = BUF_LG;
skb_queue_tail(&card->lbpool.queue, new_lb);
skb_reserve(new_lb, NS_SMBUFSIZE);
push_rxbufs(card, new_lb);
{
struct sk_buff *new_lb;
if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) {
- NS_SKB_CB(new_lb)->buf_type = BUF_LG;
+ NS_PRV_BUFTYPE(new_lb) = BUF_LG;
skb_queue_tail(&card->lbpool.queue, new_lb);
skb_reserve(new_lb, NS_SMBUFSIZE);
push_rxbufs(card, new_lb);
sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
if (sb == NULL)
return -ENOMEM;
- NS_SKB_CB(sb)->buf_type = BUF_SM;
+ NS_PRV_BUFTYPE(sb) = BUF_SM;
skb_queue_tail(&card->sbpool.queue, sb);
skb_reserve(sb, NS_AAL0_HEADER);
push_rxbufs(card, sb);
lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
if (lb == NULL)
return -ENOMEM;
- NS_SKB_CB(lb)->buf_type = BUF_LG;
+ NS_PRV_BUFTYPE(lb) = BUF_LG;
skb_queue_tail(&card->lbpool.queue, lb);
skb_reserve(lb, NS_SMBUFSIZE);
push_rxbufs(card, lb);
hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
if (hb == NULL)
return -ENOMEM;
- NS_SKB_CB(hb)->buf_type = BUF_NONE;
+ NS_PRV_BUFTYPE(hb) = BUF_NONE;
spin_lock_irqsave(&card->int_lock, flags);
skb_queue_tail(&card->hbpool.queue, hb);
card->hbpool.count++;
iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL);
if (iovb == NULL)
return -ENOMEM;
- NS_SKB_CB(iovb)->buf_type = BUF_NONE;
+ NS_PRV_BUFTYPE(iovb) = BUF_NONE;
spin_lock_irqsave(&card->int_lock, flags);
skb_queue_tail(&card->iovpool.queue, iovb);
card->iovpool.count++;
}
}
+#ifdef EXTRA_DEBUG
static void which_list(ns_dev * card, struct sk_buff *skb)
{
- printk("skb buf_type: 0x%08x\n", NS_SKB_CB(skb)->buf_type);
+ printk("skb buf_type: 0x%08x\n", NS_PRV_BUFTYPE(skb));
}
+#endif /* EXTRA_DEBUG */
static void ns_poll(unsigned long arg)
{
card = dev->dev_data;
spin_lock_irqsave(&card->res_lock, flags);
while (CMD_BUSY(card)) ;
- writel((unsigned long)value, card->membase + DR0);
+ writel((u32) value, card->membase + DR0);
writel(NS_CMD_WRITE_UTILITY | 0x00000200 | (addr & 0x000000FF),
card->membase + CMD);
spin_unlock_irqrestore(&card->res_lock, flags);
{
ns_dev *card;
unsigned long flags;
- unsigned long data;
+ u32 data;
card = dev->dev_data;
spin_lock_irqsave(&card->res_lock, flags);