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.3 2003/11/08 07:57:42 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))) {
57 struct mbuf *m = msg->nm_packet;
58 netisr_fn_t handler = msg->nm_handler;
69 * Call the netisr directly.
70 * Queueing may be done in the msg port layer at its discretion.
73 netisr_dispatch(int num, struct mbuf *m)
75 /* just queue it for now XXX JH */
80 * Same as netisr_dispatch(), but always queue.
81 * This is either used in places where we are not confident that
82 * direct dispatch is possible, or where queueing is required.
85 netisr_queue(int num, struct mbuf *m)
87 struct netisr *ni = &netisrs[num];
91 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
94 /* use better message allocation system with limits later XXX JH */
95 if (!(pmsg = malloc(sizeof(struct netmsg), M_TEMP, M_NOWAIT)))
98 if (!(port = ni->ni_mport(m)))
101 lwkt_initmsg(&pmsg->nm_lmsg, port, CMD_NETMSG_NEWPKT);
103 pmsg->nm_handler = ni->ni_handler;
104 lwkt_sendmsg(port, &pmsg->nm_lmsg);
109 netisr_register(int num, lwkt_portfn_t mportfn, netisr_fn_t handler)
111 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
112 ("bad isr %d", num));
114 netisrs[num].ni_mport = mportfn;
115 netisrs[num].ni_handler = handler;
119 netisr_unregister(int num)
121 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
122 ("unregister_netisr: bad isr number: %d\n", num));
129 * Return message port for default handler thread on CPU 0.
132 cpu0_portfn(struct mbuf *m)
134 return (&netisr_cpu[0].td_msgport);
138 * This function is used to call the netisr handler from the appropriate
139 * netisr thread for polling and other purposes. pmsg->nm_packet will be
140 * undefined. At the moment operation is restricted to non-packet ISRs only.
145 struct netisr *ni = &netisrs[num];
147 lwkt_port_t port = &netisr_cpu[0].td_msgport;
149 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
150 ("bad isr %d", num));
152 if (!(pmsg = malloc(sizeof(struct netmsg), M_TEMP, M_NOWAIT)))
155 lwkt_initmsg(&pmsg->nm_lmsg, port, CMD_NETMSG_POLL);
156 pmsg->nm_handler = ni->ni_handler;
157 lwkt_sendmsg(port, &pmsg->nm_lmsg);