2 * Copyright (c) 2003 Jeffrey Hsu
3 * Copyright (c) 2003 Jonathan Lemon
4 * Copyright (c) 2003 Matthew Dillon
6 * $DragonFly: src/sys/net/netisr.c,v 1.2 2003/09/15 23:38:13 hsu Exp $
10 #include <sys/systm.h>
12 #include <sys/interrupt.h>
13 #include <sys/socket.h>
14 #include <sys/sysctl.h>
16 #include <net/if_var.h>
17 #include <net/netisr.h>
18 #include <machine/cpufunc.h>
19 #include <machine/ipl.h>
22 static int isrsoftint_installed;
23 static struct netisr netisrs[NETISR_MAX];
25 /* SYSCTL_NODE(_net, OID_AUTO, isr, CTLFLAG_RW, 0, "netisr counters"); */
27 static int netisr_directdispatch = 0;
29 SYSCTL_INT(_net_isr, OID_AUTO, directdispatch, CTLFLAG_RW,
30 &netisr_directdispatch, 0, "enable direct dispatch");
39 while ((mask = isrmask) != 0) {
41 if (btrl(&isrmask, bit)) {
42 struct netisr *ni = &netisrs[bit];
43 netisr_fn_t func = ni->ni_handler;
51 IF_DEQUEUE(ni->ni_queue, m);
64 * Call the netisr directly instead of queueing the packet, if possible.
67 netisr_dispatch(int num, struct mbuf *m)
71 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
81 if (netisr_directdispatch) {
83 * missing check for concurrent execution from swi_net() XXX JH
84 * Address this after conversion to message ports.
88 if (IF_HANDOFF(ni->ni_queue, m, NULL))
94 * Same as netisr_dispatch(), but always queue.
95 * This is either used in places where we are not confident that
96 * direct dispatch is possible, or where queueing is required.
99 netisr_queue(int num, struct mbuf *m)
103 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
104 ("bad isr %d", num));
113 if (!IF_HANDOFF(ni->ni_queue, m, NULL))
121 netisr_register(int num, netisr_fn_t handler, struct ifqueue *ifq)
123 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
124 ("bad isr %d", num));
126 if (isrsoftint_installed == 0) {
127 isrsoftint_installed = 1;
128 register_swi(SWI_NET, swi_net, NULL, "swi_net");
130 netisrs[num].ni_handler = handler;
131 netisrs[num].ni_queue = ifq;
136 netisr_unregister(int num)
138 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
139 ("unregister_netisr: bad isr number: %d\n", num));
141 if (netisrs[num].ni_queue != NULL) {
145 IF_DRAIN(netisrs[num].ni_queue);
148 netisrs[num].ni_handler = NULL;