summaryrefslogtreecommitdiff
path: root/accel-dp/dev.c
blob: d31773db06de1f329a8feb978fe2b8af3bb36dbe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <string.h>

#include <rte_malloc.h>

#include "init.h"
#include "dev.h"

#define DEV_MAX 65536

static struct net_device **dev_list;
static int next_idx = 1;

struct net_device *netdev_get_by_index(int id)
{
	struct net_device *dev;

	if (id <= 0 || id >= DEV_MAX)
		return NULL;

	dev = dev_list[id];

	if (dev)
		++dev->refs;

	return dev;
}

struct net_device *netdev_alloc(const char *name, int priv_size, void (*setup)(struct net_device *dev))
{
	struct net_device *dev;
	int i;

	for (i = 0; i < DEV_MAX; i++) {
		if (dev_list[i] && !strcmp(dev_list[i]->name, name))
			return NULL;
	}

	for (; next_idx < DEV_MAX; next_idx++) {
		if (!dev_list[next_idx])
			break;
	}

	if (next_idx == DEV_MAX) {
		for (next_idx = 1; next_idx < DEV_MAX; next_idx++) {
			if (!dev_list[next_idx])
				break;
		}

		if (next_idx == DEV_MAX)
			return NULL;
	}

	dev = rte_malloc(NULL, sizeof(*dev) + priv_size, 0);
	strcpy(dev->name, name);
	dev->index = next_idx;

	dev->refs = 1;
	dev->destructor = netdev_free;

	if (setup)
		setup(dev);

	dev_list[next_idx] = dev;

	if (++next_idx == DEV_MAX)
		next_idx = 1;

	return dev;
}

void netdev_unregister(struct net_device *dev)
{
	dev_list[dev->index] = NULL;

	netdev_put(dev);
}

void netdev_free(struct net_device *dev)
{
	rte_free(dev);
}

void netdev_put(struct net_device *dev)
{
	if (--dev->refs == 0)
		dev->destructor(dev);
}

static void init()
{
	dev_list = rte_zmalloc(0, DEV_MAX * sizeof(void *), 0);
}

DEFINE_INIT(1, init);