net: dummy L2 for offloaded ifaces
Adds dummy link layer for offloaded ifaces, allowing
ifaces to directly receive l2_enable calls
Signed-off-by: Georges Oates_Larsen <georges.larsen@nordicsemi.no>
diff --git a/drivers/modem/hl7800.c b/drivers/modem/hl7800.c
index 792f0c8..c80787e 100644
--- a/drivers/modem/hl7800.c
+++ b/drivers/modem/hl7800.c
@@ -29,6 +29,7 @@
#include <zephyr/net/net_offload.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/dns_resolve.h>
+#include <zephyr/net/offloaded_netdev.h>
#if defined(CONFIG_NET_IPV6)
#include "ipv6.h"
#endif
@@ -6424,8 +6425,8 @@
}
}
-static struct net_if_api api_funcs = {
- .init = offload_iface_init,
+static struct offloaded_if_api api_funcs = {
+ .iface_api.init = offload_iface_init,
};
NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, hl7800_init, NULL, &ictx,
diff --git a/drivers/modem/quectel-bg9x.c b/drivers/modem/quectel-bg9x.c
index 75d49c4..40baa2c 100644
--- a/drivers/modem/quectel-bg9x.c
+++ b/drivers/modem/quectel-bg9x.c
@@ -1096,8 +1096,8 @@
net_if_socket_offload_set(iface, offload_socket);
}
-static struct net_if_api api_funcs = {
- .init = modem_net_iface_init,
+static struct offloaded_if_api api_funcs = {
+ .iface_api.init = modem_net_iface_init,
};
static bool offload_is_supported(int family, int type, int proto)
diff --git a/drivers/modem/quectel-bg9x.h b/drivers/modem/quectel-bg9x.h
index a4541b0..899f1ec 100644
--- a/drivers/modem/quectel-bg9x.h
+++ b/drivers/modem/quectel-bg9x.h
@@ -15,6 +15,7 @@
#include <zephyr/init.h>
#include <zephyr/net/net_if.h>
+#include <zephyr/net/offloaded_netdev.h>
#include <zephyr/net/net_offload.h>
#include <zephyr/net/socket_offload.h>
diff --git a/drivers/modem/simcom-sim7080.c b/drivers/modem/simcom-sim7080.c
index f92a885..a9256d9 100644
--- a/drivers/modem/simcom-sim7080.c
+++ b/drivers/modem/simcom-sim7080.c
@@ -7,6 +7,7 @@
#define DT_DRV_COMPAT simcom_sim7080
#include <zephyr/logging/log.h>
+#include <zephyr/net/offloaded_netdev.h>
LOG_MODULE_REGISTER(modem_simcom_sim7080, CONFIG_MODEM_LOG_LEVEL);
#include <zephyr/drivers/modem/simcom-sim7080.h>
@@ -760,8 +761,8 @@
.freeaddrinfo = offload_freeaddrinfo,
};
-static struct net_if_api api_funcs = {
- .init = modem_net_iface_init,
+static struct offloaded_if_api api_funcs = {
+ .iface_api.init = modem_net_iface_init,
};
static bool offload_is_supported(int family, int type, int proto)
diff --git a/drivers/modem/ublox-sara-r4.c b/drivers/modem/ublox-sara-r4.c
index d1f3216..2958783 100644
--- a/drivers/modem/ublox-sara-r4.c
+++ b/drivers/modem/ublox-sara-r4.c
@@ -19,6 +19,7 @@
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_offload.h>
+#include <zephyr/net/offloaded_netdev.h>
#include <zephyr/net/socket_offload.h>
#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN)
@@ -2103,8 +2104,8 @@
net_if_socket_offload_set(iface, offload_socket);
}
-static struct net_if_api api_funcs = {
- .init = modem_net_iface_init,
+static struct offloaded_if_api api_funcs = {
+ .iface_api.init = modem_net_iface_init,
};
static const struct modem_cmd response_cmds[] = {
diff --git a/drivers/modem/wncm14a2a.c b/drivers/modem/wncm14a2a.c
index ca805a1..1dc0a73 100644
--- a/drivers/modem/wncm14a2a.c
+++ b/drivers/modem/wncm14a2a.c
@@ -25,6 +25,7 @@
#include <zephyr/net/net_context.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_offload.h>
+#include <zephyr/net/offloaded_netdev.h>
#include <zephyr/net/net_pkt.h>
#if defined(CONFIG_NET_IPV6)
#include "ipv6.h"
@@ -1773,8 +1774,8 @@
ctx->iface = iface;
}
-static struct net_if_api api_funcs = {
- .init = offload_iface_init,
+static struct offloaded_if_api api_funcs = {
+ .iface_api.init = offload_iface_init,
};
NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, wncm14a2a_init, NULL,
diff --git a/drivers/wifi/esp_at/esp.c b/drivers/wifi/esp_at/esp.c
index 4236c91..b1dcd9d 100644
--- a/drivers/wifi/esp_at/esp.c
+++ b/drivers/wifi/esp_at/esp.c
@@ -1217,13 +1217,13 @@
}
static const struct net_wifi_mgmt_offload esp_api = {
- .wifi_iface.init = esp_iface_init,
- .scan = esp_mgmt_scan,
- .connect = esp_mgmt_connect,
- .disconnect = esp_mgmt_disconnect,
- .ap_enable = esp_mgmt_ap_enable,
- .ap_disable = esp_mgmt_ap_disable,
- .iface_status = esp_mgmt_iface_status,
+ .wifi_iface.iface_api.init = esp_iface_init,
+ .scan = esp_mgmt_scan,
+ .connect = esp_mgmt_connect,
+ .disconnect = esp_mgmt_disconnect,
+ .ap_enable = esp_mgmt_ap_enable,
+ .ap_disable = esp_mgmt_ap_disable,
+ .iface_status = esp_mgmt_iface_status,
};
static int esp_init(const struct device *dev);
diff --git a/drivers/wifi/eswifi/eswifi_core.c b/drivers/wifi/eswifi/eswifi_core.c
index b6960ff..79e403c 100644
--- a/drivers/wifi/eswifi/eswifi_core.c
+++ b/drivers/wifi/eswifi/eswifi_core.c
@@ -679,12 +679,12 @@
}
static const struct net_wifi_mgmt_offload eswifi_offload_api = {
- .wifi_iface.init = eswifi_iface_init,
- .scan = eswifi_mgmt_scan,
- .connect = eswifi_mgmt_connect,
- .disconnect = eswifi_mgmt_disconnect,
- .ap_enable = eswifi_mgmt_ap_enable,
- .ap_disable = eswifi_mgmt_ap_disable,
+ .wifi_iface.iface_api.init = eswifi_iface_init,
+ .scan = eswifi_mgmt_scan,
+ .connect = eswifi_mgmt_connect,
+ .disconnect = eswifi_mgmt_disconnect,
+ .ap_enable = eswifi_mgmt_ap_enable,
+ .ap_disable = eswifi_mgmt_ap_disable,
};
NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, eswifi_init, NULL,
diff --git a/drivers/wifi/simplelink/simplelink.c b/drivers/wifi/simplelink/simplelink.c
index a60ac99..b75329e 100644
--- a/drivers/wifi/simplelink/simplelink.c
+++ b/drivers/wifi/simplelink/simplelink.c
@@ -264,10 +264,10 @@
}
static const struct net_wifi_mgmt_offload simplelink_api = {
- .wifi_iface.init = simplelink_iface_init,
- .scan = simplelink_mgmt_scan,
- .connect = simplelink_mgmt_connect,
- .disconnect = simplelink_mgmt_disconnect,
+ .wifi_iface.iface_api.init = simplelink_iface_init,
+ .scan = simplelink_mgmt_scan,
+ .connect = simplelink_mgmt_connect,
+ .disconnect = simplelink_mgmt_disconnect,
};
static int simplelink_init(const struct device *dev)
diff --git a/drivers/wifi/winc1500/wifi_winc1500.c b/drivers/wifi/winc1500/wifi_winc1500.c
index 94049a9..329e18a 100644
--- a/drivers/wifi/winc1500/wifi_winc1500.c
+++ b/drivers/wifi/winc1500/wifi_winc1500.c
@@ -1100,12 +1100,12 @@
}
static const struct net_wifi_mgmt_offload winc1500_api = {
- .wifi_iface.init = winc1500_iface_init,
- .scan = winc1500_mgmt_scan,
- .connect = winc1500_mgmt_connect,
- .disconnect = winc1500_mgmt_disconnect,
- .ap_enable = winc1500_mgmt_ap_enable,
- .ap_disable = winc1500_mgmt_ap_disable,
+ .wifi_iface.iface_api.init = winc1500_iface_init,
+ .scan = winc1500_mgmt_scan,
+ .connect = winc1500_mgmt_connect,
+ .disconnect = winc1500_mgmt_disconnect,
+ .ap_enable = winc1500_mgmt_ap_enable,
+ .ap_disable = winc1500_mgmt_ap_disable,
};
static int winc1500_init(const struct device *dev)
diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h
index 31928dd..58bf925 100644
--- a/include/zephyr/net/net_if.h
+++ b/include/zephyr/net/net_if.h
@@ -2468,6 +2468,7 @@
NET_IF_DEV_GET_NAME(dev_id, sfx)) = { \
.dev = &(DEVICE_NAME_GET(dev_id)), \
.mtu = _mtu, \
+ .l2 = &(NET_L2_GET_NAME(OFFLOADED_NETDEV)), \
}; \
static Z_DECL_ALIGN(struct net_if) \
NET_IF_GET_NAME(dev_id, sfx)[NET_IF_MAX_CONFIGS] \
diff --git a/include/zephyr/net/net_l2.h b/include/zephyr/net/net_l2.h
index 1c792cf..98ce34d 100644
--- a/include/zephyr/net/net_l2.h
+++ b/include/zephyr/net/net_l2.h
@@ -95,6 +95,11 @@
NET_L2_DECLARE_PUBLIC(DUMMY_L2);
#endif /* CONFIG_NET_L2_DUMMY */
+#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_SOCKETS_OFFLOAD)
+#define OFFLOADED_NETDEV_L2 OFFLOADED_NETDEV
+NET_L2_DECLARE_PUBLIC(OFFLOADED_NETDEV_L2);
+#endif /* CONFIG_NET_L2_ETHERNET */
+
#ifdef CONFIG_NET_L2_ETHERNET
#define ETHERNET_L2 ETHERNET
NET_L2_DECLARE_PUBLIC(ETHERNET_L2);
diff --git a/include/zephyr/net/offloaded_netdev.h b/include/zephyr/net/offloaded_netdev.h
new file mode 100644
index 0000000..5f77868
--- /dev/null
+++ b/include/zephyr/net/offloaded_netdev.h
@@ -0,0 +1,58 @@
+/** @file
+ * @brief Offloaded network device iface API
+ *
+ * This is not to be included by the application.
+ */
+
+/*
+ * Copyright (c) 2022 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef ZEPHYR_INCLUDE_OFFLOADED_NETDEV_H_
+#define ZEPHYR_INCLUDE_OFFLOADED_NETDEV_H_
+
+#include <zephyr/kernel.h>
+#include <zephyr/types.h>
+#include <stdbool.h>
+#include <zephyr/net/net_if.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Offloaded Net Devices
+ * @defgroup offloaded_netdev Offloaded Net Devices
+ * @ingroup networking
+ * @{
+ */
+
+/**
+ * @brief Extended net_if_api for offloaded ifaces/network devices, allowing handling of
+ * admin up/down state changes
+ */
+struct offloaded_if_api {
+ /**
+ * The net_if_api must be placed in first position in this
+ * struct so that we are compatible with network interface API.
+ */
+ struct net_if_api iface_api;
+
+ /** Enable or disable the device (in response to admin state change) */
+ int (*enable)(const struct net_if *iface, bool state);
+};
+
+/* Ensure offloaded_if_api is compatible with net_if_api */
+BUILD_ASSERT(offsetof(struct offloaded_if_api, iface_api) == 0);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZEPHYR_INCLUDE_OFFLOADED_NETDEV_H_ */
diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h
index 21282f0..b4538ec 100644
--- a/include/zephyr/net/wifi_mgmt.h
+++ b/include/zephyr/net/wifi_mgmt.h
@@ -15,6 +15,7 @@
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/wifi.h>
#include <zephyr/net/ethernet.h>
+#include <zephyr/net/offloaded_netdev.h>
#ifdef __cplusplus
extern "C" {
@@ -288,7 +289,7 @@
#ifdef CONFIG_WIFI_USE_NATIVE_NETWORKING
struct ethernet_api wifi_iface;
#else
- struct net_if_api wifi_iface;
+ struct offloaded_if_api wifi_iface;
#endif
/* cb parameter is the cb that should be called for each
diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c
index 1b6f5a6..aa94c5b 100644
--- a/subsys/net/ip/net_if.c
+++ b/subsys/net/ip/net_if.c
@@ -4202,10 +4202,6 @@
goto out;
}
- if (is_iface_offloaded(iface)) {
- goto done;
- }
-
/* If the L2 does not support enable just set the flag */
if (!net_if_l2(iface) || !net_if_l2(iface)->enable) {
goto done;
@@ -4246,10 +4242,6 @@
leave_mcast_all(iface);
leave_ipv4_mcast_all(iface);
- if (is_iface_offloaded(iface)) {
- goto done;
- }
-
/* If the L2 does not support enable just clear the flag */
if (!net_if_l2(iface) || !net_if_l2(iface)->enable) {
goto done;
diff --git a/subsys/net/l2/CMakeLists.txt b/subsys/net/l2/CMakeLists.txt
index 1878286..0d68a4e 100644
--- a/subsys/net/l2/CMakeLists.txt
+++ b/subsys/net/l2/CMakeLists.txt
@@ -12,6 +12,10 @@
add_subdirectory(dummy)
endif()
+if (CONFIG_NET_OFFLOAD OR CONFIG_NET_SOCKETS_OFFLOAD)
+ add_subdirectory(offloaded_netdev)
+endif()
+
if(CONFIG_NET_L2_ETHERNET)
add_subdirectory(ethernet)
endif()
diff --git a/subsys/net/l2/offloaded_netdev/CMakeLists.txt b/subsys/net/l2/offloaded_netdev/CMakeLists.txt
new file mode 100644
index 0000000..9cc64a7
--- /dev/null
+++ b/subsys/net/l2/offloaded_netdev/CMakeLists.txt
@@ -0,0 +1,5 @@
+# Copyright (c) 2022 Nordic Semiconductor ASA
+# SPDX-License-Identifier: Apache-2.0
+
+zephyr_library()
+zephyr_library_sources(offloaded_netdev.c)
diff --git a/subsys/net/l2/offloaded_netdev/offloaded_netdev.c b/subsys/net/l2/offloaded_netdev/offloaded_netdev.c
new file mode 100644
index 0000000..12fd3d0
--- /dev/null
+++ b/subsys/net/l2/offloaded_netdev/offloaded_netdev.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2022 Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <zephyr/net/net_l2.h>
+#include <zephyr/net/net_if.h>
+#include <zephyr/net/offloaded_netdev.h>
+
+static inline int offloaded_netdev_if_enable(struct net_if *iface, bool state)
+{
+ const struct offloaded_if_api *off_if = net_if_get_device(iface)->api;
+
+ if (!off_if || !(off_if->enable)) {
+ return 0;
+ }
+
+ return off_if->enable(iface, state);
+}
+
+NET_L2_INIT(OFFLOADED_NETDEV, NULL, NULL, offloaded_netdev_if_enable, NULL);
diff --git a/tests/net/all/src/main.c b/tests/net/all/src/main.c
index 83d5bfb..7e63508 100644
--- a/tests/net/all/src/main.c
+++ b/tests/net/all/src/main.c
@@ -18,23 +18,31 @@
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/dummy.h>
+#include <zephyr/net/offloaded_netdev.h>
+
+/* Create blank dummy and offloaded APIs */
+static struct offloaded_if_api offload_dev_api;
+static const struct dummy_api dummy_dev_api;
static struct offload_context {
void *none;
} offload_context_data = {
.none = NULL
};
-static struct dummy_api offload_if_api = {
- .iface_api.init = NULL,
- .send = NULL,
-};
+/* Create blank dummy and offloaded net devices */
+NET_DEVICE_INIT(dummy_dev, "dummy_dev",
+ NULL, NULL,
+ NULL, NULL,
+ CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
+ &dummy_dev_api,
+ DUMMY_L2, NET_L2_GET_CTX_TYPE(DUMMY_L2), 0);
NET_DEVICE_OFFLOAD_INIT(net_offload, "net_offload",
NULL, NULL,
&offload_context_data, NULL,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
- &offload_if_api, 0);
+ &offload_dev_api, 0);
ZTEST(net_compile_all_test, test_ok)
{
diff --git a/tests/net/socket/offload_dispatcher/src/main.c b/tests/net/socket/offload_dispatcher/src/main.c
index cf0d9f2..d6469c1 100644
--- a/tests/net/socket/offload_dispatcher/src/main.c
+++ b/tests/net/socket/offload_dispatcher/src/main.c
@@ -8,6 +8,7 @@
#include <zephyr/logging/log.h>
#include <zephyr/net/dummy.h>
#include <zephyr/net/net_if.h>
+#include <zephyr/net/offloaded_netdev.h>
#include <zephyr/net/socket.h>
#include <sockets_internal.h>
#include <zephyr/sys/fdtable.h>
@@ -306,8 +307,8 @@
net_if_socket_offload_set(iface, offload_1_socket);
}
-static struct net_if_api offloaded_1_if_api = {
- .init = offloaded_1_iface_init,
+static struct offloaded_if_api offloaded_1_if_api = {
+ .iface_api.init = offloaded_1_iface_init,
};
NET_DEVICE_OFFLOAD_INIT(offloaded_1, "offloaded_1", offloaded_1_init, NULL,
@@ -376,8 +377,8 @@
net_if_socket_offload_set(iface, offload_2_socket);
}
-static struct net_if_api offloaded_2_if_api = {
- .init = offloaded_2_iface_init,
+static struct offloaded_if_api offloaded_2_if_api = {
+ .iface_api.init = offloaded_2_iface_init,
};
NET_DEVICE_OFFLOAD_INIT(offloaded_2, "offloaded_2", offloaded_2_init, NULL,