1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006 |
- #ifndef ZEPHYR_INCLUDE_NET_ETHERNET_H_
- #define ZEPHYR_INCLUDE_NET_ETHERNET_H_
- #include <kernel.h>
- #include <zephyr/types.h>
- #include <stdbool.h>
- #include <sys/atomic.h>
- #include <net/net_ip.h>
- #include <net/net_pkt.h>
- #if defined(CONFIG_NET_LLDP)
- #include <net/lldp.h>
- #endif
- #include <sys/util.h>
- #include <net/net_if.h>
- #include <net/ethernet_vlan.h>
- #include <net/ptp_time.h>
- #if defined(CONFIG_NET_DSA)
- #include <net/dsa.h>
- #endif
- #if defined(CONFIG_NET_ETHERNET_BRIDGE)
- #include <net/ethernet_bridge.h>
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- struct net_eth_addr {
- uint8_t addr[6];
- };
- #define NET_ETH_HDR(pkt) ((struct net_eth_hdr *)net_pkt_data(pkt))
- #define NET_ETH_PTYPE_ARP 0x0806
- #define NET_ETH_PTYPE_IP 0x0800
- #define NET_ETH_PTYPE_TSN 0x22f0
- #define NET_ETH_PTYPE_IPV6 0x86dd
- #define NET_ETH_PTYPE_VLAN 0x8100
- #define NET_ETH_PTYPE_PTP 0x88f7
- #define NET_ETH_PTYPE_LLDP 0x88cc
- #define NET_ETH_PTYPE_ALL 0x0003
- #if !defined(ETH_P_ALL)
- #define ETH_P_ALL NET_ETH_PTYPE_ALL
- #endif
- #if !defined(ETH_P_IP)
- #define ETH_P_IP NET_ETH_PTYPE_IP
- #endif
- #if !defined(ETH_P_ARP)
- #define ETH_P_ARP NET_ETH_PTYPE_ARP
- #endif
- #if !defined(ETH_P_IPV6)
- #define ETH_P_IPV6 NET_ETH_PTYPE_IPV6
- #endif
- #if !defined(ETH_P_8021Q)
- #define ETH_P_8021Q NET_ETH_PTYPE_VLAN
- #endif
- #if !defined(ETH_P_TSN)
- #define ETH_P_TSN NET_ETH_PTYPE_TSN
- #endif
- #define NET_ETH_MINIMAL_FRAME_SIZE 60
- #define NET_ETH_MTU 1500
- #define _NET_ETH_MAX_FRAME_SIZE (NET_ETH_MTU + sizeof(struct net_eth_hdr))
- #define _NET_ETH_MAX_HDR_SIZE (sizeof(struct net_eth_hdr))
- #if defined(CONFIG_NET_DSA)
- #define NET_ETH_MAX_FRAME_SIZE (_NET_ETH_MAX_FRAME_SIZE + DSA_TAG_SIZE)
- #define NET_ETH_MAX_HDR_SIZE (_NET_ETH_MAX_HDR_SIZE + DSA_TAG_SIZE)
- #else
- #define NET_ETH_MAX_FRAME_SIZE (_NET_ETH_MAX_FRAME_SIZE)
- #define NET_ETH_MAX_HDR_SIZE (_NET_ETH_MAX_HDR_SIZE)
- #endif
- #define NET_ETH_VLAN_HDR_SIZE 4
- enum ethernet_hw_caps {
-
- ETHERNET_HW_TX_CHKSUM_OFFLOAD = BIT(0),
-
- ETHERNET_HW_RX_CHKSUM_OFFLOAD = BIT(1),
-
- ETHERNET_HW_VLAN = BIT(2),
-
- ETHERNET_AUTO_NEGOTIATION_SET = BIT(3),
-
- ETHERNET_LINK_10BASE_T = BIT(4),
-
- ETHERNET_LINK_100BASE_T = BIT(5),
-
- ETHERNET_LINK_1000BASE_T = BIT(6),
-
- ETHERNET_DUPLEX_SET = BIT(7),
-
- ETHERNET_PTP = BIT(8),
-
- ETHERNET_QAV = BIT(9),
-
- ETHERNET_PROMISC_MODE = BIT(10),
-
- ETHERNET_PRIORITY_QUEUES = BIT(11),
-
- ETHERNET_HW_FILTERING = BIT(12),
-
- ETHERNET_LLDP = BIT(13),
-
- ETHERNET_HW_VLAN_TAG_STRIP = BIT(14),
-
- ETHERNET_DSA_SLAVE_PORT = BIT(15),
- ETHERNET_DSA_MASTER_PORT = BIT(16),
-
- ETHERNET_QBV = BIT(17),
-
- ETHERNET_QBU = BIT(18),
-
- ETHERNET_TXTIME = BIT(19),
- };
- enum ethernet_config_type {
- ETHERNET_CONFIG_TYPE_AUTO_NEG,
- ETHERNET_CONFIG_TYPE_LINK,
- ETHERNET_CONFIG_TYPE_DUPLEX,
- ETHERNET_CONFIG_TYPE_MAC_ADDRESS,
- ETHERNET_CONFIG_TYPE_QAV_PARAM,
- ETHERNET_CONFIG_TYPE_QBV_PARAM,
- ETHERNET_CONFIG_TYPE_QBU_PARAM,
- ETHERNET_CONFIG_TYPE_TXTIME_PARAM,
- ETHERNET_CONFIG_TYPE_PROMISC_MODE,
- ETHERNET_CONFIG_TYPE_PRIORITY_QUEUES_NUM,
- ETHERNET_CONFIG_TYPE_FILTER,
- ETHERNET_CONFIG_TYPE_PORTS_NUM,
- };
- enum ethernet_qav_param_type {
- ETHERNET_QAV_PARAM_TYPE_DELTA_BANDWIDTH,
- ETHERNET_QAV_PARAM_TYPE_IDLE_SLOPE,
- ETHERNET_QAV_PARAM_TYPE_OPER_IDLE_SLOPE,
- ETHERNET_QAV_PARAM_TYPE_TRAFFIC_CLASS,
- ETHERNET_QAV_PARAM_TYPE_STATUS,
- };
- struct ethernet_qav_param {
-
- int queue_id;
-
- enum ethernet_qav_param_type type;
- union {
-
- bool enabled;
-
- unsigned int delta_bandwidth;
-
- unsigned int idle_slope;
-
- unsigned int oper_idle_slope;
-
- unsigned int traffic_class;
- };
- };
- enum ethernet_qbv_param_type {
- ETHERNET_QBV_PARAM_TYPE_STATUS,
- ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST,
- ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST_LEN,
- ETHERNET_QBV_PARAM_TYPE_TIME,
- };
- enum ethernet_qbv_state_type {
- ETHERNET_QBV_STATE_TYPE_ADMIN,
- ETHERNET_QBV_STATE_TYPE_OPER,
- };
- enum ethernet_gate_state_operation {
- ETHERNET_SET_GATE_STATE,
- ETHERNET_SET_AND_HOLD_MAC_STATE,
- ETHERNET_SET_AND_RELEASE_MAC_STATE,
- };
- struct ethernet_qbv_param {
-
- int port_id;
-
- enum ethernet_qbv_param_type type;
-
- enum ethernet_qbv_state_type state;
- union {
-
- bool enabled;
- struct {
-
- bool gate_status[NET_TC_TX_COUNT];
-
- enum ethernet_gate_state_operation operation;
-
- uint32_t time_interval;
-
- uint16_t row;
- } gate_control;
-
- uint32_t gate_control_list_len;
-
- struct {
-
- struct net_ptp_extended_time base_time;
-
- struct net_ptp_time cycle_time;
-
- uint32_t extension_time;
- };
- };
- };
- enum ethernet_qbu_param_type {
- ETHERNET_QBU_PARAM_TYPE_STATUS,
- ETHERNET_QBU_PARAM_TYPE_RELEASE_ADVANCE,
- ETHERNET_QBU_PARAM_TYPE_HOLD_ADVANCE,
- ETHERNET_QBU_PARAM_TYPE_PREEMPTION_STATUS_TABLE,
-
- ETHERNET_QBR_PARAM_TYPE_LINK_PARTNER_STATUS,
- ETHERNET_QBR_PARAM_TYPE_ADDITIONAL_FRAGMENT_SIZE,
- };
- enum ethernet_qbu_preempt_status {
- ETHERNET_QBU_STATUS_EXPRESS,
- ETHERNET_QBU_STATUS_PREEMPTABLE
- } __packed;
- struct ethernet_qbu_param {
-
- int port_id;
-
- enum ethernet_qbu_param_type type;
- union {
-
- uint32_t hold_advance;
-
- uint32_t release_advance;
-
- enum ethernet_qbu_preempt_status
- frame_preempt_statuses[NET_TC_TX_COUNT];
-
- bool enabled;
-
- bool link_partner_status;
-
- uint8_t additional_fragment_size : 2;
- };
- };
- enum ethernet_filter_type {
- ETHERNET_FILTER_TYPE_SRC_MAC_ADDRESS,
- ETHERNET_FILTER_TYPE_DST_MAC_ADDRESS,
- };
- struct ethernet_filter {
-
- enum ethernet_filter_type type;
-
- struct net_eth_addr mac_address;
-
- bool set;
- };
- enum ethernet_txtime_param_type {
- ETHERNET_TXTIME_PARAM_TYPE_ENABLE_QUEUES,
- };
- struct ethernet_txtime_param {
-
- enum ethernet_txtime_param_type type;
-
- int queue_id;
-
- bool enable_txtime;
- };
- struct ethernet_config {
- union {
- bool auto_negotiation;
- bool full_duplex;
- bool promisc_mode;
- struct {
- bool link_10bt;
- bool link_100bt;
- bool link_1000bt;
- } l;
- struct net_eth_addr mac_address;
- struct ethernet_qav_param qav_param;
- struct ethernet_qbv_param qbv_param;
- struct ethernet_qbu_param qbu_param;
- struct ethernet_txtime_param txtime_param;
- int priority_queues_num;
- int ports_num;
- struct ethernet_filter filter;
- };
- };
- struct ethernet_api {
-
- struct net_if_api iface_api;
- #if defined(CONFIG_NET_STATISTICS_ETHERNET)
-
- struct net_stats_eth *(*get_stats)(const struct device *dev);
- #endif
-
- int (*start)(const struct device *dev);
-
- int (*stop)(const struct device *dev);
-
- enum ethernet_hw_caps (*get_capabilities)(const struct device *dev);
-
- int (*set_config)(const struct device *dev,
- enum ethernet_config_type type,
- const struct ethernet_config *config);
-
- int (*get_config)(const struct device *dev,
- enum ethernet_config_type type,
- struct ethernet_config *config);
- #if defined(CONFIG_NET_VLAN)
-
- int (*vlan_setup)(const struct device *dev, struct net_if *iface,
- uint16_t tag, bool enable);
- #endif
- #if defined(CONFIG_PTP_CLOCK)
-
- const struct device *(*get_ptp_clock)(const struct device *dev);
- #endif
-
- int (*send)(const struct device *dev, struct net_pkt *pkt);
- };
- BUILD_ASSERT(offsetof(struct ethernet_api, iface_api) == 0);
- struct net_eth_hdr {
- struct net_eth_addr dst;
- struct net_eth_addr src;
- uint16_t type;
- } __packed;
- struct ethernet_vlan {
-
- struct net_if *iface;
-
- uint16_t tag;
- };
- #if defined(CONFIG_NET_VLAN_COUNT)
- #define NET_VLAN_MAX_COUNT CONFIG_NET_VLAN_COUNT
- #else
- #define NET_VLAN_MAX_COUNT 1
- #endif
- #if defined(CONFIG_NET_LLDP)
- struct ethernet_lldp {
-
- sys_snode_t node;
-
- const struct net_lldpdu *lldpdu;
-
- const uint8_t *optional_du;
-
- size_t optional_len;
-
- struct net_if *iface;
-
- int64_t tx_timer_start;
-
- uint32_t tx_timer_timeout;
-
- net_lldp_recv_cb_t cb;
- };
- #endif
- enum ethernet_flags {
- ETH_CARRIER_UP,
- };
- struct ethernet_context {
-
- atomic_t flags;
- #if defined(CONFIG_NET_VLAN)
- struct ethernet_vlan vlan[NET_VLAN_MAX_COUNT];
-
- ATOMIC_DEFINE(interfaces, NET_VLAN_MAX_COUNT);
- #endif
- #if defined(CONFIG_NET_ETHERNET_BRIDGE)
- struct eth_bridge_iface_context bridge;
- #endif
-
- struct k_work carrier_work;
-
- struct net_if *iface;
- #if defined(CONFIG_NET_LLDP)
- struct ethernet_lldp lldp[NET_VLAN_MAX_COUNT];
- #endif
-
- enum net_l2_flags ethernet_l2_flags;
- #if defined(CONFIG_NET_GPTP)
-
- int port;
- #endif
- #if defined(CONFIG_NET_DSA)
-
- dsa_net_recv_cb_t dsa_recv_cb;
-
- uint8_t dsa_port_idx;
-
- struct dsa_context *dsa_ctx;
-
- dsa_send_t dsa_send;
- #endif
- #if defined(CONFIG_NET_VLAN)
-
- int8_t vlan_enabled;
- #endif
-
- bool is_net_carrier_up : 1;
-
- bool is_init : 1;
- };
- void ethernet_init(struct net_if *iface);
- #define ETHERNET_L2_CTX_TYPE struct ethernet_context
- struct net_eth_vlan_hdr {
- struct net_eth_addr dst;
- struct net_eth_addr src;
- struct {
- uint16_t tpid;
- uint16_t tci;
- } vlan;
- uint16_t type;
- } __packed;
- static inline bool net_eth_is_addr_broadcast(struct net_eth_addr *addr)
- {
- if (addr->addr[0] == 0xff &&
- addr->addr[1] == 0xff &&
- addr->addr[2] == 0xff &&
- addr->addr[3] == 0xff &&
- addr->addr[4] == 0xff &&
- addr->addr[5] == 0xff) {
- return true;
- }
- return false;
- }
- static inline bool net_eth_is_addr_unspecified(struct net_eth_addr *addr)
- {
- if (addr->addr[0] == 0x00 &&
- addr->addr[1] == 0x00 &&
- addr->addr[2] == 0x00 &&
- addr->addr[3] == 0x00 &&
- addr->addr[4] == 0x00 &&
- addr->addr[5] == 0x00) {
- return true;
- }
- return false;
- }
- static inline bool net_eth_is_addr_multicast(struct net_eth_addr *addr)
- {
- #if defined(CONFIG_NET_IPV6)
- if (addr->addr[0] == 0x33 &&
- addr->addr[1] == 0x33) {
- return true;
- }
- #endif
- #if defined(CONFIG_NET_IPV4)
- if (addr->addr[0] == 0x01 &&
- addr->addr[1] == 0x00 &&
- addr->addr[2] == 0x5e) {
- return true;
- }
- #endif
- return false;
- }
- static inline bool net_eth_is_addr_lldp_multicast(struct net_eth_addr *addr)
- {
- #if defined(CONFIG_NET_GPTP) || defined(CONFIG_NET_LLDP)
- if (addr->addr[0] == 0x01 &&
- addr->addr[1] == 0x80 &&
- addr->addr[2] == 0xc2 &&
- addr->addr[3] == 0x00 &&
- addr->addr[4] == 0x00 &&
- addr->addr[5] == 0x0e) {
- return true;
- }
- #endif
- return false;
- }
- const struct net_eth_addr *net_eth_broadcast_addr(void);
- void net_eth_ipv4_mcast_to_mac_addr(const struct in_addr *ipv4_addr,
- struct net_eth_addr *mac_addr);
- void net_eth_ipv6_mcast_to_mac_addr(const struct in6_addr *ipv6_addr,
- struct net_eth_addr *mac_addr);
- static inline
- enum ethernet_hw_caps net_eth_get_hw_capabilities(struct net_if *iface)
- {
- const struct ethernet_api *eth =
- (struct ethernet_api *)net_if_get_device(iface)->api;
- if (!eth->get_capabilities) {
- return (enum ethernet_hw_caps)0;
- }
- return eth->get_capabilities(net_if_get_device(iface));
- }
- #if defined(CONFIG_NET_VLAN)
- int net_eth_vlan_enable(struct net_if *iface, uint16_t tag);
- #else
- static inline int net_eth_vlan_enable(struct net_if *iface, uint16_t tag)
- {
- return -EINVAL;
- }
- #endif
- #if defined(CONFIG_NET_VLAN)
- int net_eth_vlan_disable(struct net_if *iface, uint16_t tag);
- #else
- static inline int net_eth_vlan_disable(struct net_if *iface, uint16_t tag)
- {
- return -EINVAL;
- }
- #endif
- #if defined(CONFIG_NET_VLAN)
- uint16_t net_eth_get_vlan_tag(struct net_if *iface);
- #else
- static inline uint16_t net_eth_get_vlan_tag(struct net_if *iface)
- {
- return NET_VLAN_TAG_UNSPEC;
- }
- #endif
- #if defined(CONFIG_NET_VLAN)
- struct net_if *net_eth_get_vlan_iface(struct net_if *iface, uint16_t tag);
- #else
- static inline
- struct net_if *net_eth_get_vlan_iface(struct net_if *iface, uint16_t tag)
- {
- return NULL;
- }
- #endif
- #if defined(CONFIG_NET_VLAN)
- bool net_eth_is_vlan_enabled(struct ethernet_context *ctx,
- struct net_if *iface);
- #else
- static inline bool net_eth_is_vlan_enabled(struct ethernet_context *ctx,
- struct net_if *iface)
- {
- return false;
- }
- #endif
- #if defined(CONFIG_NET_VLAN)
- bool net_eth_get_vlan_status(struct net_if *iface);
- #else
- static inline bool net_eth_get_vlan_status(struct net_if *iface)
- {
- return false;
- }
- #endif
- #if defined(CONFIG_NET_VLAN)
- #define Z_ETH_NET_DEVICE_INIT(node_id, dev_name, drv_name, init_fn, \
- pm_control_fn, data, cfg, prio, api, mtu) \
- Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, \
- pm_control_fn, data, cfg, POST_KERNEL, \
- prio, api); \
- NET_L2_DATA_INIT(dev_name, 0, NET_L2_GET_CTX_TYPE(ETHERNET_L2));\
- NET_IF_INIT(dev_name, 0, ETHERNET_L2, mtu, NET_VLAN_MAX_COUNT)
- #else
- #define Z_ETH_NET_DEVICE_INIT(node_id, dev_name, drv_name, init_fn, \
- pm_control_fn, data, cfg, prio, api, mtu) \
- Z_NET_DEVICE_INIT(node_id, dev_name, drv_name, init_fn, \
- pm_control_fn, data, cfg, prio, api, \
- ETHERNET_L2, NET_L2_GET_CTX_TYPE(ETHERNET_L2),\
- mtu)
- #endif
- #define ETH_NET_DEVICE_INIT(dev_name, drv_name, init_fn, pm_control_fn, \
- data, cfg, prio, api, mtu) \
- Z_ETH_NET_DEVICE_INIT(DT_INVALID_NODE, dev_name, drv_name, \
- init_fn, pm_control_fn, data, cfg, prio, \
- api, mtu)
- #define ETH_NET_DEVICE_DT_DEFINE(node_id, init_fn, pm_control_fn, data, \
- cfg, prio, api, mtu) \
- Z_ETH_NET_DEVICE_INIT(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
- DT_PROP_OR(node_id, label, ""), \
- init_fn, pm_control_fn, data, cfg, prio, \
- api, mtu)
- #define ETH_NET_DEVICE_DT_INST_DEFINE(inst, ...) \
- ETH_NET_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
- void net_eth_carrier_on(struct net_if *iface);
- void net_eth_carrier_off(struct net_if *iface);
- int net_eth_promisc_mode(struct net_if *iface, bool enable);
- #if defined(CONFIG_PTP_CLOCK)
- const struct device *net_eth_get_ptp_clock(struct net_if *iface);
- #else
- static inline const struct device *net_eth_get_ptp_clock(struct net_if *iface)
- {
- ARG_UNUSED(iface);
- return NULL;
- }
- #endif
- __syscall const struct device *net_eth_get_ptp_clock_by_index(int index);
- #if defined(CONFIG_NET_GPTP)
- int net_eth_get_ptp_port(struct net_if *iface);
- #else
- static inline int net_eth_get_ptp_port(struct net_if *iface)
- {
- ARG_UNUSED(iface);
- return -ENODEV;
- }
- #endif
- #if defined(CONFIG_NET_GPTP)
- void net_eth_set_ptp_port(struct net_if *iface, int port);
- #endif
- #ifdef __cplusplus
- }
- #endif
- #include <syscalls/ethernet.h>
- #endif
|