1 /*
2 * Copyright (c) 2016 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Public API for network L2 interface
10 */
11
12 #ifndef ZEPHYR_INCLUDE_NET_NET_L2_H_
13 #define ZEPHYR_INCLUDE_NET_NET_L2_H_
14
15 #include <zephyr/device.h>
16 #include <zephyr/net/buf.h>
17 #include <zephyr/net/capture.h>
18 #include <zephyr/sys/iterable_sections.h>
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 /**
25 * @brief Network Layer 2 abstraction layer
26 * @defgroup net_l2 Network L2 Abstraction Layer
27 * @since 1.5
28 * @version 1.0.0
29 * @ingroup networking
30 * @{
31 */
32
33 struct net_if;
34
35 /** L2 flags */
36 enum net_l2_flags {
37 /** IP multicast supported */
38 NET_L2_MULTICAST = BIT(0),
39
40 /** Do not join solicited node multicast group */
41 NET_L2_MULTICAST_SKIP_JOIN_SOLICIT_NODE = BIT(1),
42
43 /** Is promiscuous mode supported */
44 NET_L2_PROMISC_MODE = BIT(2),
45
46 /** Is this L2 point-to-point with tunneling so no need to have
47 * IP address etc to network interface.
48 */
49 NET_L2_POINT_TO_POINT = BIT(3),
50 } __packed;
51
52 /**
53 * @brief Network L2 structure
54 *
55 * Used to provide an interface to lower network stack.
56 */
57 struct net_l2 {
58 /**
59 * This function is used by net core to get iface's L2 layer parsing
60 * what's relevant to itself.
61 */
62 enum net_verdict (*recv)(struct net_if *iface, struct net_pkt *pkt);
63
64 /**
65 * This function is used by net core to push a packet to lower layer
66 * (interface's L2), which in turn might work on the packet relevantly.
67 * (adding proper header etc...)
68 * Returns a negative error code, or the number of bytes sent otherwise.
69 */
70 int (*send)(struct net_if *iface, struct net_pkt *pkt);
71
72 /**
73 * This function is used to enable/disable traffic over a network
74 * interface. The function returns <0 if error and >=0 if no error.
75 */
76 int (*enable)(struct net_if *iface, bool state);
77
78 /**
79 * Return L2 flags for the network interface.
80 */
81 enum net_l2_flags (*get_flags)(struct net_if *iface);
82 };
83
84 /** @cond INTERNAL_HIDDEN */
85 #define NET_L2_GET_NAME(_name) _net_l2_##_name
86 #define NET_L2_DECLARE_PUBLIC(_name) \
87 extern const struct net_l2 NET_L2_GET_NAME(_name)
88 #define NET_L2_GET_CTX_TYPE(_name) _name##_CTX_TYPE
89
90 #define VIRTUAL_L2 VIRTUAL
91 NET_L2_DECLARE_PUBLIC(VIRTUAL_L2);
92
93 #define DUMMY_L2 DUMMY
94 #define DUMMY_L2_CTX_TYPE void*
95 NET_L2_DECLARE_PUBLIC(DUMMY_L2);
96
97 #define OFFLOADED_NETDEV_L2 OFFLOADED_NETDEV
98 NET_L2_DECLARE_PUBLIC(OFFLOADED_NETDEV_L2);
99
100 #define ETHERNET_L2 ETHERNET
101 NET_L2_DECLARE_PUBLIC(ETHERNET_L2);
102
103 #define PPP_L2 PPP
104 NET_L2_DECLARE_PUBLIC(PPP_L2);
105
106 #define IEEE802154_L2 IEEE802154
107 NET_L2_DECLARE_PUBLIC(IEEE802154_L2);
108
109 #define OPENTHREAD_L2 OPENTHREAD
110 NET_L2_DECLARE_PUBLIC(OPENTHREAD_L2);
111
112 #define CANBUS_RAW_L2 CANBUS_RAW
113 #define CANBUS_RAW_L2_CTX_TYPE void*
114 NET_L2_DECLARE_PUBLIC(CANBUS_RAW_L2);
115
116 #ifdef CONFIG_NET_L2_CUSTOM_IEEE802154
117 #ifndef CUSTOM_IEEE802154_L2
118 #define CUSTOM_IEEE802154_L2 CUSTOM_IEEE802154
119 #endif
120 #define CUSTOM_IEEE802154_L2_CTX_TYPE void*
121 NET_L2_DECLARE_PUBLIC(CUSTOM_IEEE802154_L2);
122 #endif /* CONFIG_NET_L2_CUSTOM_IEEE802154 */
123
124 #define NET_L2_INIT(_name, _recv_fn, _send_fn, _enable_fn, _get_flags_fn) \
125 const STRUCT_SECTION_ITERABLE(net_l2, \
126 NET_L2_GET_NAME(_name)) = { \
127 .recv = (_recv_fn), \
128 .send = (_send_fn), \
129 .enable = (_enable_fn), \
130 .get_flags = (_get_flags_fn), \
131 }
132
133 #define NET_L2_GET_DATA(name, sfx) _net_l2_data_##name##sfx
134
135 #define NET_L2_DATA_INIT(name, sfx, ctx_type) \
136 static ctx_type NET_L2_GET_DATA(name, sfx) __used;
137
138 typedef int (*net_l2_send_t)(const struct device *dev, struct net_pkt *pkt);
139
net_l2_send(net_l2_send_t send_fn,const struct device * dev,struct net_if * iface,struct net_pkt * pkt)140 static inline int net_l2_send(net_l2_send_t send_fn,
141 const struct device *dev,
142 struct net_if *iface,
143 struct net_pkt *pkt)
144 {
145 net_capture_pkt(iface, pkt);
146
147 return send_fn(dev, pkt);
148 }
149
150 /** @endcond */
151
152 /**
153 * @}
154 */
155
156 #ifdef __cplusplus
157 }
158 #endif
159
160 #endif /* ZEPHYR_INCLUDE_NET_NET_L2_H_ */
161