1 /*
2  * Copyright 2022-2023 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_DRIVERS_ETHERNET_ETH_NXP_S32_NETC_PRIV_H_
8 #define ZEPHYR_DRIVERS_ETHERNET_ETH_NXP_S32_NETC_PRIV_H_
9 
10 #define NETC_F3_PSICFGR0_SIVC_CVLAN_BIT	BIT(0)	/* 0x8100 */
11 #define NETC_F3_PSICFGR0_SIVC_SVLAN_BIT	BIT(1)	/* 0x88A8 */
12 
13 #define NETC_MIN_RING_LEN	8U
14 #define NETC_MIN_RING_BUF_SIZE	64U
15 
16 #define NETC_SWITCH_IDX		0U
17 #define NETC_SWITCH_PORT_IDX	0U
18 #define NETC_SWITCH_PORT_AGING	300U
19 #define NETC_ETH_0_RX_CLK_IDX	49U
20 #define NETC_ETH_1_RX_CLK_IDX	51U
21 
22 #define NETC_MSIX_EVENTS_COUNT	2U
23 
24 /* Timeout for various operations */
25 #define NETC_TIMEOUT		K_MSEC(20)
26 
27 /* Helper macros to convert from Zephyr PHY speed to NETC baudrate/duplex types */
28 #define PHY_TO_NETC_SPEED(x) \
29 	(PHY_LINK_IS_SPEED_1000M(x) ? ETHTRCV_BAUD_RATE_1000MBIT : \
30 		(PHY_LINK_IS_SPEED_100M(x) ? ETHTRCV_BAUD_RATE_100MBIT : ETHTRCV_BAUD_RATE_10MBIT))
31 
32 #define PHY_TO_NETC_DUPLEX_MODE(x) \
33 	(PHY_LINK_IS_FULL_DUPLEX(x) ? NETC_ETHSWT_PORT_FULL_DUPLEX : NETC_ETHSWT_PORT_HALF_DUPLEX)
34 
35 /*
36  * Get the first MRU mailbox address for an specific mbox handle
37  * mbox[0] addr = MRU base addr + (channel × channel offset), with channel=1..N
38  */
39 #define MRU_CHANNEL_OFFSET	0x1000
40 #define MRU_MBOX_ADDR(node, name)						\
41 	(DT_REG_ADDR(DT_MBOX_CTLR_BY_NAME(node, name))				\
42 	 + ((DT_MBOX_CHANNEL_BY_NAME(node, name) + 1) * MRU_CHANNEL_OFFSET))
43 
44 #define NETC_MSIX(node, name, cb)					\
45 	{								\
46 		.handler = cb,						\
47 		.mbox_channel = MBOX_DT_CHANNEL_GET(node, name),	\
48 	}
49 
50 /* Tx/Rx ENETC ring definitions */
51 #define _NETC_RING(n, idx, len, buf_size, prefix1, prefix2)					\
52 	static Netc_Eth_Ip_##prefix1##BDRType nxp_s32_eth##n##_##prefix2##ring##idx##_desc[len]	\
53 		__nocache __aligned(FEATURE_NETC_BUFFDESCR_ALIGNMENT_BYTES);			\
54 	static uint8_t nxp_s32_eth##n##_##prefix2##ring##idx##_buf[len * buf_size]		\
55 		__nocache __aligned(FEATURE_NETC_BUFF_ALIGNMENT_BYTES)
56 
57 #define NETC_RX_RING(n, idx, len, buf_size)	_NETC_RING(n, idx, len, buf_size, Rx, rx)
58 #define NETC_TX_RING(n, idx, len, buf_size)	_NETC_RING(n, idx, len, buf_size, Tx, tx)
59 
60 /* Helper function to generate an Ethernet MAC address for a given ENETC instance */
61 #define FREESCALE_OUI_B0 0x00
62 #define FREESCALE_OUI_B1 0x04
63 #define FREESCALE_OUI_B2 0x9f
64 
65 #define _NETC_GENERATE_MAC_ADDRESS_RANDOM	\
66 	gen_random_mac(mac_addr, FREESCALE_OUI_B0, FREESCALE_OUI_B1, FREESCALE_OUI_B2)
67 
68 #define _NETC_GENERATE_MAC_ADDRESS_UNIQUE(n)				\
69 	do {								\
70 		uint32_t id = 0x001100;					\
71 									\
72 		mac_addr[0] = FREESCALE_OUI_B0;				\
73 		mac_addr[1] = FREESCALE_OUI_B1;				\
74 		/* Set MAC address locally administered bit (LAA) */	\
75 		mac_addr[2] = FREESCALE_OUI_B2 | 0x02;			\
76 		mac_addr[3] = (id >> 16) & 0xff;			\
77 		mac_addr[4] = (id >> 8) & 0xff;				\
78 		mac_addr[5] = (id + n) & 0xff;				\
79 	} while (0)
80 
81 #define NETC_GENERATE_MAC_ADDRESS(n)						\
82 	static void nxp_s32_eth##n##_generate_mac(uint8_t mac_addr[6])		\
83 	{									\
84 		COND_CODE_1(DT_INST_PROP(n, zephyr_random_mac_address),		\
85 			(_NETC_GENERATE_MAC_ADDRESS_RANDOM),			\
86 			(COND_CODE_0(DT_INST_NODE_HAS_PROP(n, local_mac_address),\
87 				(_NETC_GENERATE_MAC_ADDRESS_UNIQUE(n)),		\
88 				(ARG_UNUSED(mac_addr)))));			\
89 	}
90 
91 #define NETC_SI_NXP_S32_HW_INSTANCE_CHECK(i, n) \
92 	((DT_INST_REG_ADDR(n) == IP_NETC__ENETC0_SI##i##_BASE) ? i : 0)
93 
94 #define NETC_SI_NXP_S32_HW_INSTANCE(n)					\
95 	LISTIFY(__DEBRACKET FEATURE_NETC_ETH_NUMBER_OF_CTRLS,		\
96 			NETC_SI_NXP_S32_HW_INSTANCE_CHECK, (|), n)
97 
98 /* Helper macros to concatenate tokens that require further expansions */
99 #define _CONCAT3(a, b, c)	DT_CAT3(a, b, c)
100 
101 struct nxp_s32_eth_msix {
102 	void (*handler)(uint8_t chan, const uint32_t *buf, uint8_t buf_size);
103 	struct mbox_channel mbox_channel;
104 };
105 
106 struct nxp_s32_eth_config {
107 	const Netc_Eth_Ip_ConfigType netc_cfg;
108 
109 	Netc_Eth_Ip_MACFilterHashTableEntryType *mac_filter_hash_table;
110 
111 	uint8_t si_idx;
112 	uint8_t port_idx;
113 	const struct device *phy_dev;
114 	uint8_t tx_ring_idx;
115 	uint8_t rx_ring_idx;
116 	void (*generate_mac)(uint8_t *mac_addr);
117 	struct nxp_s32_eth_msix msix[NETC_MSIX_EVENTS_COUNT];
118 	const struct pinctrl_dev_config *pincfg;
119 };
120 
121 struct nxp_s32_eth_data {
122 	struct net_if *iface;
123 	uint8_t mac_addr[6];
124 	struct k_mutex tx_mutex;
125 	struct k_sem rx_sem;
126 	struct k_thread rx_thread;
127 
128 	K_KERNEL_STACK_MEMBER(rx_thread_stack, CONFIG_ETH_NXP_S32_RX_THREAD_STACK_SIZE);
129 };
130 
131 int nxp_s32_eth_initialize_common(const struct device *dev);
132 int nxp_s32_eth_tx(const struct device *dev, struct net_pkt *pkt);
133 enum ethernet_hw_caps nxp_s32_eth_get_capabilities(const struct device *dev);
134 void nxp_s32_eth_mcast_cb(struct net_if *iface, const struct net_addr *addr, bool is_joined);
135 int nxp_s32_eth_set_config(const struct device *dev, enum ethernet_config_type type,
136 			   const struct ethernet_config *config);
137 extern void Netc_Eth_Ip_MSIX_Rx(uint8_t si_idx);
138 
139 #endif /* ZEPHYR_DRIVERS_ETHERNET_ETH_NXP_S32_NETC_PRIV_H_ */
140