raw/ntb: setup queues
[dpdk.git] / drivers / raw / ntb / ntb.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation.
3  */
4 #include <stdint.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <errno.h>
8
9 #include <rte_common.h>
10 #include <rte_lcore.h>
11 #include <rte_cycles.h>
12 #include <rte_eal.h>
13 #include <rte_log.h>
14 #include <rte_pci.h>
15 #include <rte_mbuf.h>
16 #include <rte_bus_pci.h>
17 #include <rte_memzone.h>
18 #include <rte_memcpy.h>
19 #include <rte_rawdev.h>
20 #include <rte_rawdev_pmd.h>
21
22 #include "ntb_hw_intel.h"
23 #include "rte_pmd_ntb.h"
24 #include "ntb.h"
25
26 int ntb_logtype;
27
28 static const struct rte_pci_id pci_id_ntb_map[] = {
29         { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
30         { .vendor_id = 0, /* sentinel */ },
31 };
32
33 static inline void
34 ntb_link_cleanup(struct rte_rawdev *dev)
35 {
36         struct ntb_hw *hw = dev->dev_private;
37         int status, i;
38
39         if (hw->ntb_ops->spad_write == NULL ||
40             hw->ntb_ops->mw_set_trans == NULL) {
41                 NTB_LOG(ERR, "Not supported to clean up link.");
42                 return;
43         }
44
45         /* Clean spad registers. */
46         for (i = 0; i < hw->spad_cnt; i++) {
47                 status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
48                 if (status)
49                         NTB_LOG(ERR, "Failed to clean local spad.");
50         }
51
52         /* Clear mw so that peer cannot access local memory.*/
53         for (i = 0; i < hw->used_mw_num; i++) {
54                 status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
55                 if (status)
56                         NTB_LOG(ERR, "Failed to clean mw.");
57         }
58 }
59
60 static inline int
61 ntb_handshake_work(const struct rte_rawdev *dev)
62 {
63         struct ntb_hw *hw = dev->dev_private;
64         uint32_t val;
65         int ret, i;
66
67         if (hw->ntb_ops->spad_write == NULL ||
68             hw->ntb_ops->mw_set_trans == NULL) {
69                 NTB_LOG(ERR, "Scratchpad/MW setting is not supported.");
70                 return -ENOTSUP;
71         }
72
73         /* Tell peer the mw info of local side. */
74         ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
75         if (ret < 0)
76                 return ret;
77         for (i = 0; i < hw->mw_cnt; i++) {
78                 NTB_LOG(INFO, "Local %u mw size: 0x%"PRIx64"", i,
79                                 hw->mw_size[i]);
80                 val = hw->mw_size[i] >> 32;
81                 ret = (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
82                                                  1, val);
83                 if (ret < 0)
84                         return ret;
85                 val = hw->mw_size[i];
86                 ret = (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
87                                                  1, val);
88                 if (ret < 0)
89                         return ret;
90         }
91
92         /* Tell peer about the queue info and map memory to the peer. */
93         ret = (*hw->ntb_ops->spad_write)(dev, SPAD_Q_SZ, 1, hw->queue_size);
94         if (ret < 0)
95                 return ret;
96         ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_QPS, 1,
97                                          hw->queue_pairs);
98         if (ret < 0)
99                 return ret;
100         ret = (*hw->ntb_ops->spad_write)(dev, SPAD_USED_MWS, 1,
101                                          hw->used_mw_num);
102         if (ret < 0)
103                 return ret;
104         for (i = 0; i < hw->used_mw_num; i++) {
105                 val = (uint64_t)(size_t)(hw->mz[i]->addr) >> 32;
106                 ret = (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_BA_H + 2 * i,
107                                                  1, val);
108                 if (ret < 0)
109                         return ret;
110                 val = (uint64_t)(size_t)(hw->mz[i]->addr);
111                 ret = (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_BA_L + 2 * i,
112                                                  1, val);
113                 if (ret < 0)
114                         return ret;
115         }
116
117         for (i = 0; i < hw->used_mw_num; i++) {
118                 ret = (*hw->ntb_ops->mw_set_trans)(dev, i, hw->mz[i]->iova,
119                                                    hw->mz[i]->len);
120                 if (ret < 0)
121                         return ret;
122         }
123
124         /* Ring doorbell 0 to tell peer the device is ready. */
125         ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
126         if (ret < 0)
127                 return ret;
128
129         return 0;
130 }
131
132 static void
133 ntb_dev_intr_handler(void *param)
134 {
135         struct rte_rawdev *dev = (struct rte_rawdev *)param;
136         struct ntb_hw *hw = dev->dev_private;
137         uint32_t val_h, val_l;
138         uint64_t peer_mw_size;
139         uint64_t db_bits = 0;
140         uint8_t peer_mw_cnt;
141         int i = 0;
142
143         if (hw->ntb_ops->db_read == NULL ||
144             hw->ntb_ops->db_clear == NULL ||
145             hw->ntb_ops->peer_db_set == NULL) {
146                 NTB_LOG(ERR, "Doorbell is not supported.");
147                 return;
148         }
149
150         db_bits = (*hw->ntb_ops->db_read)(dev);
151         if (!db_bits)
152                 NTB_LOG(ERR, "No doorbells");
153
154         /* Doorbell 0 is for peer device ready. */
155         if (db_bits & 1) {
156                 NTB_LOG(INFO, "DB0: Peer device is up.");
157                 /* Clear received doorbell. */
158                 (*hw->ntb_ops->db_clear)(dev, 1);
159
160                 /**
161                  * Peer dev is already up. All mw settings are already done.
162                  * Skip them.
163                  */
164                 if (hw->peer_dev_up)
165                         return;
166
167                 if (hw->ntb_ops->spad_read == NULL) {
168                         NTB_LOG(ERR, "Scratchpad read is not supported.");
169                         return;
170                 }
171
172                 /* Check if mw setting on the peer is the same as local. */
173                 peer_mw_cnt = (*hw->ntb_ops->spad_read)(dev, SPAD_NUM_MWS, 0);
174                 if (peer_mw_cnt != hw->mw_cnt) {
175                         NTB_LOG(ERR, "Both mw cnt must be the same.");
176                         return;
177                 }
178
179                 for (i = 0; i < hw->mw_cnt; i++) {
180                         val_h = (*hw->ntb_ops->spad_read)
181                                 (dev, SPAD_MW0_SZ_H + 2 * i, 0);
182                         val_l = (*hw->ntb_ops->spad_read)
183                                 (dev, SPAD_MW0_SZ_L + 2 * i, 0);
184                         peer_mw_size = ((uint64_t)val_h << 32) | val_l;
185                         NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
186                                         peer_mw_size);
187                         if (peer_mw_size != hw->mw_size[i]) {
188                                 NTB_LOG(ERR, "Mw config must be the same.");
189                                 return;
190                         }
191                 }
192
193                 hw->peer_dev_up = 1;
194
195                 /**
196                  * Handshake with peer. Spad_write & mw_set_trans only works
197                  * when both devices are up. So write spad again when db is
198                  * received. And set db again for the later device who may miss
199                  * the 1st db.
200                  */
201                 if (ntb_handshake_work(dev) < 0) {
202                         NTB_LOG(ERR, "Handshake work failed.");
203                         return;
204                 }
205
206                 /* To get the link info. */
207                 if (hw->ntb_ops->get_link_status == NULL) {
208                         NTB_LOG(ERR, "Not supported to get link status.");
209                         return;
210                 }
211                 (*hw->ntb_ops->get_link_status)(dev);
212                 NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
213                         hw->link_speed, hw->link_width);
214                 return;
215         }
216
217         if (db_bits & (1 << 1)) {
218                 NTB_LOG(INFO, "DB1: Peer device is down.");
219                 /* Clear received doorbell. */
220                 (*hw->ntb_ops->db_clear)(dev, 2);
221
222                 /* Peer device will be down, So clean local side too. */
223                 ntb_link_cleanup(dev);
224
225                 hw->peer_dev_up = 0;
226                 /* Response peer's dev_stop request. */
227                 (*hw->ntb_ops->peer_db_set)(dev, 2);
228                 return;
229         }
230
231         if (db_bits & (1 << 2)) {
232                 NTB_LOG(INFO, "DB2: Peer device agrees dev to be down.");
233                 /* Clear received doorbell. */
234                 (*hw->ntb_ops->db_clear)(dev, (1 << 2));
235                 hw->peer_dev_up = 0;
236                 return;
237         }
238 }
239
240 static void
241 ntb_queue_conf_get(struct rte_rawdev *dev,
242                    uint16_t queue_id,
243                    rte_rawdev_obj_t queue_conf)
244 {
245         struct ntb_queue_conf *q_conf = queue_conf;
246         struct ntb_hw *hw = dev->dev_private;
247
248         q_conf->tx_free_thresh = hw->tx_queues[queue_id]->tx_free_thresh;
249         q_conf->nb_desc = hw->rx_queues[queue_id]->nb_rx_desc;
250         q_conf->rx_mp = hw->rx_queues[queue_id]->mpool;
251 }
252
253 static void
254 ntb_rxq_release_mbufs(struct ntb_rx_queue *q)
255 {
256         int i;
257
258         if (!q || !q->sw_ring) {
259                 NTB_LOG(ERR, "Pointer to rxq or sw_ring is NULL");
260                 return;
261         }
262
263         for (i = 0; i < q->nb_rx_desc; i++) {
264                 if (q->sw_ring[i].mbuf) {
265                         rte_pktmbuf_free_seg(q->sw_ring[i].mbuf);
266                         q->sw_ring[i].mbuf = NULL;
267                 }
268         }
269 }
270
271 static void
272 ntb_rxq_release(struct ntb_rx_queue *rxq)
273 {
274         if (!rxq) {
275                 NTB_LOG(ERR, "Pointer to rxq is NULL");
276                 return;
277         }
278
279         ntb_rxq_release_mbufs(rxq);
280
281         rte_free(rxq->sw_ring);
282         rte_free(rxq);
283 }
284
285 static int
286 ntb_rxq_setup(struct rte_rawdev *dev,
287               uint16_t qp_id,
288               rte_rawdev_obj_t queue_conf)
289 {
290         struct ntb_queue_conf *rxq_conf = queue_conf;
291         struct ntb_hw *hw = dev->dev_private;
292         struct ntb_rx_queue *rxq;
293
294         /* Allocate the rx queue data structure */
295         rxq = rte_zmalloc_socket("ntb rx queue",
296                                  sizeof(struct ntb_rx_queue),
297                                  RTE_CACHE_LINE_SIZE,
298                                  dev->socket_id);
299         if (!rxq) {
300                 NTB_LOG(ERR, "Failed to allocate memory for "
301                             "rx queue data structure.");
302                 return -ENOMEM;
303         }
304
305         if (rxq_conf->rx_mp == NULL) {
306                 NTB_LOG(ERR, "Invalid null mempool pointer.");
307                 return -EINVAL;
308         }
309         rxq->nb_rx_desc = rxq_conf->nb_desc;
310         rxq->mpool = rxq_conf->rx_mp;
311         rxq->port_id = dev->dev_id;
312         rxq->queue_id = qp_id;
313         rxq->hw = hw;
314
315         /* Allocate the software ring. */
316         rxq->sw_ring =
317                 rte_zmalloc_socket("ntb rx sw ring",
318                                    sizeof(struct ntb_rx_entry) *
319                                    rxq->nb_rx_desc,
320                                    RTE_CACHE_LINE_SIZE,
321                                    dev->socket_id);
322         if (!rxq->sw_ring) {
323                 ntb_rxq_release(rxq);
324                 rxq = NULL;
325                 NTB_LOG(ERR, "Failed to allocate memory for SW ring");
326                 return -ENOMEM;
327         }
328
329         hw->rx_queues[qp_id] = rxq;
330
331         return 0;
332 }
333
334 static void
335 ntb_txq_release_mbufs(struct ntb_tx_queue *q)
336 {
337         int i;
338
339         if (!q || !q->sw_ring) {
340                 NTB_LOG(ERR, "Pointer to txq or sw_ring is NULL");
341                 return;
342         }
343
344         for (i = 0; i < q->nb_tx_desc; i++) {
345                 if (q->sw_ring[i].mbuf) {
346                         rte_pktmbuf_free_seg(q->sw_ring[i].mbuf);
347                         q->sw_ring[i].mbuf = NULL;
348                 }
349         }
350 }
351
352 static void
353 ntb_txq_release(struct ntb_tx_queue *txq)
354 {
355         if (!txq) {
356                 NTB_LOG(ERR, "Pointer to txq is NULL");
357                 return;
358         }
359
360         ntb_txq_release_mbufs(txq);
361
362         rte_free(txq->sw_ring);
363         rte_free(txq);
364 }
365
366 static int
367 ntb_txq_setup(struct rte_rawdev *dev,
368               uint16_t qp_id,
369               rte_rawdev_obj_t queue_conf)
370 {
371         struct ntb_queue_conf *txq_conf = queue_conf;
372         struct ntb_hw *hw = dev->dev_private;
373         struct ntb_tx_queue *txq;
374         uint16_t i, prev;
375
376         /* Allocate the TX queue data structure. */
377         txq = rte_zmalloc_socket("ntb tx queue",
378                                   sizeof(struct ntb_tx_queue),
379                                   RTE_CACHE_LINE_SIZE,
380                                   dev->socket_id);
381         if (!txq) {
382                 NTB_LOG(ERR, "Failed to allocate memory for "
383                             "tx queue structure");
384                 return -ENOMEM;
385         }
386
387         txq->nb_tx_desc = txq_conf->nb_desc;
388         txq->port_id = dev->dev_id;
389         txq->queue_id = qp_id;
390         txq->hw = hw;
391
392         /* Allocate software ring */
393         txq->sw_ring =
394                 rte_zmalloc_socket("ntb tx sw ring",
395                                    sizeof(struct ntb_tx_entry) *
396                                    txq->nb_tx_desc,
397                                    RTE_CACHE_LINE_SIZE,
398                                    dev->socket_id);
399         if (!txq->sw_ring) {
400                 ntb_txq_release(txq);
401                 txq = NULL;
402                 NTB_LOG(ERR, "Failed to allocate memory for SW TX ring");
403                 return -ENOMEM;
404         }
405
406         prev = txq->nb_tx_desc - 1;
407         for (i = 0; i < txq->nb_tx_desc; i++) {
408                 txq->sw_ring[i].mbuf = NULL;
409                 txq->sw_ring[i].last_id = i;
410                 txq->sw_ring[prev].next_id = i;
411                 prev = i;
412         }
413
414         txq->tx_free_thresh = txq_conf->tx_free_thresh ?
415                               txq_conf->tx_free_thresh :
416                               NTB_DFLT_TX_FREE_THRESH;
417         if (txq->tx_free_thresh >= txq->nb_tx_desc - 3) {
418                 NTB_LOG(ERR, "tx_free_thresh must be less than nb_desc - 3. "
419                         "(tx_free_thresh=%u qp_id=%u)", txq->tx_free_thresh,
420                         qp_id);
421                 return -EINVAL;
422         }
423
424         hw->tx_queues[qp_id] = txq;
425
426         return 0;
427 }
428
429
430 static int
431 ntb_queue_setup(struct rte_rawdev *dev,
432                 uint16_t queue_id,
433                 rte_rawdev_obj_t queue_conf)
434 {
435         struct ntb_hw *hw = dev->dev_private;
436         int ret;
437
438         if (queue_id >= hw->queue_pairs)
439                 return -EINVAL;
440
441         ret = ntb_txq_setup(dev, queue_id, queue_conf);
442         if (ret < 0)
443                 return ret;
444
445         ret = ntb_rxq_setup(dev, queue_id, queue_conf);
446
447         return ret;
448 }
449
450 static int
451 ntb_queue_release(struct rte_rawdev *dev, uint16_t queue_id)
452 {
453         struct ntb_hw *hw = dev->dev_private;
454
455         if (queue_id >= hw->queue_pairs)
456                 return -EINVAL;
457
458         ntb_txq_release(hw->tx_queues[queue_id]);
459         hw->tx_queues[queue_id] = NULL;
460         ntb_rxq_release(hw->rx_queues[queue_id]);
461         hw->rx_queues[queue_id] = NULL;
462
463         return 0;
464 }
465
466 static uint16_t
467 ntb_queue_count(struct rte_rawdev *dev)
468 {
469         struct ntb_hw *hw = dev->dev_private;
470         return hw->queue_pairs;
471 }
472
473 static int
474 ntb_queue_init(struct rte_rawdev *dev, uint16_t qp_id)
475 {
476         struct ntb_hw *hw = dev->dev_private;
477         struct ntb_rx_queue *rxq = hw->rx_queues[qp_id];
478         struct ntb_tx_queue *txq = hw->tx_queues[qp_id];
479         volatile struct ntb_header *local_hdr;
480         struct ntb_header *remote_hdr;
481         uint16_t q_size = hw->queue_size;
482         uint32_t hdr_offset;
483         void *bar_addr;
484         uint16_t i;
485
486         if (hw->ntb_ops->get_peer_mw_addr == NULL) {
487                 NTB_LOG(ERR, "Getting peer mw addr is not supported.");
488                 return -EINVAL;
489         }
490
491         /* Put queue info into the start of shared memory. */
492         hdr_offset = hw->hdr_size_per_queue * qp_id;
493         local_hdr = (volatile struct ntb_header *)
494                     ((size_t)hw->mz[0]->addr + hdr_offset);
495         bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
496         if (bar_addr == NULL)
497                 return -EINVAL;
498         remote_hdr = (struct ntb_header *)
499                      ((size_t)bar_addr + hdr_offset);
500
501         /* rxq init. */
502         rxq->rx_desc_ring = (struct ntb_desc *)
503                             (&remote_hdr->desc_ring);
504         rxq->rx_used_ring = (volatile struct ntb_used *)
505                             (&local_hdr->desc_ring[q_size]);
506         rxq->avail_cnt = &remote_hdr->avail_cnt;
507         rxq->used_cnt = &local_hdr->used_cnt;
508
509         for (i = 0; i < rxq->nb_rx_desc - 1; i++) {
510                 struct rte_mbuf *mbuf = rte_mbuf_raw_alloc(rxq->mpool);
511                 if (unlikely(!mbuf)) {
512                         NTB_LOG(ERR, "Failed to allocate mbuf for RX");
513                         return -ENOMEM;
514                 }
515                 mbuf->port = dev->dev_id;
516
517                 rxq->sw_ring[i].mbuf = mbuf;
518
519                 rxq->rx_desc_ring[i].addr = rte_pktmbuf_mtod(mbuf, size_t);
520                 rxq->rx_desc_ring[i].len = mbuf->buf_len - RTE_PKTMBUF_HEADROOM;
521         }
522         rte_wmb();
523         *rxq->avail_cnt = rxq->nb_rx_desc - 1;
524         rxq->last_avail = rxq->nb_rx_desc - 1;
525         rxq->last_used = 0;
526
527         /* txq init */
528         txq->tx_desc_ring = (volatile struct ntb_desc *)
529                             (&local_hdr->desc_ring);
530         txq->tx_used_ring = (struct ntb_used *)
531                             (&remote_hdr->desc_ring[q_size]);
532         txq->avail_cnt = &local_hdr->avail_cnt;
533         txq->used_cnt = &remote_hdr->used_cnt;
534
535         rte_wmb();
536         *txq->used_cnt = 0;
537         txq->last_used = 0;
538         txq->last_avail = 0;
539         txq->nb_tx_free = txq->nb_tx_desc - 1;
540
541         return 0;
542 }
543
544 static int
545 ntb_enqueue_bufs(struct rte_rawdev *dev,
546                  struct rte_rawdev_buf **buffers,
547                  unsigned int count,
548                  rte_rawdev_obj_t context)
549 {
550         /* Not FIFO right now. Just for testing memory write. */
551         struct ntb_hw *hw = dev->dev_private;
552         unsigned int i;
553         void *bar_addr;
554         size_t size;
555
556         if (hw->ntb_ops->get_peer_mw_addr == NULL)
557                 return -ENOTSUP;
558         bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
559         size = (size_t)context;
560
561         for (i = 0; i < count; i++)
562                 rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
563         return 0;
564 }
565
566 static int
567 ntb_dequeue_bufs(struct rte_rawdev *dev,
568                  struct rte_rawdev_buf **buffers,
569                  unsigned int count,
570                  rte_rawdev_obj_t context)
571 {
572         /* Not FIFO. Just for testing memory read. */
573         struct ntb_hw *hw = dev->dev_private;
574         unsigned int i;
575         size_t size;
576
577         size = (size_t)context;
578
579         for (i = 0; i < count; i++)
580                 rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
581         return 0;
582 }
583
584 static void
585 ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
586 {
587         struct ntb_hw *hw = dev->dev_private;
588         struct ntb_dev_info *info = dev_info;
589
590         info->mw_cnt = hw->mw_cnt;
591         info->mw_size = hw->mw_size;
592
593         /**
594          * Intel hardware requires that mapped memory base address should be
595          * aligned with EMBARSZ and needs continuous memzone.
596          */
597         info->mw_size_align = (uint8_t)(hw->pci_dev->id.vendor_id ==
598                                         NTB_INTEL_VENDOR_ID);
599
600         if (!hw->queue_size || !hw->queue_pairs) {
601                 NTB_LOG(ERR, "No queue size and queue num assigned.");
602                 return;
603         }
604
605         hw->hdr_size_per_queue = RTE_ALIGN(sizeof(struct ntb_header) +
606                                 hw->queue_size * sizeof(struct ntb_desc) +
607                                 hw->queue_size * sizeof(struct ntb_used),
608                                 RTE_CACHE_LINE_SIZE);
609         info->ntb_hdr_size = hw->hdr_size_per_queue * hw->queue_pairs;
610 }
611
612 static int
613 ntb_dev_configure(const struct rte_rawdev *dev, rte_rawdev_obj_t config)
614 {
615         struct ntb_dev_config *conf = config;
616         struct ntb_hw *hw = dev->dev_private;
617         int ret;
618
619         hw->queue_pairs = conf->num_queues;
620         hw->queue_size = conf->queue_size;
621         hw->used_mw_num = conf->mz_num;
622         hw->mz = conf->mz_list;
623         hw->rx_queues = rte_zmalloc("ntb_rx_queues",
624                         sizeof(struct ntb_rx_queue *) * hw->queue_pairs, 0);
625         hw->tx_queues = rte_zmalloc("ntb_tx_queues",
626                         sizeof(struct ntb_tx_queue *) * hw->queue_pairs, 0);
627
628         /* Start handshake with the peer. */
629         ret = ntb_handshake_work(dev);
630         if (ret < 0) {
631                 rte_free(hw->rx_queues);
632                 rte_free(hw->tx_queues);
633                 hw->rx_queues = NULL;
634                 hw->tx_queues = NULL;
635                 return ret;
636         }
637
638         return 0;
639 }
640
641 static int
642 ntb_dev_start(struct rte_rawdev *dev)
643 {
644         struct ntb_hw *hw = dev->dev_private;
645         uint32_t peer_base_l, peer_val;
646         uint64_t peer_base_h;
647         uint32_t i;
648         int ret;
649
650         if (!hw->link_status || !hw->peer_dev_up)
651                 return -EINVAL;
652
653         for (i = 0; i < hw->queue_pairs; i++) {
654                 ret = ntb_queue_init(dev, i);
655                 if (ret) {
656                         NTB_LOG(ERR, "Failed to init queue.");
657                         goto err_q_init;
658                 }
659         }
660
661         hw->peer_mw_base = rte_zmalloc("ntb_peer_mw_base", hw->mw_cnt *
662                                         sizeof(uint64_t), 0);
663
664         if (hw->ntb_ops->spad_read == NULL) {
665                 ret = -ENOTSUP;
666                 goto err_up;
667         }
668
669         peer_val = (*hw->ntb_ops->spad_read)(dev, SPAD_Q_SZ, 0);
670         if (peer_val != hw->queue_size) {
671                 NTB_LOG(ERR, "Inconsistent queue size! (local: %u peer: %u)",
672                         hw->queue_size, peer_val);
673                 ret = -EINVAL;
674                 goto err_up;
675         }
676
677         peer_val = (*hw->ntb_ops->spad_read)(dev, SPAD_NUM_QPS, 0);
678         if (peer_val != hw->queue_pairs) {
679                 NTB_LOG(ERR, "Inconsistent number of queues! (local: %u peer:"
680                         " %u)", hw->queue_pairs, peer_val);
681                 ret = -EINVAL;
682                 goto err_up;
683         }
684
685         hw->peer_used_mws = (*hw->ntb_ops->spad_read)(dev, SPAD_USED_MWS, 0);
686
687         for (i = 0; i < hw->peer_used_mws; i++) {
688                 peer_base_h = (*hw->ntb_ops->spad_read)(dev,
689                                 SPAD_MW0_BA_H + 2 * i, 0);
690                 peer_base_l = (*hw->ntb_ops->spad_read)(dev,
691                                 SPAD_MW0_BA_L + 2 * i, 0);
692                 hw->peer_mw_base[i] = (peer_base_h << 32) + peer_base_l;
693         }
694
695         dev->started = 1;
696
697         return 0;
698
699 err_up:
700         rte_free(hw->peer_mw_base);
701 err_q_init:
702         for (i = 0; i < hw->queue_pairs; i++) {
703                 ntb_rxq_release_mbufs(hw->rx_queues[i]);
704                 ntb_txq_release_mbufs(hw->tx_queues[i]);
705         }
706
707         return ret;
708 }
709
710 static void
711 ntb_dev_stop(struct rte_rawdev *dev)
712 {
713         struct ntb_hw *hw = dev->dev_private;
714         uint32_t time_out;
715         int status, i;
716
717         if (!hw->peer_dev_up)
718                 goto clean;
719
720         ntb_link_cleanup(dev);
721
722         /* Notify the peer that device will be down. */
723         if (hw->ntb_ops->peer_db_set == NULL) {
724                 NTB_LOG(ERR, "Peer doorbell setting is not supported.");
725                 return;
726         }
727         status = (*hw->ntb_ops->peer_db_set)(dev, 1);
728         if (status) {
729                 NTB_LOG(ERR, "Failed to tell peer device is down.");
730                 return;
731         }
732
733         /*
734          * Set time out as 1s in case that the peer is stopped accidently
735          * without any notification.
736          */
737         time_out = 1000000;
738
739         /* Wait for cleanup work down before db mask clear. */
740         while (hw->peer_dev_up && time_out) {
741                 time_out -= 10;
742                 rte_delay_us(10);
743         }
744
745 clean:
746         /* Clear doorbells mask. */
747         if (hw->ntb_ops->db_set_mask == NULL) {
748                 NTB_LOG(ERR, "Doorbell mask setting is not supported.");
749                 return;
750         }
751         status = (*hw->ntb_ops->db_set_mask)(dev,
752                                 (((uint64_t)1 << hw->db_cnt) - 1));
753         if (status)
754                 NTB_LOG(ERR, "Failed to clear doorbells.");
755
756         for (i = 0; i < hw->queue_pairs; i++) {
757                 ntb_rxq_release_mbufs(hw->rx_queues[i]);
758                 ntb_txq_release_mbufs(hw->tx_queues[i]);
759         }
760
761         dev->started = 0;
762 }
763
764 static int
765 ntb_dev_close(struct rte_rawdev *dev)
766 {
767         struct ntb_hw *hw = dev->dev_private;
768         struct rte_intr_handle *intr_handle;
769         int i;
770
771         if (dev->started)
772                 ntb_dev_stop(dev);
773
774         /* free queues */
775         for (i = 0; i < hw->queue_pairs; i++)
776                 ntb_queue_release(dev, i);
777         hw->queue_pairs = 0;
778
779         intr_handle = &hw->pci_dev->intr_handle;
780         /* Clean datapath event and vec mapping */
781         rte_intr_efd_disable(intr_handle);
782         if (intr_handle->intr_vec) {
783                 rte_free(intr_handle->intr_vec);
784                 intr_handle->intr_vec = NULL;
785         }
786         /* Disable uio intr before callback unregister */
787         rte_intr_disable(intr_handle);
788
789         /* Unregister callback func to eal lib */
790         rte_intr_callback_unregister(intr_handle,
791                                      ntb_dev_intr_handler, dev);
792
793         return 0;
794 }
795
796 static int
797 ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
798 {
799         return 0;
800 }
801
802 static int
803 ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
804              uint64_t attr_value)
805 {
806         struct ntb_hw *hw;
807         int index;
808
809         if (dev == NULL || attr_name == NULL) {
810                 NTB_LOG(ERR, "Invalid arguments for setting attributes");
811                 return -EINVAL;
812         }
813
814         hw = dev->dev_private;
815
816         if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
817                 if (hw->ntb_ops->spad_write == NULL)
818                         return -ENOTSUP;
819                 index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
820                 (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index],
821                                            1, attr_value);
822                 NTB_LOG(DEBUG, "Set attribute (%s) Value (%" PRIu64 ")",
823                         attr_name, attr_value);
824                 return 0;
825         }
826
827         if (!strncmp(attr_name, NTB_QUEUE_SZ_NAME, NTB_ATTR_NAME_LEN)) {
828                 hw->queue_size = attr_value;
829                 NTB_LOG(DEBUG, "Set attribute (%s) Value (%" PRIu64 ")",
830                         attr_name, attr_value);
831                 return 0;
832         }
833
834         if (!strncmp(attr_name, NTB_QUEUE_NUM_NAME, NTB_ATTR_NAME_LEN)) {
835                 hw->queue_pairs = attr_value;
836                 NTB_LOG(DEBUG, "Set attribute (%s) Value (%" PRIu64 ")",
837                         attr_name, attr_value);
838                 return 0;
839         }
840
841         /* Attribute not found. */
842         NTB_LOG(ERR, "Attribute not found.");
843         return -EINVAL;
844 }
845
846 static int
847 ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
848              uint64_t *attr_value)
849 {
850         struct ntb_hw *hw;
851         int index;
852
853         if (dev == NULL || attr_name == NULL || attr_value == NULL) {
854                 NTB_LOG(ERR, "Invalid arguments for getting attributes");
855                 return -EINVAL;
856         }
857
858         hw = dev->dev_private;
859
860         if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
861                 *attr_value = hw->topo;
862                 NTB_LOG(DEBUG, "Attribute (%s) Value (%" PRIu64 ")",
863                         attr_name, *attr_value);
864                 return 0;
865         }
866
867         if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
868                 /* hw->link_status only indicates hw link status. */
869                 *attr_value = hw->link_status && hw->peer_dev_up;
870                 NTB_LOG(DEBUG, "Attribute (%s) Value (%" PRIu64 ")",
871                         attr_name, *attr_value);
872                 return 0;
873         }
874
875         if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
876                 *attr_value = hw->link_speed;
877                 NTB_LOG(DEBUG, "Attribute (%s) Value (%" PRIu64 ")",
878                         attr_name, *attr_value);
879                 return 0;
880         }
881
882         if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
883                 *attr_value = hw->link_width;
884                 NTB_LOG(DEBUG, "Attribute (%s) Value (%" PRIu64 ")",
885                         attr_name, *attr_value);
886                 return 0;
887         }
888
889         if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
890                 *attr_value = hw->mw_cnt;
891                 NTB_LOG(DEBUG, "Attribute (%s) Value (%" PRIu64 ")",
892                         attr_name, *attr_value);
893                 return 0;
894         }
895
896         if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
897                 *attr_value = hw->db_cnt;
898                 NTB_LOG(DEBUG, "Attribute (%s) Value (%" PRIu64 ")",
899                         attr_name, *attr_value);
900                 return 0;
901         }
902
903         if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
904                 *attr_value = hw->spad_cnt;
905                 NTB_LOG(DEBUG, "Attribute (%s) Value (%" PRIu64 ")",
906                         attr_name, *attr_value);
907                 return 0;
908         }
909
910         if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
911                 if (hw->ntb_ops->spad_read == NULL)
912                         return -ENOTSUP;
913                 index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
914                 *attr_value = (*hw->ntb_ops->spad_read)(dev,
915                                 hw->spad_user_list[index], 0);
916                 NTB_LOG(DEBUG, "Attribute (%s) Value (%" PRIu64 ")",
917                         attr_name, *attr_value);
918                 return 0;
919         }
920
921         /* Attribute not found. */
922         NTB_LOG(ERR, "Attribute not found.");
923         return -EINVAL;
924 }
925
926 static int
927 ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
928                const unsigned int ids[] __rte_unused,
929                uint64_t values[] __rte_unused,
930                unsigned int n __rte_unused)
931 {
932         return 0;
933 }
934
935 static int
936 ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
937                      struct rte_rawdev_xstats_name *xstats_names __rte_unused,
938                      unsigned int size __rte_unused)
939 {
940         return 0;
941 }
942
943 static uint64_t
944 ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
945                        const char *name __rte_unused,
946                        unsigned int *id __rte_unused)
947 {
948         return 0;
949 }
950
951 static int
952 ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
953                  const uint32_t ids[] __rte_unused,
954                  uint32_t nb_ids __rte_unused)
955 {
956         return 0;
957 }
958
959
960 static const struct rte_rawdev_ops ntb_ops = {
961         .dev_info_get         = ntb_dev_info_get,
962         .dev_configure        = ntb_dev_configure,
963         .dev_start            = ntb_dev_start,
964         .dev_stop             = ntb_dev_stop,
965         .dev_close            = ntb_dev_close,
966         .dev_reset            = ntb_dev_reset,
967
968         .queue_def_conf       = ntb_queue_conf_get,
969         .queue_setup          = ntb_queue_setup,
970         .queue_release        = ntb_queue_release,
971         .queue_count          = ntb_queue_count,
972
973         .enqueue_bufs         = ntb_enqueue_bufs,
974         .dequeue_bufs         = ntb_dequeue_bufs,
975
976         .attr_get             = ntb_attr_get,
977         .attr_set             = ntb_attr_set,
978
979         .xstats_get           = ntb_xstats_get,
980         .xstats_get_names     = ntb_xstats_get_names,
981         .xstats_get_by_name   = ntb_xstats_get_by_name,
982         .xstats_reset         = ntb_xstats_reset,
983 };
984
985 static int
986 ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
987 {
988         struct ntb_hw *hw = dev->dev_private;
989         struct rte_intr_handle *intr_handle;
990         int ret, i;
991
992         hw->pci_dev = pci_dev;
993         hw->peer_dev_up = 0;
994         hw->link_status = NTB_LINK_DOWN;
995         hw->link_speed = NTB_SPEED_NONE;
996         hw->link_width = NTB_WIDTH_NONE;
997
998         switch (pci_dev->id.device_id) {
999         case NTB_INTEL_DEV_ID_B2B_SKX:
1000                 hw->ntb_ops = &intel_ntb_ops;
1001                 break;
1002         default:
1003                 NTB_LOG(ERR, "Not supported device.");
1004                 return -EINVAL;
1005         }
1006
1007         if (hw->ntb_ops->ntb_dev_init == NULL)
1008                 return -ENOTSUP;
1009         ret = (*hw->ntb_ops->ntb_dev_init)(dev);
1010         if (ret) {
1011                 NTB_LOG(ERR, "Unable to init ntb dev.");
1012                 return ret;
1013         }
1014
1015         if (hw->ntb_ops->set_link == NULL)
1016                 return -ENOTSUP;
1017         ret = (*hw->ntb_ops->set_link)(dev, 1);
1018         if (ret)
1019                 return ret;
1020
1021         /* Init doorbell. */
1022         hw->db_valid_mask = RTE_LEN2MASK(hw->db_cnt, uint64_t);
1023
1024         intr_handle = &pci_dev->intr_handle;
1025         /* Register callback func to eal lib */
1026         rte_intr_callback_register(intr_handle,
1027                                    ntb_dev_intr_handler, dev);
1028
1029         ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
1030         if (ret)
1031                 return ret;
1032
1033         /* To clarify, the interrupt for each doorbell is already mapped
1034          * by default for intel gen3. They are mapped to msix vec 1-32,
1035          * and hardware intr is mapped to 0. Map all to 0 for uio.
1036          */
1037         if (!rte_intr_cap_multiple(intr_handle)) {
1038                 for (i = 0; i < hw->db_cnt; i++) {
1039                         if (hw->ntb_ops->vector_bind == NULL)
1040                                 return -ENOTSUP;
1041                         ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
1042                         if (ret)
1043                                 return ret;
1044                 }
1045         }
1046
1047         if (hw->ntb_ops->db_set_mask == NULL ||
1048             hw->ntb_ops->peer_db_set == NULL) {
1049                 NTB_LOG(ERR, "Doorbell is not supported.");
1050                 return -ENOTSUP;
1051         }
1052         hw->db_mask = 0;
1053         ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
1054         if (ret) {
1055                 NTB_LOG(ERR, "Unable to enable intr for all dbs.");
1056                 return ret;
1057         }
1058
1059         /* enable uio intr after callback register */
1060         rte_intr_enable(intr_handle);
1061
1062         return ret;
1063 }
1064
1065 static int
1066 ntb_create(struct rte_pci_device *pci_dev, int socket_id)
1067 {
1068         char name[RTE_RAWDEV_NAME_MAX_LEN];
1069         struct rte_rawdev *rawdev = NULL;
1070         int ret;
1071
1072         if (pci_dev == NULL) {
1073                 NTB_LOG(ERR, "Invalid pci_dev.");
1074                 return -EINVAL;
1075         }
1076
1077         memset(name, 0, sizeof(name));
1078         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
1079                  pci_dev->addr.bus, pci_dev->addr.devid,
1080                  pci_dev->addr.function);
1081
1082         NTB_LOG(INFO, "Init %s on NUMA node %d", name, socket_id);
1083
1084         /* Allocate device structure. */
1085         rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
1086                                          socket_id);
1087         if (rawdev == NULL) {
1088                 NTB_LOG(ERR, "Unable to allocate rawdev.");
1089                 return -EINVAL;
1090         }
1091
1092         rawdev->dev_ops = &ntb_ops;
1093         rawdev->device = &pci_dev->device;
1094         rawdev->driver_name = pci_dev->driver->driver.name;
1095
1096         ret = ntb_init_hw(rawdev, pci_dev);
1097         if (ret < 0) {
1098                 NTB_LOG(ERR, "Unable to init ntb hw.");
1099                 goto fail;
1100         }
1101
1102         return ret;
1103
1104 fail:
1105         if (rawdev != NULL)
1106                 rte_rawdev_pmd_release(rawdev);
1107
1108         return ret;
1109 }
1110
1111 static int
1112 ntb_destroy(struct rte_pci_device *pci_dev)
1113 {
1114         char name[RTE_RAWDEV_NAME_MAX_LEN];
1115         struct rte_rawdev *rawdev;
1116         int ret;
1117
1118         if (pci_dev == NULL) {
1119                 NTB_LOG(ERR, "Invalid pci_dev.");
1120                 ret = -EINVAL;
1121                 return ret;
1122         }
1123
1124         memset(name, 0, sizeof(name));
1125         snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
1126                  pci_dev->addr.bus, pci_dev->addr.devid,
1127                  pci_dev->addr.function);
1128
1129         NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
1130
1131         rawdev = rte_rawdev_pmd_get_named_dev(name);
1132         if (rawdev == NULL) {
1133                 NTB_LOG(ERR, "Invalid device name (%s)", name);
1134                 ret = -EINVAL;
1135                 return ret;
1136         }
1137
1138         ret = rte_rawdev_pmd_release(rawdev);
1139         if (ret)
1140                 NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
1141
1142         return ret;
1143 }
1144
1145 static int
1146 ntb_probe(struct rte_pci_driver *pci_drv __rte_unused,
1147         struct rte_pci_device *pci_dev)
1148 {
1149         return ntb_create(pci_dev, rte_socket_id());
1150 }
1151
1152 static int
1153 ntb_remove(struct rte_pci_device *pci_dev)
1154 {
1155         return ntb_destroy(pci_dev);
1156 }
1157
1158
1159 static struct rte_pci_driver rte_ntb_pmd = {
1160         .id_table = pci_id_ntb_map,
1161         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
1162         .probe = ntb_probe,
1163         .remove = ntb_remove,
1164 };
1165
1166 RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
1167 RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
1168 RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
1169
1170 RTE_INIT(ntb_init_log)
1171 {
1172         ntb_logtype = rte_log_register("pmd.raw.ntb");
1173         if (ntb_logtype >= 0)
1174                 rte_log_set_level(ntb_logtype, RTE_LOG_INFO);
1175 }