in nicstar.c [946:1058]
static void push_rxbufs(ns_dev * card, struct sk_buff *skb)
{
struct sk_buff *handle1, *handle2;
int id1, id2;
u32 addr1, addr2;
u32 stat;
unsigned long flags;
/* *BARF* */
handle2 = NULL;
addr2 = 0;
handle1 = skb;
addr1 = dma_map_single(&card->pcidev->dev,
skb->data,
(NS_PRV_BUFTYPE(skb) == BUF_SM
? NS_SMSKBSIZE : NS_LGSKBSIZE),
DMA_TO_DEVICE);
NS_PRV_DMA(skb) = addr1; /* save so we can unmap later */
#ifdef GENERAL_DEBUG
if (!addr1)
printk("nicstar%d: push_rxbufs called with addr1 = 0.\n",
card->index);
#endif /* GENERAL_DEBUG */
stat = readl(card->membase + STAT);
card->sbfqc = ns_stat_sfbqc_get(stat);
card->lbfqc = ns_stat_lfbqc_get(stat);
if (NS_PRV_BUFTYPE(skb) == BUF_SM) {
if (!addr2) {
if (card->sm_addr) {
addr2 = card->sm_addr;
handle2 = card->sm_handle;
card->sm_addr = 0x00000000;
card->sm_handle = NULL;
} else { /* (!sm_addr) */
card->sm_addr = addr1;
card->sm_handle = handle1;
}
}
} else { /* buf_type == BUF_LG */
if (!addr2) {
if (card->lg_addr) {
addr2 = card->lg_addr;
handle2 = card->lg_handle;
card->lg_addr = 0x00000000;
card->lg_handle = NULL;
} else { /* (!lg_addr) */
card->lg_addr = addr1;
card->lg_handle = handle1;
}
}
}
if (addr2) {
if (NS_PRV_BUFTYPE(skb) == BUF_SM) {
if (card->sbfqc >= card->sbnr.max) {
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(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;
}
id1 = idr_alloc(&card->idr, handle1, 0, 0, GFP_ATOMIC);
if (id1 < 0)
goto out;
id2 = idr_alloc(&card->idr, handle2, 0, 0, GFP_ATOMIC);
if (id2 < 0)
goto out;
spin_lock_irqsave(&card->res_lock, flags);
while (CMD_BUSY(card)) ;
writel(addr2, card->membase + DR3);
writel(id2, card->membase + DR2);
writel(addr1, card->membase + DR1);
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,
(NS_PRV_BUFTYPE(skb) == BUF_SM ? "small" : "large"),
addr1, addr2);
}
if (!card->efbie && card->sbfqc >= card->sbnr.min &&
card->lbfqc >= card->lbnr.min) {
card->efbie = 1;
writel((readl(card->membase + CFG) | NS_CFG_EFBIE),
card->membase + CFG);
}
out:
return;
}