xref: /freebsd/sys/dev/wtap/wtap_hal/hal.c (revision 177034c44ed18d99e6cc85dfddd2bb04b41d38ac)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2010-2011 Monthadar Al Jaberi, TerraNet AB
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer,
12  *    without modification.
13  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15  *    redistribution must be conditioned upon including a substantially
16  *    similar Disclaimer requirement for further binary redistribution.
17  *
18  * NO WARRANTY
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
22  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
24  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29  * THE POSSIBILITY OF SUCH DAMAGES.
30  *
31  * $FreeBSD$
32  */
33 #include "hal.h"
34 #include "../if_medium.h"
35 #include "handler.h"
36 
37 static void
38 hal_tx_proc(void *arg, int npending)
39 {
40 	struct wtap_hal *hal = (struct wtap_hal *)arg;
41 	struct packet *p;
42 
43 #if 0
44 	DWTAP_PRINTF("%s\n", __func__);
45 #endif
46 
47 	hal = (struct wtap_hal *)arg;
48 	for(;;){
49 		p = medium_get_next_packet(hal->hal_md);
50 		if(p == NULL)
51 		return;
52 
53 		hal->plugin->work(hal->plugin, p);
54 
55 #if 0
56 		DWTAP_PRINTF("[%d] freeing m=%p\n", p->id, p->m);
57 #endif
58 		m_free(p->m);
59 		free(p, M_WTAP_PACKET);
60 	}
61 }
62 
63 void
64 init_hal(struct wtap_hal *hal)
65 {
66 
67 	DWTAP_PRINTF("%s\n", __func__);
68 	mtx_init(&hal->hal_mtx, "wtap_hal mtx", NULL, MTX_DEF | MTX_RECURSE);
69 
70 	hal->hal_md = (struct wtap_medium *)malloc(sizeof(struct wtap_medium),
71 	    M_WTAP, M_NOWAIT | M_ZERO);
72 
73 	init_medium(hal->hal_md);
74 	/* register event handler for packets */
75 	TASK_INIT(&hal->hal_md->tx_handler->proc, 0, hal_tx_proc, hal);
76 
77 	callout_init_mtx(&hal->hw.timer_intr, &hal->hal_mtx, 0);
78 	hal->hw.timer_intr_intval = msecs_to_ticks(HAL_TIMER_INTVAL);
79 }
80 
81 void
82 register_plugin(struct wtap_hal *hal, struct wtap_plugin *plugin)
83 {
84 
85 	plugin->init(plugin);
86 	hal->plugin = plugin;
87 }
88 
89 void
90 deregister_plugin(struct wtap_hal *hal)
91 {
92 
93 	hal->plugin->deinit(hal->plugin);
94 	hal->plugin = NULL; /* catch illegal usages */
95 }
96 
97 void
98 deinit_hal(struct wtap_hal *hal)
99 {
100 
101 	DWTAP_PRINTF("%s\n", __func__);
102 	deinit_medium(hal->hal_md);
103 	free(hal->hal_md, M_WTAP);
104 	mtx_destroy(&hal->hal_mtx);
105 }
106 
107 int32_t
108 new_wtap(struct wtap_hal *hal, int32_t id)
109 {
110 	static const uint8_t mac_pool[64][IEEE80211_ADDR_LEN] = {
111 	    {0,152,154,152,150,151},
112 	    {0,152,154,152,150,152},
113 	    {0,152,154,152,150,153},
114 	    {0,152,154,152,150,154},
115 	    {0,152,154,152,150,155},
116 	    {0,152,154,152,150,156},
117 	    {0,152,154,152,150,157},
118 	    {0,152,154,152,150,158},
119 	    {0,152,154,152,151,151},
120 	    {0,152,154,152,151,152},
121 	    {0,152,154,152,151,153},
122 	    {0,152,154,152,151,154},
123 	    {0,152,154,152,151,155},
124 	    {0,152,154,152,151,156},
125 	    {0,152,154,152,151,157},
126 	    {0,152,154,152,151,158},
127 	    {0,152,154,152,152,151},
128 	    {0,152,154,152,152,152},
129 	    {0,152,154,152,152,153},
130 	    {0,152,154,152,152,154},
131 	    {0,152,154,152,152,155},
132 	    {0,152,154,152,152,156},
133 	    {0,152,154,152,152,157},
134 	    {0,152,154,152,152,158},
135 	    {0,152,154,152,153,151},
136 	    {0,152,154,152,153,152},
137 	    {0,152,154,152,153,153},
138 	    {0,152,154,152,153,154},
139 	    {0,152,154,152,153,155},
140 	    {0,152,154,152,153,156},
141 	    {0,152,154,152,153,157},
142 	    {0,152,154,152,153,158},
143 	    {0,152,154,152,154,151},
144 	    {0,152,154,152,154,152},
145 	    {0,152,154,152,154,153},
146 	    {0,152,154,152,154,154},
147 	    {0,152,154,152,154,155},
148 	    {0,152,154,152,154,156},
149 	    {0,152,154,152,154,157},
150 	    {0,152,154,152,154,158},
151 	    {0,152,154,152,155,151},
152 	    {0,152,154,152,155,152},
153 	    {0,152,154,152,155,153},
154 	    {0,152,154,152,155,154},
155 	    {0,152,154,152,155,155},
156 	    {0,152,154,152,155,156},
157 	    {0,152,154,152,155,157},
158 	    {0,152,154,152,155,158},
159 	    {0,152,154,152,156,151},
160 	    {0,152,154,152,156,152},
161 	    {0,152,154,152,156,153},
162 	    {0,152,154,152,156,154},
163 	    {0,152,154,152,156,155},
164 	    {0,152,154,152,156,156},
165 	    {0,152,154,152,156,157},
166 	    {0,152,154,152,156,158},
167 	    {0,152,154,152,157,151},
168 	    {0,152,154,152,157,152},
169 	    {0,152,154,152,157,153},
170 	    {0,152,154,152,157,154},
171 	    {0,152,154,152,157,155},
172 	    {0,152,154,152,157,156},
173 	    {0,152,154,152,157,157},
174 	    {0,152,154,152,157,158}
175 	    };
176 
177 	DWTAP_PRINTF("%s\n", __func__);
178 	uint8_t const *macaddr = mac_pool[id];
179 	if(hal->hal_devs[id] != NULL){
180 		printf("error, wtap_id=%d already created\n", id);
181 		return -1;
182 	}
183 
184 	hal->hal_devs[id] = (struct wtap_softc *)malloc(
185 	    sizeof(struct wtap_softc), M_WTAP, M_NOWAIT | M_ZERO);
186 	hal->hal_devs[id]->sc_md = hal->hal_md;
187 	hal->hal_devs[id]->id = id;
188 	hal->hal_devs[id]->hal = hal;
189 	snprintf(hal->hal_devs[id]->name, sizeof(hal->hal_devs[id]->name),
190 	    "wtap%d", id);
191 	mtx_init(&hal->hal_devs[id]->sc_mtx, "wtap_softc mtx", NULL,
192 	    MTX_DEF | MTX_RECURSE);
193 
194 	if(wtap_attach(hal->hal_devs[id], macaddr)){
195 		printf("%s, cant alloc new wtap\n", __func__);
196 		return -1;
197 	}
198 
199 	return 0;
200 }
201 
202 int32_t
203 free_wtap(struct wtap_hal *hal, int32_t id)
204 {
205 
206 	DWTAP_PRINTF("%s\n", __func__);
207 	if(hal->hal_devs[id] == NULL){
208 		printf("error, wtap_id=%d never created\n", id);
209 		return -1;
210 	}
211 
212 	if(wtap_detach(hal->hal_devs[id]))
213 		printf("%s, cant alloc new wtap\n", __func__);
214 	mtx_destroy(&hal->hal_devs[id]->sc_mtx);
215 	free(hal->hal_devs[id], M_WTAP);
216 	hal->hal_devs[id] = NULL;
217 	return 0;
218 }
219 
220 void
221 wtap_hal_timer_intr(void *arg)
222 {
223 	struct wtap_hal *hal = arg;
224 	uint32_t intval = hal->hw.timer_intr_intval;
225 
226 	hal->hw.tsf += ticks_to_msecs(intval);
227 
228 	callout_schedule(&hal->hw.timer_intr, intval);
229 }
230 
231 void
232 wtap_hal_reset_tsf(struct wtap_hal *hal)
233 {
234 	mtx_lock(&hal->hal_mtx);
235 
236 	callout_stop(&hal->hw.timer_intr);
237 	hal->hw.tsf = 0;
238 	callout_reset(&hal->hw.timer_intr, hal->hw.timer_intr_intval,
239 	    wtap_hal_timer_intr, hal);
240 
241 	mtx_unlock(&hal->hal_mtx);
242 }
243 
244 uint64_t
245 wtap_hal_get_tsf(struct wtap_hal *hal)
246 {
247 	return (hal->hw.tsf);
248 }
249