drivers/net/ethernet/dec/tulip/interrupt.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/dec/tulip/interrupt.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/dec/tulip/interrupt.c
Extension
.c
Size
25466 bytes
Lines
823
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (tp->rx_buffers[entry].skb == NULL) {
			struct sk_buff *skb;
			dma_addr_t mapping;

			skb = tp->rx_buffers[entry].skb =
				netdev_alloc_skb(dev, PKT_BUF_SZ);
			if (skb == NULL)
				break;

			mapping = dma_map_single(&tp->pdev->dev, skb->data,
						 PKT_BUF_SZ, DMA_FROM_DEVICE);
			if (dma_mapping_error(&tp->pdev->dev, mapping)) {
				dev_kfree_skb(skb);
				tp->rx_buffers[entry].skb = NULL;
				break;
			}

			tp->rx_buffers[entry].mapping = mapping;

			tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping);
			refilled++;
		}
		tp->rx_ring[entry].status = cpu_to_le32(DescOwned);
	}
	if(tp->chip_id == LC82C168) {
		if(((ioread32(tp->base_addr + CSR5)>>17)&0x07) == 4) {
			/* Rx stopped due to out of buffers,
			 * restart it
			 */
			iowrite32(0x01, tp->base_addr + CSR2);
		}
	}
	return refilled;
}

#ifdef CONFIG_TULIP_NAPI

void oom_timer(struct timer_list *t)
{
	struct tulip_private *tp = timer_container_of(tp, t, oom_timer);

	napi_schedule(&tp->napi);
}

int tulip_poll(struct napi_struct *napi, int budget)
{
	struct tulip_private *tp = container_of(napi, struct tulip_private, napi);
	struct net_device *dev = tp->dev;
	int entry = tp->cur_rx % RX_RING_SIZE;
	int work_done = 0;
#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION
	int received = 0;
#endif

#ifdef CONFIG_TULIP_NAPI_HW_MITIGATION

/* that one buffer is needed for mit activation; or might be a
   bug in the ring buffer code; check later -- JHS*/

        if (budget >=RX_RING_SIZE) budget--;
#endif

	if (tulip_debug > 4)
		netdev_dbg(dev, " In tulip_rx(), entry %d %08x\n",
			   entry, tp->rx_ring[entry].status);

       do {
		if (ioread32(tp->base_addr + CSR5) == 0xffffffff) {
			netdev_dbg(dev, " In tulip_poll(), hardware disappeared\n");
			break;
		}
               /* Acknowledge current RX interrupt sources. */
               iowrite32((RxIntr | RxNoBuf), tp->base_addr + CSR5);


               /* If we own the next entry, it is a new packet. Send it up. */
               while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
                       s32 status = le32_to_cpu(tp->rx_ring[entry].status);
		       short pkt_len;

                       if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
                               break;

		       if (tulip_debug > 5)
				netdev_dbg(dev, "In tulip_rx(), entry %d %08x\n",
					   entry, status);

		       if (++work_done >= budget)
                               goto not_done;

Annotation

Implementation Notes