net/sfc: implement Rx queue start and stop operations
[dpdk.git] / drivers / net / sfc / sfc_ev.c
1 /*-
2  * Copyright (c) 2016 Solarflare Communications Inc.
3  * All rights reserved.
4  *
5  * This software was jointly developed between OKTET Labs (under contract
6  * for Solarflare) and 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
30 #include <rte_debug.h>
31 #include <rte_cycles.h>
32 #include <rte_alarm.h>
33
34 #include "efx.h"
35
36 #include "sfc.h"
37 #include "sfc_debug.h"
38 #include "sfc_log.h"
39 #include "sfc_ev.h"
40 #include "sfc_rx.h"
41
42
43 /* Initial delay when waiting for event queue init complete event */
44 #define SFC_EVQ_INIT_BACKOFF_START_US   (1)
45 /* Maximum delay between event queue polling attempts */
46 #define SFC_EVQ_INIT_BACKOFF_MAX_US     (10 * 1000)
47 /* Event queue init approx timeout */
48 #define SFC_EVQ_INIT_TIMEOUT_US         (2 * US_PER_S)
49
50 /* Management event queue polling period in microseconds */
51 #define SFC_MGMT_EV_QPOLL_PERIOD_US     (US_PER_S)
52
53
54 static boolean_t
55 sfc_ev_initialized(void *arg)
56 {
57         struct sfc_evq *evq = arg;
58
59         /* Init done events may be duplicated on SFN7xxx (SFC bug 31631) */
60         SFC_ASSERT(evq->init_state == SFC_EVQ_STARTING ||
61                    evq->init_state == SFC_EVQ_STARTED);
62
63         evq->init_state = SFC_EVQ_STARTED;
64
65         return B_FALSE;
66 }
67
68 static boolean_t
69 sfc_ev_rx(void *arg, __rte_unused uint32_t label, __rte_unused uint32_t id,
70           __rte_unused uint32_t size, __rte_unused uint16_t flags)
71 {
72         struct sfc_evq *evq = arg;
73
74         sfc_err(evq->sa, "EVQ %u unexpected Rx event", evq->evq_index);
75         return B_TRUE;
76 }
77
78 static boolean_t
79 sfc_ev_tx(void *arg, __rte_unused uint32_t label, __rte_unused uint32_t id)
80 {
81         struct sfc_evq *evq = arg;
82
83         sfc_err(evq->sa, "EVQ %u unexpected Tx event", evq->evq_index);
84         return B_TRUE;
85 }
86
87 static boolean_t
88 sfc_ev_exception(void *arg, __rte_unused uint32_t code,
89                  __rte_unused uint32_t data)
90 {
91         struct sfc_evq *evq = arg;
92
93         if (code == EFX_EXCEPTION_UNKNOWN_SENSOREVT)
94                 return B_FALSE;
95
96         evq->exception = B_TRUE;
97         sfc_warn(evq->sa,
98                  "hardware exception %s (code=%u, data=%#x) on EVQ %u;"
99                  " needs recovery",
100                  (code == EFX_EXCEPTION_RX_RECOVERY) ? "RX_RECOVERY" :
101                  (code == EFX_EXCEPTION_RX_DSC_ERROR) ? "RX_DSC_ERROR" :
102                  (code == EFX_EXCEPTION_TX_DSC_ERROR) ? "TX_DSC_ERROR" :
103                  (code == EFX_EXCEPTION_FWALERT_SRAM) ? "FWALERT_SRAM" :
104                  (code == EFX_EXCEPTION_UNKNOWN_FWALERT) ? "UNKNOWN_FWALERT" :
105                  (code == EFX_EXCEPTION_RX_ERROR) ? "RX_ERROR" :
106                  (code == EFX_EXCEPTION_TX_ERROR) ? "TX_ERROR" :
107                  (code == EFX_EXCEPTION_EV_ERROR) ? "EV_ERROR" :
108                  "UNKNOWN",
109                  code, data, evq->evq_index);
110
111         return B_TRUE;
112 }
113
114 static boolean_t
115 sfc_ev_rxq_flush_done(void *arg, __rte_unused uint32_t rxq_hw_index)
116 {
117         struct sfc_evq *evq = arg;
118         struct sfc_rxq *rxq;
119
120         rxq = evq->rxq;
121         SFC_ASSERT(rxq != NULL);
122         SFC_ASSERT(rxq->hw_index == rxq_hw_index);
123         SFC_ASSERT(rxq->evq == evq);
124         sfc_rx_qflush_done(rxq);
125
126         return B_FALSE;
127 }
128
129 static boolean_t
130 sfc_ev_rxq_flush_failed(void *arg, __rte_unused uint32_t rxq_hw_index)
131 {
132         struct sfc_evq *evq = arg;
133         struct sfc_rxq *rxq;
134
135         rxq = evq->rxq;
136         SFC_ASSERT(rxq != NULL);
137         SFC_ASSERT(rxq->hw_index == rxq_hw_index);
138         SFC_ASSERT(rxq->evq == evq);
139         sfc_rx_qflush_failed(rxq);
140
141         return B_FALSE;
142 }
143
144 static boolean_t
145 sfc_ev_txq_flush_done(void *arg, __rte_unused uint32_t txq_hw_index)
146 {
147         struct sfc_evq *evq = arg;
148
149         sfc_err(evq->sa, "EVQ %u unexpected Tx flush done event",
150                 evq->evq_index);
151         return B_TRUE;
152 }
153
154 static boolean_t
155 sfc_ev_software(void *arg, uint16_t magic)
156 {
157         struct sfc_evq *evq = arg;
158
159         sfc_err(evq->sa, "EVQ %u unexpected software event magic=%#.4x",
160                 evq->evq_index, magic);
161         return B_TRUE;
162 }
163
164 static boolean_t
165 sfc_ev_sram(void *arg, uint32_t code)
166 {
167         struct sfc_evq *evq = arg;
168
169         sfc_err(evq->sa, "EVQ %u unexpected SRAM event code=%u",
170                 evq->evq_index, code);
171         return B_TRUE;
172 }
173
174 static boolean_t
175 sfc_ev_wake_up(void *arg, uint32_t index)
176 {
177         struct sfc_evq *evq = arg;
178
179         sfc_err(evq->sa, "EVQ %u unexpected wake up event index=%u",
180                 evq->evq_index, index);
181         return B_TRUE;
182 }
183
184 static boolean_t
185 sfc_ev_timer(void *arg, uint32_t index)
186 {
187         struct sfc_evq *evq = arg;
188
189         sfc_err(evq->sa, "EVQ %u unexpected timer event index=%u",
190                 evq->evq_index, index);
191         return B_TRUE;
192 }
193
194 static boolean_t
195 sfc_ev_link_change(void *arg, efx_link_mode_t link_mode)
196 {
197         struct sfc_evq *evq = arg;
198         struct sfc_adapter *sa = evq->sa;
199         struct rte_eth_link *dev_link = &sa->eth_dev->data->dev_link;
200         struct rte_eth_link new_link;
201
202         EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
203
204         sfc_port_link_mode_to_info(link_mode, &new_link);
205         rte_atomic64_set((rte_atomic64_t *)dev_link, *(uint64_t *)&new_link);
206
207         return B_FALSE;
208 }
209
210 static const efx_ev_callbacks_t sfc_ev_callbacks = {
211         .eec_initialized        = sfc_ev_initialized,
212         .eec_rx                 = sfc_ev_rx,
213         .eec_tx                 = sfc_ev_tx,
214         .eec_exception          = sfc_ev_exception,
215         .eec_rxq_flush_done     = sfc_ev_rxq_flush_done,
216         .eec_rxq_flush_failed   = sfc_ev_rxq_flush_failed,
217         .eec_txq_flush_done     = sfc_ev_txq_flush_done,
218         .eec_software           = sfc_ev_software,
219         .eec_sram               = sfc_ev_sram,
220         .eec_wake_up            = sfc_ev_wake_up,
221         .eec_timer              = sfc_ev_timer,
222         .eec_link_change        = sfc_ev_link_change,
223 };
224
225
226 void
227 sfc_ev_qpoll(struct sfc_evq *evq)
228 {
229         SFC_ASSERT(evq->init_state == SFC_EVQ_STARTED ||
230                    evq->init_state == SFC_EVQ_STARTING);
231
232         /* Synchronize the DMA memory for reading not required */
233
234         efx_ev_qpoll(evq->common, &evq->read_ptr, &sfc_ev_callbacks, evq);
235
236         /* Poll-mode driver does not re-prime the event queue for interrupts */
237 }
238
239 void
240 sfc_ev_mgmt_qpoll(struct sfc_adapter *sa)
241 {
242         if (rte_spinlock_trylock(&sa->mgmt_evq_lock)) {
243                 struct sfc_evq *mgmt_evq = sa->evq_info[sa->mgmt_evq_index].evq;
244
245                 if (mgmt_evq->init_state == SFC_EVQ_STARTED)
246                         sfc_ev_qpoll(mgmt_evq);
247
248                 rte_spinlock_unlock(&sa->mgmt_evq_lock);
249         }
250 }
251
252 int
253 sfc_ev_qprime(struct sfc_evq *evq)
254 {
255         SFC_ASSERT(evq->init_state == SFC_EVQ_STARTED);
256         return efx_ev_qprime(evq->common, evq->read_ptr);
257 }
258
259 int
260 sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index)
261 {
262         const struct sfc_evq_info *evq_info;
263         struct sfc_evq *evq;
264         efsys_mem_t *esmp;
265         unsigned int total_delay_us;
266         unsigned int delay_us;
267         int rc;
268
269         sfc_log_init(sa, "sw_index=%u", sw_index);
270
271         evq_info = &sa->evq_info[sw_index];
272         evq = evq_info->evq;
273         esmp = &evq->mem;
274
275         /* Clear all events */
276         (void)memset((void *)esmp->esm_base, 0xff,
277                      EFX_EVQ_SIZE(evq_info->entries));
278
279         /* Create the common code event queue */
280         rc = efx_ev_qcreate(sa->nic, sw_index, esmp, evq_info->entries,
281                             0 /* unused on EF10 */, 0,
282                             EFX_EVQ_FLAGS_TYPE_THROUGHPUT |
283                             EFX_EVQ_FLAGS_NOTIFY_DISABLED,
284                             &evq->common);
285         if (rc != 0)
286                 goto fail_ev_qcreate;
287
288         evq->init_state = SFC_EVQ_STARTING;
289
290         /* Wait for the initialization event */
291         total_delay_us = 0;
292         delay_us = SFC_EVQ_INIT_BACKOFF_START_US;
293         do {
294                 (void)sfc_ev_qpoll(evq);
295
296                 /* Check to see if the initialization complete indication
297                  * posted by the hardware.
298                  */
299                 if (evq->init_state == SFC_EVQ_STARTED)
300                         goto done;
301
302                 /* Give event queue some time to init */
303                 rte_delay_us(delay_us);
304
305                 total_delay_us += delay_us;
306
307                 /* Exponential backoff */
308                 delay_us *= 2;
309                 if (delay_us > SFC_EVQ_INIT_BACKOFF_MAX_US)
310                         delay_us = SFC_EVQ_INIT_BACKOFF_MAX_US;
311
312         } while (total_delay_us < SFC_EVQ_INIT_TIMEOUT_US);
313
314         rc = ETIMEDOUT;
315         goto fail_timedout;
316
317 done:
318         return 0;
319
320 fail_timedout:
321         evq->init_state = SFC_EVQ_INITIALIZED;
322         efx_ev_qdestroy(evq->common);
323
324 fail_ev_qcreate:
325         sfc_log_init(sa, "failed %d", rc);
326         return rc;
327 }
328
329 void
330 sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index)
331 {
332         const struct sfc_evq_info *evq_info;
333         struct sfc_evq *evq;
334
335         sfc_log_init(sa, "sw_index=%u", sw_index);
336
337         SFC_ASSERT(sw_index < sa->evq_count);
338
339         evq_info = &sa->evq_info[sw_index];
340         evq = evq_info->evq;
341
342         if (evq == NULL || evq->init_state != SFC_EVQ_STARTED)
343                 return;
344
345         evq->init_state = SFC_EVQ_INITIALIZED;
346         evq->read_ptr = 0;
347         evq->exception = B_FALSE;
348
349         efx_ev_qdestroy(evq->common);
350 }
351
352 static void
353 sfc_ev_mgmt_periodic_qpoll(void *arg)
354 {
355         struct sfc_adapter *sa = arg;
356         int rc;
357
358         sfc_ev_mgmt_qpoll(sa);
359
360         rc = rte_eal_alarm_set(SFC_MGMT_EV_QPOLL_PERIOD_US,
361                                sfc_ev_mgmt_periodic_qpoll, sa);
362         if (rc != 0)
363                 sfc_panic(sa,
364                           "cannot rearm management EVQ polling alarm (rc=%d)",
365                           rc);
366 }
367
368 static void
369 sfc_ev_mgmt_periodic_qpoll_start(struct sfc_adapter *sa)
370 {
371         sfc_ev_mgmt_periodic_qpoll(sa);
372 }
373
374 static void
375 sfc_ev_mgmt_periodic_qpoll_stop(struct sfc_adapter *sa)
376 {
377         rte_eal_alarm_cancel(sfc_ev_mgmt_periodic_qpoll, sa);
378 }
379
380 int
381 sfc_ev_start(struct sfc_adapter *sa)
382 {
383         int rc;
384
385         sfc_log_init(sa, "entry");
386
387         rc = efx_ev_init(sa->nic);
388         if (rc != 0)
389                 goto fail_ev_init;
390
391         /* Start management EVQ used for global events */
392         rte_spinlock_lock(&sa->mgmt_evq_lock);
393
394         rc = sfc_ev_qstart(sa, sa->mgmt_evq_index);
395         if (rc != 0)
396                 goto fail_mgmt_evq_start;
397
398         rte_spinlock_unlock(&sa->mgmt_evq_lock);
399
400         /*
401          * Start management EVQ polling. If interrupts are disabled
402          * (not used), it is required to process link status change
403          * and other device level events to avoid unrecoverable
404          * error because the event queue overflow.
405          */
406         sfc_ev_mgmt_periodic_qpoll_start(sa);
407
408         /*
409          * Rx/Tx event queues are started/stopped when corresponding
410          * Rx/Tx queue is started/stopped.
411          */
412
413         return 0;
414
415 fail_mgmt_evq_start:
416         rte_spinlock_unlock(&sa->mgmt_evq_lock);
417         efx_ev_fini(sa->nic);
418
419 fail_ev_init:
420         sfc_log_init(sa, "failed %d", rc);
421         return rc;
422 }
423
424 void
425 sfc_ev_stop(struct sfc_adapter *sa)
426 {
427         unsigned int sw_index;
428
429         sfc_log_init(sa, "entry");
430
431         sfc_ev_mgmt_periodic_qpoll_stop(sa);
432
433         /* Make sure that all event queues are stopped */
434         sw_index = sa->evq_count;
435         while (sw_index-- > 0) {
436                 if (sw_index == sa->mgmt_evq_index) {
437                         /* Locks are required for the management EVQ */
438                         rte_spinlock_lock(&sa->mgmt_evq_lock);
439                         sfc_ev_qstop(sa, sa->mgmt_evq_index);
440                         rte_spinlock_unlock(&sa->mgmt_evq_lock);
441                 } else {
442                         sfc_ev_qstop(sa, sw_index);
443                 }
444         }
445
446         efx_ev_fini(sa->nic);
447 }
448
449 int
450 sfc_ev_qinit(struct sfc_adapter *sa, unsigned int sw_index,
451              unsigned int entries, int socket_id)
452 {
453         struct sfc_evq_info *evq_info;
454         struct sfc_evq *evq;
455         int rc;
456
457         sfc_log_init(sa, "sw_index=%u", sw_index);
458
459         evq_info = &sa->evq_info[sw_index];
460
461         SFC_ASSERT(rte_is_power_of_2(entries));
462         SFC_ASSERT(entries <= evq_info->max_entries);
463         evq_info->entries = entries;
464
465         evq = rte_zmalloc_socket("sfc-evq", sizeof(*evq), RTE_CACHE_LINE_SIZE,
466                                  socket_id);
467         if (evq == NULL)
468                 return ENOMEM;
469
470         evq->sa = sa;
471         evq->evq_index = sw_index;
472
473         /* Allocate DMA space */
474         rc = sfc_dma_alloc(sa, "evq", sw_index, EFX_EVQ_SIZE(evq_info->entries),
475                            socket_id, &evq->mem);
476         if (rc != 0)
477                 return rc;
478
479         evq->init_state = SFC_EVQ_INITIALIZED;
480
481         evq_info->evq = evq;
482
483         return 0;
484 }
485
486 void
487 sfc_ev_qfini(struct sfc_adapter *sa, unsigned int sw_index)
488 {
489         struct sfc_evq *evq;
490
491         sfc_log_init(sa, "sw_index=%u", sw_index);
492
493         evq = sa->evq_info[sw_index].evq;
494
495         SFC_ASSERT(evq->init_state == SFC_EVQ_INITIALIZED);
496
497         sa->evq_info[sw_index].evq = NULL;
498
499         sfc_dma_free(sa, &evq->mem);
500
501         rte_free(evq);
502 }
503
504 static int
505 sfc_ev_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
506 {
507         struct sfc_evq_info *evq_info = &sa->evq_info[sw_index];
508         unsigned int max_entries;
509
510         sfc_log_init(sa, "sw_index=%u", sw_index);
511
512         max_entries = sfc_evq_max_entries(sa, sw_index);
513         SFC_ASSERT(rte_is_power_of_2(max_entries));
514
515         evq_info->max_entries = max_entries;
516
517         return 0;
518 }
519
520 static void
521 sfc_ev_qfini_info(struct sfc_adapter *sa, unsigned int sw_index)
522 {
523         sfc_log_init(sa, "sw_index=%u", sw_index);
524
525         /* Nothing to cleanup */
526 }
527
528 int
529 sfc_ev_init(struct sfc_adapter *sa)
530 {
531         int rc;
532         unsigned int sw_index;
533
534         sfc_log_init(sa, "entry");
535
536         sa->evq_count = sfc_ev_qcount(sa);
537         sa->mgmt_evq_index = 0;
538         rte_spinlock_init(&sa->mgmt_evq_lock);
539
540         /* Allocate EVQ info array */
541         rc = ENOMEM;
542         sa->evq_info = rte_calloc_socket("sfc-evqs", sa->evq_count,
543                                          sizeof(struct sfc_evq_info), 0,
544                                          sa->socket_id);
545         if (sa->evq_info == NULL)
546                 goto fail_evqs_alloc;
547
548         for (sw_index = 0; sw_index < sa->evq_count; ++sw_index) {
549                 rc = sfc_ev_qinit_info(sa, sw_index);
550                 if (rc != 0)
551                         goto fail_ev_qinit_info;
552         }
553
554         rc = sfc_ev_qinit(sa, sa->mgmt_evq_index, SFC_MGMT_EVQ_ENTRIES,
555                           sa->socket_id);
556         if (rc != 0)
557                 goto fail_mgmt_evq_init;
558
559         /*
560          * Rx/Tx event queues are created/destroyed when corresponding
561          * Rx/Tx queue is created/destroyed.
562          */
563
564         return 0;
565
566 fail_mgmt_evq_init:
567 fail_ev_qinit_info:
568         while (sw_index-- > 0)
569                 sfc_ev_qfini_info(sa, sw_index);
570
571         rte_free(sa->evq_info);
572         sa->evq_info = NULL;
573
574 fail_evqs_alloc:
575         sa->evq_count = 0;
576         sfc_log_init(sa, "failed %d", rc);
577         return rc;
578 }
579
580 void
581 sfc_ev_fini(struct sfc_adapter *sa)
582 {
583         int sw_index;
584
585         sfc_log_init(sa, "entry");
586
587         /* Cleanup all event queues */
588         sw_index = sa->evq_count;
589         while (--sw_index >= 0) {
590                 if (sa->evq_info[sw_index].evq != NULL)
591                         sfc_ev_qfini(sa, sw_index);
592                 sfc_ev_qfini_info(sa, sw_index);
593         }
594
595         rte_free(sa->evq_info);
596         sa->evq_info = NULL;
597         sa->evq_count = 0;
598 }