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