xref: /f-stack/dpdk/drivers/net/sfc/sfc.h (revision 16d80a6d)
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 };
112 
113 struct sfc_rxq_info;
114 struct sfc_txq_info;
115 struct sfc_dp_rx;
116 
117 struct sfc_port {
118 	unsigned int			lsc_seq;
119 
120 	uint32_t			phy_adv_cap_mask;
121 	uint32_t			phy_adv_cap;
122 
123 	unsigned int			flow_ctrl;
124 	boolean_t			flow_ctrl_autoneg;
125 	size_t				pdu;
126 
127 	/*
128 	 * Flow API isolated mode overrides promisc and allmulti settings;
129 	 * they won't be applied if isolated mode is active
130 	 */
131 	boolean_t			isolated;
132 	boolean_t			promisc;
133 	boolean_t			allmulti;
134 
135 	struct ether_addr		default_mac_addr;
136 
137 	unsigned int			max_mcast_addrs;
138 	unsigned int			nb_mcast_addrs;
139 	uint8_t				*mcast_addrs;
140 
141 	rte_spinlock_t			mac_stats_lock;
142 	uint64_t			*mac_stats_buf;
143 	unsigned int			mac_stats_nb_supported;
144 	efsys_mem_t			mac_stats_dma_mem;
145 	boolean_t			mac_stats_reset_pending;
146 	uint16_t			mac_stats_update_period_ms;
147 	uint32_t			mac_stats_update_generation;
148 	boolean_t			mac_stats_periodic_dma_supported;
149 	uint64_t			mac_stats_last_request_timestamp;
150 
151 	uint32_t		mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES];
152 
153 	uint64_t			ipackets;
154 };
155 
156 struct sfc_rss_hf_rte_to_efx {
157 	uint64_t			rte;
158 	efx_rx_hash_type_t		efx;
159 };
160 
161 struct sfc_rss {
162 	unsigned int			channels;
163 	efx_rx_scale_context_type_t	context_type;
164 	efx_rx_hash_support_t		hash_support;
165 	efx_rx_hash_alg_t		hash_alg;
166 	unsigned int			hf_map_nb_entries;
167 	struct sfc_rss_hf_rte_to_efx	*hf_map;
168 
169 	efx_rx_hash_type_t		hash_types;
170 	unsigned int			tbl[EFX_RSS_TBL_SIZE];
171 	uint8_t				key[EFX_RSS_KEY_SIZE];
172 };
173 
174 /* Adapter private data */
175 struct sfc_adapter {
176 	/*
177 	 * PMD setup and configuration is not thread safe. Since it is not
178 	 * performance sensitive, it is better to guarantee thread-safety
179 	 * and add device level lock. Adapter control operations which
180 	 * change its state should acquire the lock.
181 	 */
182 	rte_spinlock_t			lock;
183 	enum sfc_adapter_state		state;
184 	struct rte_pci_addr		pci_addr;
185 	uint16_t			port_id;
186 	struct rte_eth_dev		*eth_dev;
187 	struct rte_kvargs		*kvargs;
188 	uint32_t			logtype_main;
189 	int				socket_id;
190 	efsys_bar_t			mem_bar;
191 	efx_family_t			family;
192 	efx_nic_t			*nic;
193 	rte_spinlock_t			nic_lock;
194 	rte_atomic32_t			restart_required;
195 
196 	struct sfc_mcdi			mcdi;
197 	struct sfc_intr			intr;
198 	struct sfc_port			port;
199 	struct sfc_filter		filter;
200 
201 	unsigned int			rxq_max;
202 	unsigned int			txq_max;
203 
204 	unsigned int			txq_max_entries;
205 
206 	uint32_t			evq_flags;
207 	unsigned int			evq_count;
208 
209 	unsigned int			mgmt_evq_index;
210 	/*
211 	 * The lock is used to serialise management event queue polling
212 	 * which can be done from different context. Also the lock
213 	 * guarantees that mgmt_evq_running is preserved while the lock
214 	 * is held. It is used to serialise polling and start/stop
215 	 * operations.
216 	 *
217 	 * Locks which may be held when the lock is acquired:
218 	 *  - adapter lock, when:
219 	 *    - device start/stop to change mgmt_evq_running
220 	 *    - any control operations in client side MCDI proxy handling to
221 	 *	poll management event queue waiting for proxy response
222 	 *  - MCDI lock, when:
223 	 *    - any control operations in client side MCDI proxy handling to
224 	 *	poll management event queue waiting for proxy response
225 	 *
226 	 * Locks which are acquired with the lock held:
227 	 *  - nic_lock, when:
228 	 *    - MC event processing on management event queue polling
229 	 *	(e.g. MC REBOOT or BADASSERT events)
230 	 */
231 	rte_spinlock_t			mgmt_evq_lock;
232 	bool				mgmt_evq_running;
233 	struct sfc_evq			*mgmt_evq;
234 
235 	unsigned int			rxq_count;
236 	struct sfc_rxq_info		*rxq_info;
237 
238 	unsigned int			txq_count;
239 	struct sfc_txq_info		*txq_info;
240 
241 	boolean_t			tso;
242 
243 	uint32_t			rxd_wait_timeout_ns;
244 
245 	struct sfc_rss			rss;
246 
247 	/*
248 	 * Shared memory copy of the Rx datapath name to be used by
249 	 * the secondary process to find Rx datapath to be used.
250 	 */
251 	char				*dp_rx_name;
252 	const struct sfc_dp_rx		*dp_rx;
253 
254 	/*
255 	 * Shared memory copy of the Tx datapath name to be used by
256 	 * the secondary process to find Tx datapath to be used.
257 	 */
258 	char				*dp_tx_name;
259 	const struct sfc_dp_tx		*dp_tx;
260 };
261 
262 /*
263  * Add wrapper functions to acquire/release lock to be able to remove or
264  * change the lock in one place.
265  */
266 
267 static inline void
268 sfc_adapter_lock_init(struct sfc_adapter *sa)
269 {
270 	rte_spinlock_init(&sa->lock);
271 }
272 
273 static inline int
274 sfc_adapter_is_locked(struct sfc_adapter *sa)
275 {
276 	return rte_spinlock_is_locked(&sa->lock);
277 }
278 
279 static inline void
280 sfc_adapter_lock(struct sfc_adapter *sa)
281 {
282 	rte_spinlock_lock(&sa->lock);
283 }
284 
285 static inline int
286 sfc_adapter_trylock(struct sfc_adapter *sa)
287 {
288 	return rte_spinlock_trylock(&sa->lock);
289 }
290 
291 static inline void
292 sfc_adapter_unlock(struct sfc_adapter *sa)
293 {
294 	rte_spinlock_unlock(&sa->lock);
295 }
296 
297 static inline void
298 sfc_adapter_lock_fini(__rte_unused struct sfc_adapter *sa)
299 {
300 	/* Just for symmetry of the API */
301 }
302 
303 /** Get the number of milliseconds since boot from the default timer */
304 static inline uint64_t
305 sfc_get_system_msecs(void)
306 {
307 	return rte_get_timer_cycles() * MS_PER_S / rte_get_timer_hz();
308 }
309 
310 int sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id,
311 		  size_t len, int socket_id, efsys_mem_t *esmp);
312 void sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp);
313 
314 uint32_t sfc_register_logtype(const struct rte_pci_addr *pci_addr,
315 			      const char *lt_prefix_str,
316 			      uint32_t ll_default);
317 
318 int sfc_probe(struct sfc_adapter *sa);
319 void sfc_unprobe(struct sfc_adapter *sa);
320 int sfc_attach(struct sfc_adapter *sa);
321 void sfc_detach(struct sfc_adapter *sa);
322 int sfc_start(struct sfc_adapter *sa);
323 void sfc_stop(struct sfc_adapter *sa);
324 
325 void sfc_schedule_restart(struct sfc_adapter *sa);
326 
327 int sfc_mcdi_init(struct sfc_adapter *sa);
328 void sfc_mcdi_fini(struct sfc_adapter *sa);
329 
330 int sfc_configure(struct sfc_adapter *sa);
331 void sfc_close(struct sfc_adapter *sa);
332 
333 int sfc_intr_attach(struct sfc_adapter *sa);
334 void sfc_intr_detach(struct sfc_adapter *sa);
335 int sfc_intr_configure(struct sfc_adapter *sa);
336 void sfc_intr_close(struct sfc_adapter *sa);
337 int sfc_intr_start(struct sfc_adapter *sa);
338 void sfc_intr_stop(struct sfc_adapter *sa);
339 
340 int sfc_port_attach(struct sfc_adapter *sa);
341 void sfc_port_detach(struct sfc_adapter *sa);
342 int sfc_port_configure(struct sfc_adapter *sa);
343 void sfc_port_close(struct sfc_adapter *sa);
344 int sfc_port_start(struct sfc_adapter *sa);
345 void sfc_port_stop(struct sfc_adapter *sa);
346 void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
347 				struct rte_eth_link *link_info);
348 int sfc_port_update_mac_stats(struct sfc_adapter *sa);
349 int sfc_port_reset_mac_stats(struct sfc_adapter *sa);
350 int sfc_set_rx_mode(struct sfc_adapter *sa);
351 
352 
353 #ifdef __cplusplus
354 }
355 #endif
356 
357 #endif  /* _SFC_H */
358