netdev_eth.c
3.1 KB
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup driver_netdev_eth
* @{
*
* @file
* @brief Common code for netdev ethernet drivers
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
*
* @}
*/
#include <assert.h>
#include <errno.h>
#include "net/netdev.h"
#include "net/eui64.h"
#include "net/ethernet.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
static int _get_iid(netdev_t *netdev, eui64_t *value, size_t max_len)
{
if (max_len < sizeof(eui64_t)) {
return -EOVERFLOW;
}
uint8_t addr[ETHERNET_ADDR_LEN];
netdev->driver->get(netdev, NETOPT_ADDRESS, addr, ETHERNET_ADDR_LEN);
ethernet_get_iid(value, addr);
return sizeof(eui64_t);
}
int netdev_eth_get(netdev_t *dev, netopt_t opt, void *value, size_t max_len)
{
int res = 0;
switch (opt) {
case NETOPT_DEVICE_TYPE:
{
uint16_t *tgt = (uint16_t *)value;
*tgt = NETDEV_TYPE_ETHERNET;
res = 2;
break;
}
case NETOPT_ADDR_LEN:
case NETOPT_SRC_LEN:
{
assert(max_len == 2);
uint16_t *tgt = (uint16_t*)value;
*tgt=6;
res = sizeof(uint16_t);
break;
}
case NETOPT_MAX_PACKET_SIZE:
{
assert(max_len >= 2);
uint16_t *val = (uint16_t*) value;
*val = ETHERNET_DATA_LEN;
res = sizeof(uint16_t);
break;
}
case NETOPT_IS_WIRED:
{
res = 1;
break;
}
case NETOPT_IPV6_IID:
{
return _get_iid(dev, value, max_len);
}
#ifdef MODULE_NETSTATS_L2
case NETOPT_STATS:
{
assert(max_len >= sizeof(uintptr_t));
*((netstats_t**)value) = &dev->stats;
res = sizeof(uintptr_t);
break;
}
#endif
#ifdef MODULE_L2FILTER
case NETOPT_L2FILTER:
{
assert(max_len >= sizeof(l2filter_t **));
*((l2filter_t **)value) = dev->filter;
res = sizeof(l2filter_t **);
break;
}
#endif
default:
{
res = -ENOTSUP;
break;
}
}
return res;
}
int netdev_eth_set(netdev_t *dev, netopt_t opt, const void *value, size_t value_len)
{
#ifndef MODULE_L2FILTER
(void)dev;
#endif
(void)value;
(void)value_len;
int res = 0;
switch (opt) {
#ifdef MODULE_L2FILTER
case NETOPT_L2FILTER:
res = l2filter_add(dev->filter, value, value_len);
break;
case NETOPT_L2FILTER_RM:
res = l2filter_rm(dev->filter, value, value_len);
break;
#endif
default:
res = -ENOTSUP;
break;
}
return res;
}