Deleted Added
sdiff udiff text old ( 301067 ) new ( 301075 )
full compact
1/*-
2 * Copyright (c) 2010-2016 Solarflare Communications Inc.
3 * All rights reserved.
4 *
5 * This software was developed in part by Philip Paeps under contract for
6 * Solarflare Communications, Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * The views and conclusions contained in the software and documentation are
30 * those of the authors and should not be interpreted as representing official
31 * policies, either expressed or implied, of the FreeBSD Project.
32 *
33 * $FreeBSD: head/sys/dev/sfxge/sfxge.h 301075 2016-05-31 20:54:42Z arybchik $
34 */
35
36#ifndef _SFXGE_H
37#define _SFXGE_H
38
39#include <sys/param.h>
40#include <sys/kernel.h>
41#include <sys/socket.h>
42#include <sys/sysctl.h>
43#include <sys/sx.h>
44#include <vm/uma.h>
45
46#include <net/ethernet.h>
47#include <net/if.h>
48#include <net/if_var.h>
49#include <net/if_media.h>
50#include <net/if_types.h>
51
52#include "sfxge_ioc.h"
53
54/*
55 * Debugging
56 */
57#if 0
58#define DBGPRINT(dev, fmt, args...) \
59 device_printf(dev, "%s: " fmt "\n", __func__, ## args)
60#else
61#define DBGPRINT(dev, fmt, args...)
62#endif
63
64/*
65 * Backward-compatibility
66 */
67#ifndef CACHE_LINE_SIZE
68/* This should be right on most machines the driver will be used on, and
69 * we needn't care too much about wasting a few KB per interface.
70 */
71#define CACHE_LINE_SIZE 128
72#endif
73
74#ifndef IFCAP_LINKSTATE
75#define IFCAP_LINKSTATE 0
76#endif
77
78#ifndef IFCAP_VLAN_HWTSO
79#define IFCAP_VLAN_HWTSO 0
80#endif
81
82#ifndef IFM_10G_T
83#define IFM_10G_T IFM_UNKNOWN
84#endif
85
86#ifndef IFM_10G_KX4
87#define IFM_10G_KX4 IFM_10G_CX4
88#endif
89
90#ifndef IFM_40G_CR4
91#define IFM_40G_CR4 IFM_UNKNOWN
92#endif
93
94#if (__FreeBSD_version >= 800501 && __FreeBSD_version < 900000) || \
95 __FreeBSD_version >= 900003
96#define SFXGE_HAVE_DESCRIBE_INTR
97#endif
98
99#ifdef IFM_ETH_RXPAUSE
100#define SFXGE_HAVE_PAUSE_MEDIAOPTS
101#endif
102
103#ifndef CTLTYPE_U64
104#define CTLTYPE_U64 CTLTYPE_QUAD
105#endif
106
107#include "sfxge_rx.h"
108#include "sfxge_tx.h"
109
110#define ROUNDUP_POW_OF_TWO(_n) (1ULL << flsl((_n) - 1))
111
112#define SFXGE_IP_ALIGN 2
113
114#define SFXGE_ETHERTYPE_LOOPBACK 0x9000 /* Xerox loopback */
115
116
117#define SFXGE_MAGIC_RESERVED 0x8000
118
119#define SFXGE_MAGIC_DMAQ_LABEL_WIDTH 6
120#define SFXGE_MAGIC_DMAQ_LABEL_MASK \
121 ((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1)
122
123enum sfxge_sw_ev {
124 SFXGE_SW_EV_RX_QFLUSH_DONE = 1,
125 SFXGE_SW_EV_RX_QFLUSH_FAILED,
126 SFXGE_SW_EV_RX_QREFILL,
127 SFXGE_SW_EV_TX_QFLUSH_DONE,
128};
129
130#define SFXGE_SW_EV_MAGIC(_sw_ev) \
131 (SFXGE_MAGIC_RESERVED | ((_sw_ev) << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
132
133enum sfxge_evq_state {
134 SFXGE_EVQ_UNINITIALIZED = 0,
135 SFXGE_EVQ_INITIALIZED,
136 SFXGE_EVQ_STARTING,
137 SFXGE_EVQ_STARTED
138};
139
140#define SFXGE_EV_BATCH 16384
141
142struct sfxge_evq {
143 /* Structure members below are sorted by usage order */
144 struct sfxge_softc *sc;
145 struct mtx lock;
146 unsigned int index;
147 enum sfxge_evq_state init_state;
148 efsys_mem_t mem;
149 efx_evq_t *common;
150 unsigned int read_ptr;
151 boolean_t exception;
152 unsigned int rx_done;
153 unsigned int tx_done;
154
155 /* Linked list of TX queues with completions to process */
156 struct sfxge_txq *txq;
157 struct sfxge_txq **txqs;
158
159 /* Structure members not used on event processing path */
160 unsigned int buf_base_id;
161 unsigned int entries;
162 char lock_name[SFXGE_LOCK_NAME_MAX];
163} __aligned(CACHE_LINE_SIZE);
164
165#define SFXGE_NDESCS 1024
166#define SFXGE_MODERATION 30
167
168enum sfxge_intr_state {
169 SFXGE_INTR_UNINITIALIZED = 0,
170 SFXGE_INTR_INITIALIZED,
171 SFXGE_INTR_TESTING,
172 SFXGE_INTR_STARTED
173};
174
175struct sfxge_intr_hdl {
176 int eih_rid;
177 void *eih_tag;
178 struct resource *eih_res;
179};
180
181struct sfxge_intr {
182 enum sfxge_intr_state state;
183 struct resource *msix_res;
184 struct sfxge_intr_hdl *table;
185 int n_alloc;
186 int type;
187 efsys_mem_t status;
188 uint32_t zero_count;
189};
190
191enum sfxge_mcdi_state {
192 SFXGE_MCDI_UNINITIALIZED = 0,
193 SFXGE_MCDI_INITIALIZED,
194 SFXGE_MCDI_BUSY,
195 SFXGE_MCDI_COMPLETED
196};
197
198struct sfxge_mcdi {
199 struct mtx lock;
200 efsys_mem_t mem;
201 enum sfxge_mcdi_state state;
202 efx_mcdi_transport_t transport;
203
204 /* Only used in debugging output */
205 char lock_name[SFXGE_LOCK_NAME_MAX];
206};
207
208struct sfxge_hw_stats {
209 clock_t update_time;
210 efsys_mem_t dma_buf;
211 void *decode_buf;
212};
213
214enum sfxge_port_state {
215 SFXGE_PORT_UNINITIALIZED = 0,
216 SFXGE_PORT_INITIALIZED,
217 SFXGE_PORT_STARTED
218};
219
220struct sfxge_port {
221 struct sfxge_softc *sc;
222 struct mtx lock;
223 enum sfxge_port_state init_state;
224#ifndef SFXGE_HAVE_PAUSE_MEDIAOPTS
225 unsigned int wanted_fc;
226#endif
227 struct sfxge_hw_stats phy_stats;
228 struct sfxge_hw_stats mac_stats;
229 efx_link_mode_t link_mode;
230 uint8_t mcast_addrs[EFX_MAC_MULTICAST_LIST_MAX *
231 EFX_MAC_ADDR_LEN];
232 unsigned int mcast_count;
233
234 /* Only used in debugging output */
235 char lock_name[SFXGE_LOCK_NAME_MAX];
236};
237
238enum sfxge_softc_state {
239 SFXGE_UNINITIALIZED = 0,
240 SFXGE_INITIALIZED,
241 SFXGE_REGISTERED,
242 SFXGE_STARTED
243};
244
245struct sfxge_softc {
246 device_t dev;
247 struct sx softc_lock;
248 char softc_lock_name[SFXGE_LOCK_NAME_MAX];
249 enum sfxge_softc_state init_state;
250 struct ifnet *ifnet;
251 unsigned int if_flags;
252 struct sysctl_oid *stats_node;
253 struct sysctl_oid *txqs_node;
254
255 struct task task_reset;
256
257 efx_family_t family;
258 caddr_t vpd_data;
259 size_t vpd_size;
260 efx_nic_t *enp;
261 efsys_lock_t enp_lock;
262
263 unsigned int rxq_entries;
264 unsigned int txq_entries;
265
266 bus_dma_tag_t parent_dma_tag;
267 efsys_bar_t bar;
268
269 struct sfxge_intr intr;
270 struct sfxge_mcdi mcdi;
271 struct sfxge_port port;
272 uint32_t buffer_table_next;
273
274 struct sfxge_evq *evq[SFXGE_RX_SCALE_MAX];
275 unsigned int ev_moderation;
276#if EFSYS_OPT_QSTATS
277 clock_t ev_stats_update_time;
278 uint64_t ev_stats[EV_NQSTATS];
279#endif
280
281 unsigned int max_rss_channels;
282 uma_zone_t rxq_cache;
283 struct sfxge_rxq *rxq[SFXGE_RX_SCALE_MAX];
284 unsigned int rx_indir_table[SFXGE_RX_SCALE_MAX];
285
286 struct sfxge_txq *txq[SFXGE_TXQ_NTYPES + SFXGE_RX_SCALE_MAX];
287
288 struct ifmedia media;
289
290 size_t rx_prefix_size;
291 size_t rx_buffer_size;
292 size_t rx_buffer_align;
293 int rx_cluster_size;
294
295 unsigned int evq_max;
296 unsigned int evq_count;
297 unsigned int rxq_count;
298 unsigned int txq_count;
299
300 unsigned int tso_fw_assisted;
301#define SFXGE_FATSOV1 (1 << 0)
302#define SFXGE_FATSOV2 (1 << 1)
303
304#if EFSYS_OPT_MCDI_LOGGING
305 int mcdi_logging;
306#endif
307};
308
309#define SFXGE_LINK_UP(sc) ((sc)->port.link_mode != EFX_LINK_DOWN)
310#define SFXGE_RUNNING(sc) ((sc)->ifnet->if_drv_flags & IFF_DRV_RUNNING)
311
312#define SFXGE_PARAM(_name) "hw.sfxge." #_name
313
314SYSCTL_DECL(_hw_sfxge);
315
316/*
317 * From sfxge.c.
318 */
319extern void sfxge_schedule_reset(struct sfxge_softc *sc);
320extern void sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n,
321 uint32_t *idp);
322
323/*
324 * From sfxge_dma.c.
325 */
326extern int sfxge_dma_init(struct sfxge_softc *sc);
327extern void sfxge_dma_fini(struct sfxge_softc *sc);
328extern int sfxge_dma_alloc(struct sfxge_softc *sc, bus_size_t len,
329 efsys_mem_t *esmp);
330extern void sfxge_dma_free(efsys_mem_t *esmp);
331extern int sfxge_dma_map_sg_collapse(bus_dma_tag_t tag, bus_dmamap_t map,
332 struct mbuf **mp,
333 bus_dma_segment_t *segs,
334 int *nsegs, int maxsegs);
335
336/*
337 * From sfxge_ev.c.
338 */
339extern int sfxge_ev_init(struct sfxge_softc *sc);
340extern void sfxge_ev_fini(struct sfxge_softc *sc);
341extern int sfxge_ev_start(struct sfxge_softc *sc);
342extern void sfxge_ev_stop(struct sfxge_softc *sc);
343extern int sfxge_ev_qpoll(struct sfxge_evq *evq);
344
345/*
346 * From sfxge_intr.c.
347 */
348extern int sfxge_intr_init(struct sfxge_softc *sc);
349extern void sfxge_intr_fini(struct sfxge_softc *sc);
350extern int sfxge_intr_start(struct sfxge_softc *sc);
351extern void sfxge_intr_stop(struct sfxge_softc *sc);
352
353/*
354 * From sfxge_mcdi.c.
355 */
356extern int sfxge_mcdi_init(struct sfxge_softc *sc);
357extern void sfxge_mcdi_fini(struct sfxge_softc *sc);
358extern int sfxge_mcdi_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip);
359
360/*
361 * From sfxge_nvram.c.
362 */
363extern int sfxge_nvram_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip);
364
365/*
366 * From sfxge_port.c.
367 */
368extern int sfxge_port_init(struct sfxge_softc *sc);
369extern void sfxge_port_fini(struct sfxge_softc *sc);
370extern int sfxge_port_start(struct sfxge_softc *sc);
371extern void sfxge_port_stop(struct sfxge_softc *sc);
372extern void sfxge_mac_link_update(struct sfxge_softc *sc,
373 efx_link_mode_t mode);
374extern int sfxge_mac_filter_set(struct sfxge_softc *sc);
375extern int sfxge_port_ifmedia_init(struct sfxge_softc *sc);
376extern uint64_t sfxge_get_counter(struct ifnet *ifp, ift_counter c);
377
378#define SFXGE_MAX_MTU (9 * 1024)
379
380#define SFXGE_ADAPTER_LOCK_INIT(_sc, _ifname) \
381 do { \
382 struct sfxge_softc *__sc = (_sc); \
383 \
384 snprintf((__sc)->softc_lock_name, \
385 sizeof((__sc)->softc_lock_name), \
386 "%s:softc", (_ifname)); \
387 sx_init(&(__sc)->softc_lock, (__sc)->softc_lock_name); \
388 } while (B_FALSE)
389#define SFXGE_ADAPTER_LOCK_DESTROY(_sc) \
390 sx_destroy(&(_sc)->softc_lock)
391#define SFXGE_ADAPTER_LOCK(_sc) \
392 sx_xlock(&(_sc)->softc_lock)
393#define SFXGE_ADAPTER_UNLOCK(_sc) \
394 sx_xunlock(&(_sc)->softc_lock)
395#define SFXGE_ADAPTER_LOCK_ASSERT_OWNED(_sc) \
396 sx_assert(&(_sc)->softc_lock, LA_XLOCKED)
397
398#define SFXGE_PORT_LOCK_INIT(_port, _ifname) \
399 do { \
400 struct sfxge_port *__port = (_port); \
401 \
402 snprintf((__port)->lock_name, \
403 sizeof((__port)->lock_name), \
404 "%s:port", (_ifname)); \
405 mtx_init(&(__port)->lock, (__port)->lock_name, \
406 NULL, MTX_DEF); \
407 } while (B_FALSE)
408#define SFXGE_PORT_LOCK_DESTROY(_port) \
409 mtx_destroy(&(_port)->lock)
410#define SFXGE_PORT_LOCK(_port) \
411 mtx_lock(&(_port)->lock)
412#define SFXGE_PORT_UNLOCK(_port) \
413 mtx_unlock(&(_port)->lock)
414#define SFXGE_PORT_LOCK_ASSERT_OWNED(_port) \
415 mtx_assert(&(_port)->lock, MA_OWNED)
416
417#define SFXGE_MCDI_LOCK_INIT(_mcdi, _ifname) \
418 do { \
419 struct sfxge_mcdi *__mcdi = (_mcdi); \
420 \
421 snprintf((__mcdi)->lock_name, \
422 sizeof((__mcdi)->lock_name), \
423 "%s:mcdi", (_ifname)); \
424 mtx_init(&(__mcdi)->lock, (__mcdi)->lock_name, \
425 NULL, MTX_DEF); \
426 } while (B_FALSE)
427#define SFXGE_MCDI_LOCK_DESTROY(_mcdi) \
428 mtx_destroy(&(_mcdi)->lock)
429#define SFXGE_MCDI_LOCK(_mcdi) \
430 mtx_lock(&(_mcdi)->lock)
431#define SFXGE_MCDI_UNLOCK(_mcdi) \
432 mtx_unlock(&(_mcdi)->lock)
433#define SFXGE_MCDI_LOCK_ASSERT_OWNED(_mcdi) \
434 mtx_assert(&(_mcdi)->lock, MA_OWNED)
435
436#define SFXGE_EVQ_LOCK_INIT(_evq, _ifname, _evq_index) \
437 do { \
438 struct sfxge_evq *__evq = (_evq); \
439 \
440 snprintf((__evq)->lock_name, \
441 sizeof((__evq)->lock_name), \
442 "%s:evq%u", (_ifname), (_evq_index)); \
443 mtx_init(&(__evq)->lock, (__evq)->lock_name, \
444 NULL, MTX_DEF); \
445 } while (B_FALSE)
446#define SFXGE_EVQ_LOCK_DESTROY(_evq) \
447 mtx_destroy(&(_evq)->lock)
448#define SFXGE_EVQ_LOCK(_evq) \
449 mtx_lock(&(_evq)->lock)
450#define SFXGE_EVQ_UNLOCK(_evq) \
451 mtx_unlock(&(_evq)->lock)
452#define SFXGE_EVQ_LOCK_ASSERT_OWNED(_evq) \
453 mtx_assert(&(_evq)->lock, MA_OWNED)
454
455#endif /* _SFXGE_H */