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