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