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.7 2003/11/23 00:28:01 dillon Exp $
10 #include <sys/systm.h>
11 #include <sys/kernel.h>
12 #include <sys/msgport.h>
13 #include <sys/msgport2.h>
15 #include <sys/interrupt.h>
16 #include <sys/socket.h>
17 #include <sys/sysctl.h>
19 #include <net/if_var.h>
20 #include <net/netisr.h>
21 #include <machine/cpufunc.h>
22 #include <machine/ipl.h>
25 struct lwkt_msg nm_lmsg;
26 struct mbuf *nm_packet;
27 netisr_fn_t nm_handler;
30 #define CMD_NETMSG_NEWPKT (MSG_CMD_NETMSG | 0x0001)
31 #define CMD_NETMSG_POLL (MSG_CMD_NETMSG | 0x0002)
33 static struct netisr netisrs[NETISR_MAX];
35 /* Per-CPU thread to handle any protocol. */
36 struct thread netisr_cpu[MAXCPU];
43 /* Create default per-cpu threads for generic protocol handling. */
44 for (i = 0; i < ncpus; ++i)
45 lwkt_create(netmsg_service_loop, NULL, NULL, &netisr_cpu[i], 0, i,
49 SYSINIT(netisr, SI_SUB_PROTO_BEGIN, SI_ORDER_FIRST, netisr_init, NULL);
52 netmsg_service_loop(void *arg)
56 while ((msg = lwkt_waitport(&curthread->td_msgport, NULL))) {
57 struct mbuf *m = msg->nm_packet;
58 netisr_fn_t handler = msg->nm_handler;
63 while (m->m_type == MT_TAG)
73 * Call the netisr directly.
74 * Queueing may be done in the msg port layer at its discretion.
77 netisr_dispatch(int num, struct mbuf *m)
79 /* just queue it for now XXX JH */
84 * Same as netisr_dispatch(), but always queue.
85 * This is either used in places where we are not confident that
86 * direct dispatch is possible, or where queueing is required.
89 netisr_queue(int num, struct mbuf *m)
95 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
96 ("netisr_queue: bad isr %d", num));
99 if (ni->ni_handler == NULL) {
100 printf("netisr_queue: unregistered isr %d\n", num);
104 /* use better message allocation system with limits later XXX JH */
105 if (!(pmsg = malloc(sizeof(struct netmsg), M_TEMP, M_NOWAIT)))
108 if (!(port = ni->ni_mport(m)))
111 lwkt_initmsg(&pmsg->nm_lmsg, port, CMD_NETMSG_NEWPKT);
113 pmsg->nm_handler = ni->ni_handler;
114 lwkt_sendmsg(port, &pmsg->nm_lmsg);
119 netisr_register(int num, lwkt_portfn_t mportfn, netisr_fn_t handler)
121 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
122 ("netisr_register: bad isr %d", num));
124 netisrs[num].ni_mport = mportfn;
125 netisrs[num].ni_handler = handler;
129 netisr_unregister(int num)
131 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
132 ("unregister_netisr: bad isr number: %d\n", num));
139 * Return message port for default handler thread on CPU 0.
142 cpu0_portfn(struct mbuf *m)
144 return (&netisr_cpu[0].td_msgport);
148 * This function is used to call the netisr handler from the appropriate
149 * netisr thread for polling and other purposes. pmsg->nm_packet will be
150 * undefined. At the moment operation is restricted to non-packet ISRs only.
155 struct netisr *ni = &netisrs[num];
157 lwkt_port_t port = &netisr_cpu[0].td_msgport;
159 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
160 ("schednetisr: bad isr %d", num));
162 if (!(pmsg = malloc(sizeof(struct netmsg), M_TEMP, M_NOWAIT)))
165 lwkt_initmsg(&pmsg->nm_lmsg, port, CMD_NETMSG_POLL);
166 pmsg->nm_handler = ni->ni_handler;
167 lwkt_sendmsg(port, &pmsg->nm_lmsg);