wlan: registration of devices

This commit is contained in:
Matheus
2026-09-09 22:06:20 -03:00
parent 84ad92b475
commit 8134c00b69
4 changed files with 150 additions and 2 deletions
+1
View File
@@ -33,6 +33,7 @@ typedef struct {
#define NETDEV_FLAGS_DEBUG 0x4
#define NETDEV_FLAGS_LOOPBACK 0x8
#define NETDEV_FLAGS_RUNNING 0x40
#define NETDEV_FLAGS_WLAN 0x80
typedef struct netdev_t {
mac_t mac;
+8
View File
@@ -0,0 +1,8 @@
#ifndef _WLAN_H
#define _WLAN_H
#include <u80211_drv/kernel_interface.h>
int wlan_register(void *handle, const u80211_drv_device_metadata_t *metadata, const u80211_drv_device_ops_t *ops, u80211_drv_network_device_handle_t *network_device);
#endif
@@ -253,8 +253,7 @@ int u80211_drv_kernel_submit_bulk_xfer_and_wait(u80211_drv_device_handle_t opaqu
}
int u80211_drv_device_ready(void *device, const u80211_drv_device_metadata_t *metadata, const u80211_drv_device_ops_t *ops, u80211_drv_network_device_handle_t *network_device) {
printf("device ready\n");
return 0;
return wlan_register(device, metadata, ops, network_device) ? U80211_DRV_STATUS_UNKNOWN_ERROR : U80211_DRV_STATUS_SUCCESS;
}
void u80211_drv_packet_received(u80211_drv_network_device_handle_t device, void *packet, size_t packet_size) {
+140
View File
@@ -0,0 +1,140 @@
#include <kernel/wlan.h>
#include <u80211/u80211.h>
#include <kernel/net.h>
#include <logging.h>
#include <string.h>
#include <errno.h>
typedef struct {
netdev_t netdev;
void *driver_handle;
u80211_device_t *u80211_device;
const u80211_drv_device_ops_t *ops;
int id;
} wlan_device_t;
// TODO: in u80211, change the device ops to take a (void *) handle
// TODO: general netdev cleanup:
// - use struct ops instead of having function pointers in netdev struct
// - proper initialize() function
// - proper destroy() function
static uint64_t id_bitmap;
static int allocate_id(void) {
for (;;) {
uint64_t snapshot = __atomic_load_n(&id_bitmap, __ATOMIC_RELAXED);
if (snapshot == UINT64_MAX)
return -1;
int id = __builtin_ctz(~snapshot);
uint64_t mask = 1lu << id;
if (__atomic_fetch_or(&id_bitmap, mask, __ATOMIC_RELAXED) & mask)
continue;
return id;
}
}
static void free_id(int id) {
__atomic_fetch_and(&id_bitmap, ~(1lu << id), __ATOMIC_RELAXED);
}
static int allocate_tx_buffer(u80211_device_t *device, size_t size, u80211_tx_buffer_descriptor_t *buffer_descriptor) {
wlan_device_t *wlan = device->driver_data;
}
static int free_tx_buffer(u80211_device_t *device, u80211_tx_buffer_descriptor_t *buffer_descriptor) {
wlan_device_t *wlan = device->driver_data;
}
static int transmit(u80211_device_t *device, u80211_tx_buffer_descriptor_t *buffer_descriptor, const u80211_transmit_options_t *options) {
wlan_device_t *wlan = device->driver_data;
}
static int set_channel(u80211_device_t *device, int channel) {
wlan_device_t *wlan = device->driver_data;
}
static int set_key(u80211_device_t *device, const u80211_key_t *key) {
wlan_device_t *wlan = device->driver_data;
}
static int del_key(u80211_device_t *device, uint8_t index, const u80211_mac_address_t *peer, uint32_t flags) {
wlan_device_t *wlan = device->driver_data;
}
static u80211_device_ops_t ops = {
.allocate_tx_buffer = allocate_tx_buffer,
.free_tx_buffer = free_tx_buffer,
.transmit = transmit,
.set_channel = set_channel,
.set_key = set_key,
.del_key = del_key
};
static int wlan_alloc_desc(netdev_t *netdev, size_t requestedsize, netdesc_t *desc) {
}
static int wlan_free_desc(netdev_t *netdev, netdesc_t *desc) {
}
static int wlan_send_packet(netdev_t *_internal, netdesc_t desc, mac_t targetmac, int proto) {
}
int wlan_register(void *handle, const u80211_drv_device_metadata_t *drv_metadata, const u80211_drv_device_ops_t *drv_ops, u80211_drv_network_device_handle_t *network_device) {
wlan_device_t *wlan = alloc(sizeof(wlan_device_t));
if (wlan == NULL)
return ENOMEM;
wlan->driver_handle = handle;
wlan->ops = drv_ops;
wlan->netdev.mtu = 1500;
wlan->netdev.sendpacket = wlan_send_packet;
wlan->netdev.allocdesc = wlan_alloc_desc;
wlan->netdev.freedesc = wlan_free_desc;
wlan->netdev.flags = NETDEV_FLAGS_WLAN;
memcpy(&wlan->netdev.mac, &drv_metadata->mac_address, 6);
if (hashtable_init(&wlan->netdev.arpcache, 30)) {
free(wlan);
return ENOMEM;
}
wlan->id = allocate_id();
if (wlan->id == -1) {
hashtable_destroy(&wlan->netdev.arpcache);
free(wlan);
return EAGAIN;
}
u80211_device_metadata_t metadata;
memcpy(&metadata.mac_address, &drv_metadata->mac_address, sizeof(metadata.mac_address));
memcpy(&metadata.rate_bitmap, &drv_metadata->rate_bitmap, sizeof(metadata.rate_bitmap));
int status = u80211_register_device(&metadata, &ops, wlan, &wlan->u80211_device);
if (status != U80211_STATUS_SUCCESS) {
free_id(wlan->id);
hashtable_destroy(&wlan->netdev.arpcache);
free(wlan);
return EINVAL;
}
char name[10];
snprintf(name, 10, "wlan%d", wlan->id);
int error = netdev_register(&wlan->netdev, name);
if (error) {
u80211_unregister_device(wlan->u80211_device);
free_id(wlan->id);
hashtable_destroy(&wlan->netdev.arpcache);
free(wlan);
}
return error;
}