xref: /dpdk/drivers/net/sfc/sfc.h (revision 0d09cbc7)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2020 Xilinx, Inc.
4  * Copyright(c) 2016-2019 Solarflare Communications Inc.
5  *
6  * This software was jointly developed between OKTET Labs (under contract
7  * for Solarflare) and Solarflare Communications, Inc.
8  */
9 
10 #ifndef _SFC_H
11 #define _SFC_H
12 
13 #include <stdbool.h>
14 
15 #include <rte_pci.h>
16 #include <rte_bus_pci.h>
17 #include <rte_ethdev_driver.h>
18 #include <rte_kvargs.h>
19 #include <rte_spinlock.h>
20 #include <rte_atomic.h>
21 
22 #include "efx.h"
23 
24 #include "sfc_efx_mcdi.h"
25 
26 #include "sfc_debug.h"
27 #include "sfc_log.h"
28 #include "sfc_filter.h"
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /*
35  * +---------------+
36  * | UNINITIALIZED |<-----------+
37  * +---------------+		|
38  *	|.eth_dev_init		|.eth_dev_uninit
39  *	V			|
40  * +---------------+------------+
41  * |  INITIALIZED  |
42  * +---------------+<-----------<---------------+
43  *	|.dev_configure		|		|
44  *	V			|failed		|
45  * +---------------+------------+		|
46  * |  CONFIGURING  |				|
47  * +---------------+----+			|
48  *	|success	|			|
49  *	|		|		+---------------+
50  *	|		|		|    CLOSING    |
51  *	|		|		+---------------+
52  *	|		|			^
53  *	V		|.dev_configure		|
54  * +---------------+----+			|.dev_close
55  * |  CONFIGURED   |----------------------------+
56  * +---------------+<-----------+
57  *	|.dev_start		|
58  *	V			|
59  * +---------------+		|
60  * |   STARTING    |------------^
61  * +---------------+ failed	|
62  *	|success		|
63  *	|		+---------------+
64  *	|		|   STOPPING    |
65  *	|		+---------------+
66  *	|			^
67  *	V			|.dev_stop
68  * +---------------+------------+
69  * |    STARTED    |
70  * +---------------+
71  */
72 enum sfc_adapter_state {
73 	SFC_ADAPTER_UNINITIALIZED = 0,
74 	SFC_ADAPTER_INITIALIZED,
75 	SFC_ADAPTER_CONFIGURING,
76 	SFC_ADAPTER_CONFIGURED,
77 	SFC_ADAPTER_CLOSING,
78 	SFC_ADAPTER_STARTING,
79 	SFC_ADAPTER_STARTED,
80 	SFC_ADAPTER_STOPPING,
81 
82 	SFC_ADAPTER_NSTATES
83 };
84 
85 enum sfc_dev_filter_mode {
86 	SFC_DEV_FILTER_MODE_PROMISC = 0,
87 	SFC_DEV_FILTER_MODE_ALLMULTI,
88 
89 	SFC_DEV_FILTER_NMODES
90 };
91 
92 struct sfc_intr {
93 	efx_intr_type_t			type;
94 	rte_intr_callback_fn		handler;
95 	boolean_t			lsc_intr;
96 	boolean_t			rxq_intr;
97 };
98 
99 struct sfc_rxq;
100 struct sfc_txq;
101 
102 struct sfc_rxq_info;
103 struct sfc_txq_info;
104 struct sfc_dp_rx;
105 
106 struct sfc_port {
107 	unsigned int			lsc_seq;
108 
109 	uint32_t			phy_adv_cap_mask;
110 	uint32_t			phy_adv_cap;
111 
112 	unsigned int			flow_ctrl;
113 	boolean_t			flow_ctrl_autoneg;
114 	size_t				pdu;
115 
116 	/*
117 	 * Flow API isolated mode overrides promisc and allmulti settings;
118 	 * they won't be applied if isolated mode is active
119 	 */
120 	boolean_t			promisc;
121 	boolean_t			allmulti;
122 
123 	struct rte_ether_addr		default_mac_addr;
124 
125 	unsigned int			max_mcast_addrs;
126 	unsigned int			nb_mcast_addrs;
127 	uint8_t				*mcast_addrs;
128 
129 	rte_spinlock_t			mac_stats_lock;
130 	uint64_t			*mac_stats_buf;
131 	unsigned int			mac_stats_nb_supported;
132 	efsys_mem_t			mac_stats_dma_mem;
133 	boolean_t			mac_stats_reset_pending;
134 	uint16_t			mac_stats_update_period_ms;
135 	uint32_t			mac_stats_update_generation;
136 	boolean_t			mac_stats_periodic_dma_supported;
137 	uint64_t			mac_stats_last_request_timestamp;
138 
139 	uint32_t		mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES];
140 
141 	uint64_t			ipackets;
142 };
143 
144 struct sfc_rss_hf_rte_to_efx {
145 	uint64_t			rte;
146 	efx_rx_hash_type_t		efx;
147 };
148 
149 struct sfc_rss {
150 	unsigned int			channels;
151 	efx_rx_scale_context_type_t	context_type;
152 	efx_rx_hash_support_t		hash_support;
153 	efx_rx_hash_alg_t		hash_alg;
154 	unsigned int			hf_map_nb_entries;
155 	struct sfc_rss_hf_rte_to_efx	*hf_map;
156 
157 	efx_rx_hash_type_t		hash_types;
158 	unsigned int			tbl[EFX_RSS_TBL_SIZE];
159 	uint8_t				key[EFX_RSS_KEY_SIZE];
160 };
161 
162 /* Adapter private data shared by primary and secondary processes */
163 struct sfc_adapter_shared {
164 	unsigned int			rxq_count;
165 	struct sfc_rxq_info		*rxq_info;
166 
167 	unsigned int			txq_count;
168 	struct sfc_txq_info		*txq_info;
169 
170 	struct sfc_rss			rss;
171 
172 	boolean_t			isolated;
173 	uint32_t			tunnel_encaps;
174 
175 	char				log_prefix[SFC_LOG_PREFIX_MAX];
176 	struct rte_pci_addr		pci_addr;
177 	uint16_t			port_id;
178 
179 	char				*dp_rx_name;
180 	char				*dp_tx_name;
181 };
182 
183 /* Adapter process private data */
184 struct sfc_adapter_priv {
185 	struct sfc_adapter_shared	*shared;
186 	const struct sfc_dp_rx		*dp_rx;
187 	const struct sfc_dp_tx		*dp_tx;
188 	uint32_t			logtype_main;
189 };
190 
191 static inline struct sfc_adapter_priv *
192 sfc_adapter_priv_by_eth_dev(struct rte_eth_dev *eth_dev)
193 {
194 	struct sfc_adapter_priv *sap = eth_dev->process_private;
195 
196 	SFC_ASSERT(sap != NULL);
197 	return sap;
198 }
199 
200 /* Adapter private data */
201 struct sfc_adapter {
202 	/*
203 	 * It must be the first field of the sfc_adapter structure since
204 	 * sfc_adapter is the primary process private data (i.e.  process
205 	 * private data plus additional primary process specific data).
206 	 */
207 	struct sfc_adapter_priv		priv;
208 
209 	/*
210 	 * PMD setup and configuration is not thread safe. Since it is not
211 	 * performance sensitive, it is better to guarantee thread-safety
212 	 * and add device level lock. Adapter control operations which
213 	 * change its state should acquire the lock.
214 	 */
215 	rte_spinlock_t			lock;
216 	enum sfc_adapter_state		state;
217 	struct rte_eth_dev		*eth_dev;
218 	struct rte_kvargs		*kvargs;
219 	int				socket_id;
220 	efsys_bar_t			mem_bar;
221 	efx_family_t			family;
222 	efx_nic_t			*nic;
223 	rte_spinlock_t			nic_lock;
224 	rte_atomic32_t			restart_required;
225 
226 	struct sfc_efx_mcdi		mcdi;
227 	struct sfc_intr			intr;
228 	struct sfc_port			port;
229 	struct sfc_filter		filter;
230 
231 	struct sfc_flow_list		flow_list;
232 
233 	unsigned int			rxq_max;
234 	unsigned int			txq_max;
235 
236 	unsigned int			rxq_max_entries;
237 	unsigned int			rxq_min_entries;
238 
239 	unsigned int			txq_max_entries;
240 	unsigned int			txq_min_entries;
241 
242 	unsigned int			evq_max_entries;
243 	unsigned int			evq_min_entries;
244 
245 	uint32_t			evq_flags;
246 	unsigned int			evq_count;
247 
248 	unsigned int			mgmt_evq_index;
249 	/*
250 	 * The lock is used to serialise management event queue polling
251 	 * which can be done from different context. Also the lock
252 	 * guarantees that mgmt_evq_running is preserved while the lock
253 	 * is held. It is used to serialise polling and start/stop
254 	 * operations.
255 	 *
256 	 * Locks which may be held when the lock is acquired:
257 	 *  - adapter lock, when:
258 	 *    - device start/stop to change mgmt_evq_running
259 	 *    - any control operations in client side MCDI proxy handling to
260 	 *	poll management event queue waiting for proxy response
261 	 *  - MCDI lock, when:
262 	 *    - any control operations in client side MCDI proxy handling to
263 	 *	poll management event queue waiting for proxy response
264 	 *
265 	 * Locks which are acquired with the lock held:
266 	 *  - nic_lock, when:
267 	 *    - MC event processing on management event queue polling
268 	 *	(e.g. MC REBOOT or BADASSERT events)
269 	 */
270 	rte_spinlock_t			mgmt_evq_lock;
271 	bool				mgmt_evq_running;
272 	struct sfc_evq			*mgmt_evq;
273 
274 	struct sfc_rxq			*rxq_ctrl;
275 	struct sfc_txq			*txq_ctrl;
276 
277 	boolean_t			tso;
278 	boolean_t			tso_encap;
279 
280 	uint32_t			rxd_wait_timeout_ns;
281 };
282 
283 static inline struct sfc_adapter_shared *
284 sfc_adapter_shared_by_eth_dev(struct rte_eth_dev *eth_dev)
285 {
286 	struct sfc_adapter_shared *sas = eth_dev->data->dev_private;
287 
288 	return sas;
289 }
290 
291 static inline struct sfc_adapter *
292 sfc_adapter_by_eth_dev(struct rte_eth_dev *eth_dev)
293 {
294 	struct sfc_adapter_priv *sap = sfc_adapter_priv_by_eth_dev(eth_dev);
295 
296 	SFC_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
297 
298 	return container_of(sap, struct sfc_adapter, priv);
299 }
300 
301 static inline struct sfc_adapter_shared *
302 sfc_sa2shared(struct sfc_adapter *sa)
303 {
304 	return sa->priv.shared;
305 }
306 
307 /*
308  * Add wrapper functions to acquire/release lock to be able to remove or
309  * change the lock in one place.
310  */
311 
312 static inline void
313 sfc_adapter_lock_init(struct sfc_adapter *sa)
314 {
315 	rte_spinlock_init(&sa->lock);
316 }
317 
318 static inline int
319 sfc_adapter_is_locked(struct sfc_adapter *sa)
320 {
321 	return rte_spinlock_is_locked(&sa->lock);
322 }
323 
324 static inline void
325 sfc_adapter_lock(struct sfc_adapter *sa)
326 {
327 	rte_spinlock_lock(&sa->lock);
328 }
329 
330 static inline int
331 sfc_adapter_trylock(struct sfc_adapter *sa)
332 {
333 	return rte_spinlock_trylock(&sa->lock);
334 }
335 
336 static inline void
337 sfc_adapter_unlock(struct sfc_adapter *sa)
338 {
339 	rte_spinlock_unlock(&sa->lock);
340 }
341 
342 static inline void
343 sfc_adapter_lock_fini(__rte_unused struct sfc_adapter *sa)
344 {
345 	/* Just for symmetry of the API */
346 }
347 
348 /** Get the number of milliseconds since boot from the default timer */
349 static inline uint64_t
350 sfc_get_system_msecs(void)
351 {
352 	return rte_get_timer_cycles() * MS_PER_S / rte_get_timer_hz();
353 }
354 
355 int sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id,
356 		  size_t len, int socket_id, efsys_mem_t *esmp);
357 void sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp);
358 
359 uint32_t sfc_register_logtype(const struct rte_pci_addr *pci_addr,
360 			      const char *lt_prefix_str,
361 			      uint32_t ll_default);
362 
363 int sfc_probe(struct sfc_adapter *sa);
364 void sfc_unprobe(struct sfc_adapter *sa);
365 int sfc_attach(struct sfc_adapter *sa);
366 void sfc_detach(struct sfc_adapter *sa);
367 int sfc_start(struct sfc_adapter *sa);
368 void sfc_stop(struct sfc_adapter *sa);
369 
370 void sfc_schedule_restart(struct sfc_adapter *sa);
371 
372 int sfc_mcdi_init(struct sfc_adapter *sa);
373 void sfc_mcdi_fini(struct sfc_adapter *sa);
374 
375 int sfc_configure(struct sfc_adapter *sa);
376 void sfc_close(struct sfc_adapter *sa);
377 
378 int sfc_intr_attach(struct sfc_adapter *sa);
379 void sfc_intr_detach(struct sfc_adapter *sa);
380 int sfc_intr_configure(struct sfc_adapter *sa);
381 void sfc_intr_close(struct sfc_adapter *sa);
382 int sfc_intr_start(struct sfc_adapter *sa);
383 void sfc_intr_stop(struct sfc_adapter *sa);
384 
385 int sfc_port_attach(struct sfc_adapter *sa);
386 void sfc_port_detach(struct sfc_adapter *sa);
387 int sfc_port_configure(struct sfc_adapter *sa);
388 void sfc_port_close(struct sfc_adapter *sa);
389 int sfc_port_start(struct sfc_adapter *sa);
390 void sfc_port_stop(struct sfc_adapter *sa);
391 void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
392 				struct rte_eth_link *link_info);
393 int sfc_port_update_mac_stats(struct sfc_adapter *sa);
394 int sfc_port_reset_mac_stats(struct sfc_adapter *sa);
395 int sfc_set_rx_mode(struct sfc_adapter *sa);
396 int sfc_set_rx_mode_unchecked(struct sfc_adapter *sa);
397 
398 
399 #ifdef __cplusplus
400 }
401 #endif
402 
403 #endif  /* _SFC_H */
404