TCP: Fixed RTO update and dup ACKs generation.
[haiku.git] / src / libs / compat / freebsd_network / driver.c
blob48ad2fed2d4a87c494cee0507128f5169fa39eb3
1 /*
2 * Copyright 2007, Hugo Santos. All Rights Reserved.
3 * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved.
4 * Copyright 2004, Marcus Overhagen. All Rights Reserved.
5 * Distributed under the terms of the MIT License.
6 */
9 /*! Driver functions that adapt the FreeBSD driver to Haiku's driver API.
10 The actual driver functions are exported by the HAIKU_FBSD_DRIVER_GLUE
11 macro, and just call the functions here.
15 #include "device.h"
17 #include <stdlib.h>
18 #include <sys/sockio.h>
20 #include <Drivers.h>
21 #include <ether_driver.h>
22 #include <PCI_x86.h>
24 #include <compat/sys/haiku-module.h>
26 #include <compat/sys/bus.h>
27 #include <compat/sys/mbuf.h>
28 #include <compat/net/ethernet.h>
31 //#define TRACE_DRIVER
32 #ifdef TRACE_DRIVER
33 # define TRACE(x) dprintf x
34 #else
35 # define TRACE(x)
36 #endif
39 const char *gDeviceNameList[MAX_DEVICES + 1];
40 struct ifnet *gDevices[MAX_DEVICES];
41 int32 gDeviceCount;
44 static status_t
45 init_root_device(device_t *_root)
47 static driver_t sRootDriver = {
48 "pci",
49 NULL,
50 sizeof(struct root_device_softc)
53 device_t root = device_add_child(NULL, NULL, 0);
54 if (root == NULL)
55 return B_NO_MEMORY;
57 root->softc = malloc(sizeof(struct root_device_softc));
58 if (root->softc == NULL) {
59 device_delete_child(NULL, root);
60 return B_NO_MEMORY;
63 bzero(root->softc, sizeof(struct root_device_softc));
64 root->driver = &sRootDriver;
65 root->root = root;
67 if (_root != NULL)
68 *_root = root;
70 return B_OK;
74 static status_t
75 add_child_device(driver_t *driver, device_t root, device_t *_child)
77 device_t child = device_add_child(root, driver->name, 0);
78 if (child == NULL) {
79 return B_ERROR;
82 if (_child != NULL)
83 *_child = child;
85 return B_OK;
89 static pci_info *
90 get_pci_info(struct device *device)
92 return &((struct root_device_softc *)device->softc)->pci_info;
96 // #pragma mark - Haiku Driver API
99 status_t
100 _fbsd_init_hardware(driver_t *drivers[])
102 status_t status = B_ENTRY_NOT_FOUND;
103 device_t root;
104 pci_info *info;
105 driver_t *driver = NULL;
106 int i = 0;
108 if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPci) < B_OK)
109 return B_ERROR;
111 status = init_root_device(&root);
112 if (status != B_OK)
113 goto err;
115 for (info = get_pci_info(root); gPci->get_nth_pci_info(i, info) == B_OK;
116 i++) {
117 int index;
118 driver = NULL;
120 for (index = 0; drivers[index] && gDeviceCount < MAX_DEVICES
121 && driver == NULL; index++) {
122 int result;
123 device_t device;
124 status = add_child_device(drivers[index], root, &device);
125 if (status < B_OK)
126 break;
128 result = device->methods.probe(device);
129 if (result >= 0) {
130 TRACE(("%s, found %s at %d\n", gDriverName,
131 device_get_desc(device), i));
132 driver = drivers[index];
134 device_delete_child(root, device);
137 if (driver != NULL)
138 break;
141 device_delete_child(NULL, root);
143 if (driver == NULL) {
144 status = B_ERROR;
145 TRACE(("%s: no hardware found.\n", gDriverName));
147 err:
148 put_module(B_PCI_MODULE_NAME);
149 TRACE(("%s: status 0x%lx\n", gDriverName, status));
151 return status;
155 status_t
156 _fbsd_init_drivers(driver_t *drivers[])
158 status_t status;
159 int i = 0;
160 int index = 0;
161 pci_info *info;
162 device_t root;
164 status = get_module(B_PCI_MODULE_NAME, (module_info **)&gPci);
165 if (status < B_OK)
166 return status;
168 // if it fails we just don't support x86 specific features (like MSIs)
169 if (get_module(B_PCI_X86_MODULE_NAME, (module_info **)&gPCIx86) != B_OK)
170 gPCIx86 = NULL;
172 status = init_hard_clock();
173 if (status < B_OK)
174 goto err1;
176 status = init_mutexes();
177 if (status < B_OK)
178 goto err2;
180 status = init_mbufs();
181 if (status < B_OK)
182 goto err3;
184 status = init_callout();
185 if (status < B_OK)
186 goto err4;
188 init_bounce_pages();
190 if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES)) {
191 status = init_taskqueues();
192 if (status < B_OK)
193 goto err5;
196 status = init_wlan_stack();
197 if (status < B_OK)
198 goto err6;
200 status = init_root_device(&root);
201 if (status != B_OK)
202 goto err7;
204 for (info = get_pci_info(root); gPci->get_nth_pci_info(i, info) == B_OK;
205 i++) {
206 int best = 0;
207 driver_t *driver = NULL;
209 for (index = 0; drivers[index] && gDeviceCount < MAX_DEVICES; index++) {
210 int result;
211 device_t device;
212 status = add_child_device(drivers[index], root, &device);
213 if (status < B_OK)
214 break;
216 result = device->methods.probe(device);
217 if (result >= 0 && (driver == NULL || result > best)) {
218 TRACE(("%s, found %s at %d (%d)\n", gDriverName,
219 device_get_desc(device), i, result));
220 driver = drivers[index];
221 best = result;
223 device_delete_child(root, device);
226 if (driver != NULL) {
227 device_t device;
228 status = add_child_device(driver, root, &device);
229 if (status != B_OK)
230 break;
231 if (device_attach(device) == 0) {
232 dprintf("%s: init_driver(%p) at %d\n", gDriverName, driver, i);
233 } else
234 device_delete_child(root, device);
238 if (gDeviceCount > 0)
239 return B_OK;
241 device_delete_child(NULL, root);
243 if (status == B_OK)
244 status = B_ERROR;
246 err7:
247 uninit_wlan_stack();
249 err6:
250 if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES))
251 uninit_taskqueues();
252 err5:
253 uninit_mbufs();
254 err4:
255 uninit_callout();
256 err3:
257 uninit_mutexes();
258 err2:
259 uninit_hard_clock();
260 err1:
261 put_module(B_PCI_MODULE_NAME);
262 if (gPCIx86 != NULL)
263 put_module(B_PCI_X86_MODULE_NAME);
265 return status;
269 status_t
270 _fbsd_uninit_drivers(driver_t *drivers[])
272 int i;
274 for (i = 0; drivers[i]; i++)
275 TRACE(("%s: uninit_driver(%p)\n", gDriverName, drivers[i]));
277 for (i = 0; i < gDeviceCount; i++) {
278 device_delete_child(NULL, gDevices[i]->root_device);
281 uninit_wlan_stack();
282 uninit_bounce_pages();
283 uninit_mbufs();
284 if (HAIKU_DRIVER_REQUIRES(FBSD_TASKQUEUES))
285 uninit_taskqueues();
286 uninit_callout();
287 uninit_mutexes();
288 uninit_hard_clock();
290 put_module(B_PCI_MODULE_NAME);
291 if (gPCIx86 != NULL)
292 put_module(B_PCI_X86_MODULE_NAME);
294 return B_OK;