.. | .. |
---|
1 | 1 | /* |
---|
2 | | - * Copyright(c) 2017 - 2018 Intel Corporation. |
---|
| 2 | + * Copyright(c) 2017 - 2020 Intel Corporation. |
---|
3 | 3 | * |
---|
4 | 4 | * This file is provided under a dual BSD/GPLv2 license. When using or |
---|
5 | 5 | * redistributing this file, you may do so under either license. |
---|
.. | .. |
---|
53 | 53 | #include <linux/if_vlan.h> |
---|
54 | 54 | |
---|
55 | 55 | #include "vnic.h" |
---|
| 56 | +#include "netdev.h" |
---|
56 | 57 | |
---|
57 | 58 | #define HFI_TX_TIMEOUT_MS 1000 |
---|
58 | 59 | |
---|
.. | .. |
---|
62 | 63 | |
---|
63 | 64 | static DEFINE_SPINLOCK(vport_cntr_lock); |
---|
64 | 65 | |
---|
65 | | -static int setup_vnic_ctxt(struct hfi1_devdata *dd, struct hfi1_ctxtdata *uctxt) |
---|
66 | | -{ |
---|
67 | | - unsigned int rcvctrl_ops = 0; |
---|
68 | | - int ret; |
---|
69 | | - |
---|
70 | | - uctxt->do_interrupt = &handle_receive_interrupt; |
---|
71 | | - |
---|
72 | | - /* Now allocate the RcvHdr queue and eager buffers. */ |
---|
73 | | - ret = hfi1_create_rcvhdrq(dd, uctxt); |
---|
74 | | - if (ret) |
---|
75 | | - goto done; |
---|
76 | | - |
---|
77 | | - ret = hfi1_setup_eagerbufs(uctxt); |
---|
78 | | - if (ret) |
---|
79 | | - goto done; |
---|
80 | | - |
---|
81 | | - if (uctxt->rcvhdrtail_kvaddr) |
---|
82 | | - clear_rcvhdrtail(uctxt); |
---|
83 | | - |
---|
84 | | - rcvctrl_ops = HFI1_RCVCTRL_CTXT_ENB; |
---|
85 | | - rcvctrl_ops |= HFI1_RCVCTRL_INTRAVAIL_ENB; |
---|
86 | | - |
---|
87 | | - if (!HFI1_CAP_KGET_MASK(uctxt->flags, MULTI_PKT_EGR)) |
---|
88 | | - rcvctrl_ops |= HFI1_RCVCTRL_ONE_PKT_EGR_ENB; |
---|
89 | | - if (HFI1_CAP_KGET_MASK(uctxt->flags, NODROP_EGR_FULL)) |
---|
90 | | - rcvctrl_ops |= HFI1_RCVCTRL_NO_EGR_DROP_ENB; |
---|
91 | | - if (HFI1_CAP_KGET_MASK(uctxt->flags, NODROP_RHQ_FULL)) |
---|
92 | | - rcvctrl_ops |= HFI1_RCVCTRL_NO_RHQ_DROP_ENB; |
---|
93 | | - if (HFI1_CAP_KGET_MASK(uctxt->flags, DMA_RTAIL)) |
---|
94 | | - rcvctrl_ops |= HFI1_RCVCTRL_TAILUPD_ENB; |
---|
95 | | - |
---|
96 | | - hfi1_rcvctrl(uctxt->dd, rcvctrl_ops, uctxt); |
---|
97 | | -done: |
---|
98 | | - return ret; |
---|
99 | | -} |
---|
100 | | - |
---|
101 | | -static int allocate_vnic_ctxt(struct hfi1_devdata *dd, |
---|
102 | | - struct hfi1_ctxtdata **vnic_ctxt) |
---|
103 | | -{ |
---|
104 | | - struct hfi1_ctxtdata *uctxt; |
---|
105 | | - int ret; |
---|
106 | | - |
---|
107 | | - if (dd->flags & HFI1_FROZEN) |
---|
108 | | - return -EIO; |
---|
109 | | - |
---|
110 | | - ret = hfi1_create_ctxtdata(dd->pport, dd->node, &uctxt); |
---|
111 | | - if (ret < 0) { |
---|
112 | | - dd_dev_err(dd, "Unable to create ctxtdata, failing open\n"); |
---|
113 | | - return -ENOMEM; |
---|
114 | | - } |
---|
115 | | - |
---|
116 | | - uctxt->flags = HFI1_CAP_KGET(MULTI_PKT_EGR) | |
---|
117 | | - HFI1_CAP_KGET(NODROP_RHQ_FULL) | |
---|
118 | | - HFI1_CAP_KGET(NODROP_EGR_FULL) | |
---|
119 | | - HFI1_CAP_KGET(DMA_RTAIL); |
---|
120 | | - uctxt->seq_cnt = 1; |
---|
121 | | - uctxt->is_vnic = true; |
---|
122 | | - |
---|
123 | | - hfi1_set_vnic_msix_info(uctxt); |
---|
124 | | - |
---|
125 | | - hfi1_stats.sps_ctxts++; |
---|
126 | | - dd_dev_dbg(dd, "created vnic context %d\n", uctxt->ctxt); |
---|
127 | | - *vnic_ctxt = uctxt; |
---|
128 | | - |
---|
129 | | - return 0; |
---|
130 | | -} |
---|
131 | | - |
---|
132 | | -static void deallocate_vnic_ctxt(struct hfi1_devdata *dd, |
---|
133 | | - struct hfi1_ctxtdata *uctxt) |
---|
134 | | -{ |
---|
135 | | - dd_dev_dbg(dd, "closing vnic context %d\n", uctxt->ctxt); |
---|
136 | | - flush_wc(); |
---|
137 | | - |
---|
138 | | - hfi1_reset_vnic_msix_info(uctxt); |
---|
139 | | - |
---|
140 | | - /* |
---|
141 | | - * Disable receive context and interrupt available, reset all |
---|
142 | | - * RcvCtxtCtrl bits to default values. |
---|
143 | | - */ |
---|
144 | | - hfi1_rcvctrl(dd, HFI1_RCVCTRL_CTXT_DIS | |
---|
145 | | - HFI1_RCVCTRL_TIDFLOW_DIS | |
---|
146 | | - HFI1_RCVCTRL_INTRAVAIL_DIS | |
---|
147 | | - HFI1_RCVCTRL_ONE_PKT_EGR_DIS | |
---|
148 | | - HFI1_RCVCTRL_NO_RHQ_DROP_DIS | |
---|
149 | | - HFI1_RCVCTRL_NO_EGR_DROP_DIS, uctxt); |
---|
150 | | - |
---|
151 | | - uctxt->event_flags = 0; |
---|
152 | | - |
---|
153 | | - hfi1_clear_tids(uctxt); |
---|
154 | | - hfi1_clear_ctxt_pkey(dd, uctxt); |
---|
155 | | - |
---|
156 | | - hfi1_stats.sps_ctxts--; |
---|
157 | | - |
---|
158 | | - hfi1_free_ctxt(uctxt); |
---|
159 | | -} |
---|
160 | | - |
---|
161 | | -void hfi1_vnic_setup(struct hfi1_devdata *dd) |
---|
162 | | -{ |
---|
163 | | - idr_init(&dd->vnic.vesw_idr); |
---|
164 | | -} |
---|
165 | | - |
---|
166 | | -void hfi1_vnic_cleanup(struct hfi1_devdata *dd) |
---|
167 | | -{ |
---|
168 | | - idr_destroy(&dd->vnic.vesw_idr); |
---|
169 | | -} |
---|
170 | | - |
---|
171 | 66 | #define SUM_GRP_COUNTERS(stats, qstats, x_grp) do { \ |
---|
172 | 67 | u64 *src64, *dst64; \ |
---|
173 | 68 | for (src64 = &qstats->x_grp.unicast, \ |
---|
.. | .. |
---|
176 | 71 | *dst64++ += *src64++; \ |
---|
177 | 72 | } \ |
---|
178 | 73 | } while (0) |
---|
| 74 | + |
---|
| 75 | +#define VNIC_MASK (0xFF) |
---|
| 76 | +#define VNIC_ID(val) ((1ull << 24) | ((val) & VNIC_MASK)) |
---|
179 | 77 | |
---|
180 | 78 | /* hfi1_vnic_update_stats - update statistics */ |
---|
181 | 79 | static void hfi1_vnic_update_stats(struct hfi1_vnic_vport_info *vinfo, |
---|
.. | .. |
---|
421 | 319 | |
---|
422 | 320 | static u16 hfi1_vnic_select_queue(struct net_device *netdev, |
---|
423 | 321 | struct sk_buff *skb, |
---|
424 | | - struct net_device *sb_dev, |
---|
425 | | - select_queue_fallback_t fallback) |
---|
| 322 | + struct net_device *sb_dev) |
---|
426 | 323 | { |
---|
427 | 324 | struct hfi1_vnic_vport_info *vinfo = opa_vnic_dev_priv(netdev); |
---|
428 | 325 | struct opa_vnic_skb_mdata *mdata; |
---|
.. | .. |
---|
453 | 350 | return rc; |
---|
454 | 351 | } |
---|
455 | 352 | |
---|
456 | | -static inline struct sk_buff *hfi1_vnic_get_skb(struct hfi1_vnic_rx_queue *rxq) |
---|
| 353 | +static struct hfi1_vnic_vport_info *get_vnic_port(struct hfi1_devdata *dd, |
---|
| 354 | + int vesw_id) |
---|
457 | 355 | { |
---|
458 | | - unsigned char *pad_info; |
---|
459 | | - struct sk_buff *skb; |
---|
| 356 | + int vnic_id = VNIC_ID(vesw_id); |
---|
460 | 357 | |
---|
461 | | - skb = skb_dequeue(&rxq->skbq); |
---|
462 | | - if (unlikely(!skb)) |
---|
| 358 | + return hfi1_netdev_get_data(dd, vnic_id); |
---|
| 359 | +} |
---|
| 360 | + |
---|
| 361 | +static struct hfi1_vnic_vport_info *get_first_vnic_port(struct hfi1_devdata *dd) |
---|
| 362 | +{ |
---|
| 363 | + struct hfi1_vnic_vport_info *vinfo; |
---|
| 364 | + int next_id = VNIC_ID(0); |
---|
| 365 | + |
---|
| 366 | + vinfo = hfi1_netdev_get_first_data(dd, &next_id); |
---|
| 367 | + |
---|
| 368 | + if (next_id > VNIC_ID(VNIC_MASK)) |
---|
463 | 369 | return NULL; |
---|
464 | 370 | |
---|
465 | | - /* remove tail padding and icrc */ |
---|
466 | | - pad_info = skb->data + skb->len - 1; |
---|
467 | | - skb_trim(skb, (skb->len - OPA_VNIC_ICRC_TAIL_LEN - |
---|
468 | | - ((*pad_info) & 0x7))); |
---|
469 | | - |
---|
470 | | - return skb; |
---|
471 | | -} |
---|
472 | | - |
---|
473 | | -/* hfi1_vnic_handle_rx - handle skb receive */ |
---|
474 | | -static void hfi1_vnic_handle_rx(struct hfi1_vnic_rx_queue *rxq, |
---|
475 | | - int *work_done, int work_to_do) |
---|
476 | | -{ |
---|
477 | | - struct hfi1_vnic_vport_info *vinfo = rxq->vinfo; |
---|
478 | | - struct sk_buff *skb; |
---|
479 | | - int rc; |
---|
480 | | - |
---|
481 | | - while (1) { |
---|
482 | | - if (*work_done >= work_to_do) |
---|
483 | | - break; |
---|
484 | | - |
---|
485 | | - skb = hfi1_vnic_get_skb(rxq); |
---|
486 | | - if (unlikely(!skb)) |
---|
487 | | - break; |
---|
488 | | - |
---|
489 | | - rc = hfi1_vnic_decap_skb(rxq, skb); |
---|
490 | | - /* update rx counters */ |
---|
491 | | - hfi1_vnic_update_rx_counters(vinfo, rxq->idx, skb, rc); |
---|
492 | | - if (unlikely(rc)) { |
---|
493 | | - dev_kfree_skb_any(skb); |
---|
494 | | - continue; |
---|
495 | | - } |
---|
496 | | - |
---|
497 | | - skb_checksum_none_assert(skb); |
---|
498 | | - skb->protocol = eth_type_trans(skb, rxq->netdev); |
---|
499 | | - |
---|
500 | | - napi_gro_receive(&rxq->napi, skb); |
---|
501 | | - (*work_done)++; |
---|
502 | | - } |
---|
503 | | -} |
---|
504 | | - |
---|
505 | | -/* hfi1_vnic_napi - napi receive polling callback function */ |
---|
506 | | -static int hfi1_vnic_napi(struct napi_struct *napi, int budget) |
---|
507 | | -{ |
---|
508 | | - struct hfi1_vnic_rx_queue *rxq = container_of(napi, |
---|
509 | | - struct hfi1_vnic_rx_queue, napi); |
---|
510 | | - struct hfi1_vnic_vport_info *vinfo = rxq->vinfo; |
---|
511 | | - int work_done = 0; |
---|
512 | | - |
---|
513 | | - v_dbg("napi %d budget %d\n", rxq->idx, budget); |
---|
514 | | - hfi1_vnic_handle_rx(rxq, &work_done, budget); |
---|
515 | | - |
---|
516 | | - v_dbg("napi %d work_done %d\n", rxq->idx, work_done); |
---|
517 | | - if (work_done < budget) |
---|
518 | | - napi_complete(napi); |
---|
519 | | - |
---|
520 | | - return work_done; |
---|
| 371 | + return vinfo; |
---|
521 | 372 | } |
---|
522 | 373 | |
---|
523 | 374 | void hfi1_vnic_bypass_rcv(struct hfi1_packet *packet) |
---|
.. | .. |
---|
526 | 377 | struct hfi1_vnic_vport_info *vinfo = NULL; |
---|
527 | 378 | struct hfi1_vnic_rx_queue *rxq; |
---|
528 | 379 | struct sk_buff *skb; |
---|
529 | | - int l4_type, vesw_id = -1; |
---|
| 380 | + int l4_type, vesw_id = -1, rc; |
---|
530 | 381 | u8 q_idx; |
---|
| 382 | + unsigned char *pad_info; |
---|
531 | 383 | |
---|
532 | 384 | l4_type = hfi1_16B_get_l4(packet->ebuf); |
---|
533 | 385 | if (likely(l4_type == OPA_16B_L4_ETHR)) { |
---|
534 | 386 | vesw_id = HFI1_VNIC_GET_VESWID(packet->ebuf); |
---|
535 | | - vinfo = idr_find(&dd->vnic.vesw_idr, vesw_id); |
---|
| 387 | + vinfo = get_vnic_port(dd, vesw_id); |
---|
536 | 388 | |
---|
537 | 389 | /* |
---|
538 | 390 | * In case of invalid vesw id, count the error on |
---|
.. | .. |
---|
540 | 392 | */ |
---|
541 | 393 | if (unlikely(!vinfo)) { |
---|
542 | 394 | struct hfi1_vnic_vport_info *vinfo_tmp; |
---|
543 | | - int id_tmp = 0; |
---|
544 | 395 | |
---|
545 | | - vinfo_tmp = idr_get_next(&dd->vnic.vesw_idr, &id_tmp); |
---|
| 396 | + vinfo_tmp = get_first_vnic_port(dd); |
---|
546 | 397 | if (vinfo_tmp) { |
---|
547 | 398 | spin_lock(&vport_cntr_lock); |
---|
548 | 399 | vinfo_tmp->stats[0].netstats.rx_nohandler++; |
---|
.. | .. |
---|
561 | 412 | rxq = &vinfo->rxq[q_idx]; |
---|
562 | 413 | if (unlikely(!netif_oper_up(vinfo->netdev))) { |
---|
563 | 414 | vinfo->stats[q_idx].rx_drop_state++; |
---|
564 | | - skb_queue_purge(&rxq->skbq); |
---|
565 | | - return; |
---|
566 | | - } |
---|
567 | | - |
---|
568 | | - if (unlikely(skb_queue_len(&rxq->skbq) > HFI1_VNIC_RCV_Q_SIZE)) { |
---|
569 | | - vinfo->stats[q_idx].netstats.rx_fifo_errors++; |
---|
570 | 415 | return; |
---|
571 | 416 | } |
---|
572 | 417 | |
---|
.. | .. |
---|
578 | 423 | |
---|
579 | 424 | memcpy(skb->data, packet->ebuf, packet->tlen); |
---|
580 | 425 | skb_put(skb, packet->tlen); |
---|
581 | | - skb_queue_tail(&rxq->skbq, skb); |
---|
582 | 426 | |
---|
583 | | - if (napi_schedule_prep(&rxq->napi)) { |
---|
584 | | - v_dbg("napi %d scheduling\n", q_idx); |
---|
585 | | - __napi_schedule(&rxq->napi); |
---|
| 427 | + pad_info = skb->data + skb->len - 1; |
---|
| 428 | + skb_trim(skb, (skb->len - OPA_VNIC_ICRC_TAIL_LEN - |
---|
| 429 | + ((*pad_info) & 0x7))); |
---|
| 430 | + |
---|
| 431 | + rc = hfi1_vnic_decap_skb(rxq, skb); |
---|
| 432 | + |
---|
| 433 | + /* update rx counters */ |
---|
| 434 | + hfi1_vnic_update_rx_counters(vinfo, rxq->idx, skb, rc); |
---|
| 435 | + if (unlikely(rc)) { |
---|
| 436 | + dev_kfree_skb_any(skb); |
---|
| 437 | + return; |
---|
586 | 438 | } |
---|
| 439 | + |
---|
| 440 | + skb_checksum_none_assert(skb); |
---|
| 441 | + skb->protocol = eth_type_trans(skb, rxq->netdev); |
---|
| 442 | + |
---|
| 443 | + napi_gro_receive(&rxq->napi, skb); |
---|
587 | 444 | } |
---|
588 | 445 | |
---|
589 | 446 | static int hfi1_vnic_up(struct hfi1_vnic_vport_info *vinfo) |
---|
590 | 447 | { |
---|
591 | 448 | struct hfi1_devdata *dd = vinfo->dd; |
---|
592 | 449 | struct net_device *netdev = vinfo->netdev; |
---|
593 | | - int i, rc; |
---|
| 450 | + int rc; |
---|
594 | 451 | |
---|
595 | 452 | /* ensure virtual eth switch id is valid */ |
---|
596 | 453 | if (!vinfo->vesw_id) |
---|
597 | 454 | return -EINVAL; |
---|
598 | 455 | |
---|
599 | | - rc = idr_alloc(&dd->vnic.vesw_idr, vinfo, vinfo->vesw_id, |
---|
600 | | - vinfo->vesw_id + 1, GFP_NOWAIT); |
---|
| 456 | + rc = hfi1_netdev_add_data(dd, VNIC_ID(vinfo->vesw_id), vinfo); |
---|
601 | 457 | if (rc < 0) |
---|
602 | 458 | return rc; |
---|
603 | 459 | |
---|
604 | | - for (i = 0; i < vinfo->num_rx_q; i++) { |
---|
605 | | - struct hfi1_vnic_rx_queue *rxq = &vinfo->rxq[i]; |
---|
606 | | - |
---|
607 | | - skb_queue_head_init(&rxq->skbq); |
---|
608 | | - napi_enable(&rxq->napi); |
---|
609 | | - } |
---|
| 460 | + rc = hfi1_netdev_rx_init(dd); |
---|
| 461 | + if (rc) |
---|
| 462 | + goto err_remove; |
---|
610 | 463 | |
---|
611 | 464 | netif_carrier_on(netdev); |
---|
612 | 465 | netif_tx_start_all_queues(netdev); |
---|
613 | 466 | set_bit(HFI1_VNIC_UP, &vinfo->flags); |
---|
614 | 467 | |
---|
615 | 468 | return 0; |
---|
| 469 | + |
---|
| 470 | +err_remove: |
---|
| 471 | + hfi1_netdev_remove_data(dd, VNIC_ID(vinfo->vesw_id)); |
---|
| 472 | + return rc; |
---|
616 | 473 | } |
---|
617 | 474 | |
---|
618 | 475 | static void hfi1_vnic_down(struct hfi1_vnic_vport_info *vinfo) |
---|
619 | 476 | { |
---|
620 | 477 | struct hfi1_devdata *dd = vinfo->dd; |
---|
621 | | - u8 i; |
---|
622 | 478 | |
---|
623 | 479 | clear_bit(HFI1_VNIC_UP, &vinfo->flags); |
---|
624 | 480 | netif_carrier_off(vinfo->netdev); |
---|
625 | 481 | netif_tx_disable(vinfo->netdev); |
---|
626 | | - idr_remove(&dd->vnic.vesw_idr, vinfo->vesw_id); |
---|
| 482 | + hfi1_netdev_remove_data(dd, VNIC_ID(vinfo->vesw_id)); |
---|
627 | 483 | |
---|
628 | | - /* ensure irqs see the change */ |
---|
629 | | - hfi1_vnic_synchronize_irq(dd); |
---|
630 | | - |
---|
631 | | - /* remove unread skbs */ |
---|
632 | | - for (i = 0; i < vinfo->num_rx_q; i++) { |
---|
633 | | - struct hfi1_vnic_rx_queue *rxq = &vinfo->rxq[i]; |
---|
634 | | - |
---|
635 | | - napi_disable(&rxq->napi); |
---|
636 | | - skb_queue_purge(&rxq->skbq); |
---|
637 | | - } |
---|
| 484 | + hfi1_netdev_rx_destroy(dd); |
---|
638 | 485 | } |
---|
639 | 486 | |
---|
640 | 487 | static int hfi1_netdev_open(struct net_device *netdev) |
---|
.. | .. |
---|
659 | 506 | return 0; |
---|
660 | 507 | } |
---|
661 | 508 | |
---|
662 | | -static int hfi1_vnic_allot_ctxt(struct hfi1_devdata *dd, |
---|
663 | | - struct hfi1_ctxtdata **vnic_ctxt) |
---|
664 | | -{ |
---|
665 | | - int rc; |
---|
666 | | - |
---|
667 | | - rc = allocate_vnic_ctxt(dd, vnic_ctxt); |
---|
668 | | - if (rc) { |
---|
669 | | - dd_dev_err(dd, "vnic ctxt alloc failed %d\n", rc); |
---|
670 | | - return rc; |
---|
671 | | - } |
---|
672 | | - |
---|
673 | | - rc = setup_vnic_ctxt(dd, *vnic_ctxt); |
---|
674 | | - if (rc) { |
---|
675 | | - dd_dev_err(dd, "vnic ctxt setup failed %d\n", rc); |
---|
676 | | - deallocate_vnic_ctxt(dd, *vnic_ctxt); |
---|
677 | | - *vnic_ctxt = NULL; |
---|
678 | | - } |
---|
679 | | - |
---|
680 | | - return rc; |
---|
681 | | -} |
---|
682 | | - |
---|
683 | 509 | static int hfi1_vnic_init(struct hfi1_vnic_vport_info *vinfo) |
---|
684 | 510 | { |
---|
685 | 511 | struct hfi1_devdata *dd = vinfo->dd; |
---|
686 | | - int i, rc = 0; |
---|
| 512 | + int rc = 0; |
---|
687 | 513 | |
---|
688 | 514 | mutex_lock(&hfi1_mutex); |
---|
689 | | - if (!dd->vnic.num_vports) { |
---|
| 515 | + if (!dd->vnic_num_vports) { |
---|
690 | 516 | rc = hfi1_vnic_txreq_init(dd); |
---|
691 | 517 | if (rc) |
---|
692 | 518 | goto txreq_fail; |
---|
693 | | - |
---|
694 | | - dd->vnic.msix_idx = dd->first_dyn_msix_idx; |
---|
695 | 519 | } |
---|
696 | 520 | |
---|
697 | | - for (i = dd->vnic.num_ctxt; i < vinfo->num_rx_q; i++) { |
---|
698 | | - rc = hfi1_vnic_allot_ctxt(dd, &dd->vnic.ctxt[i]); |
---|
699 | | - if (rc) |
---|
700 | | - break; |
---|
701 | | - hfi1_rcd_get(dd->vnic.ctxt[i]); |
---|
702 | | - dd->vnic.ctxt[i]->vnic_q_idx = i; |
---|
703 | | - } |
---|
704 | | - |
---|
705 | | - if (i < vinfo->num_rx_q) { |
---|
706 | | - /* |
---|
707 | | - * If required amount of contexts is not |
---|
708 | | - * allocated successfully then remaining contexts |
---|
709 | | - * are released. |
---|
710 | | - */ |
---|
711 | | - while (i-- > dd->vnic.num_ctxt) { |
---|
712 | | - deallocate_vnic_ctxt(dd, dd->vnic.ctxt[i]); |
---|
713 | | - hfi1_rcd_put(dd->vnic.ctxt[i]); |
---|
714 | | - dd->vnic.ctxt[i] = NULL; |
---|
715 | | - } |
---|
| 521 | + rc = hfi1_netdev_rx_init(dd); |
---|
| 522 | + if (rc) { |
---|
| 523 | + dd_dev_err(dd, "Unable to initialize netdev contexts\n"); |
---|
716 | 524 | goto alloc_fail; |
---|
717 | 525 | } |
---|
718 | 526 | |
---|
719 | | - if (dd->vnic.num_ctxt != i) { |
---|
720 | | - dd->vnic.num_ctxt = i; |
---|
721 | | - hfi1_init_vnic_rsm(dd); |
---|
722 | | - } |
---|
| 527 | + hfi1_init_vnic_rsm(dd); |
---|
723 | 528 | |
---|
724 | | - dd->vnic.num_vports++; |
---|
| 529 | + dd->vnic_num_vports++; |
---|
725 | 530 | hfi1_vnic_sdma_init(vinfo); |
---|
| 531 | + |
---|
726 | 532 | alloc_fail: |
---|
727 | | - if (!dd->vnic.num_vports) |
---|
| 533 | + if (!dd->vnic_num_vports) |
---|
728 | 534 | hfi1_vnic_txreq_deinit(dd); |
---|
729 | 535 | txreq_fail: |
---|
730 | 536 | mutex_unlock(&hfi1_mutex); |
---|
.. | .. |
---|
734 | 540 | static void hfi1_vnic_deinit(struct hfi1_vnic_vport_info *vinfo) |
---|
735 | 541 | { |
---|
736 | 542 | struct hfi1_devdata *dd = vinfo->dd; |
---|
737 | | - int i; |
---|
738 | 543 | |
---|
739 | 544 | mutex_lock(&hfi1_mutex); |
---|
740 | | - if (--dd->vnic.num_vports == 0) { |
---|
741 | | - for (i = 0; i < dd->vnic.num_ctxt; i++) { |
---|
742 | | - deallocate_vnic_ctxt(dd, dd->vnic.ctxt[i]); |
---|
743 | | - hfi1_rcd_put(dd->vnic.ctxt[i]); |
---|
744 | | - dd->vnic.ctxt[i] = NULL; |
---|
745 | | - } |
---|
| 545 | + if (--dd->vnic_num_vports == 0) { |
---|
746 | 546 | hfi1_deinit_vnic_rsm(dd); |
---|
747 | | - dd->vnic.num_ctxt = 0; |
---|
748 | 547 | hfi1_vnic_txreq_deinit(dd); |
---|
749 | 548 | } |
---|
750 | 549 | mutex_unlock(&hfi1_mutex); |
---|
| 550 | + hfi1_netdev_rx_destroy(dd); |
---|
751 | 551 | } |
---|
752 | 552 | |
---|
753 | 553 | static void hfi1_vnic_set_vesw_id(struct net_device *netdev, int id) |
---|
.. | .. |
---|
805 | 605 | struct rdma_netdev *rn; |
---|
806 | 606 | int i, size, rc; |
---|
807 | 607 | |
---|
808 | | - if (!dd->num_vnic_contexts) |
---|
| 608 | + if (!dd->num_netdev_contexts) |
---|
809 | 609 | return ERR_PTR(-ENOMEM); |
---|
810 | 610 | |
---|
811 | 611 | if (!port_num || (port_num > dd->num_pports)) |
---|
.. | .. |
---|
816 | 616 | |
---|
817 | 617 | size = sizeof(struct opa_vnic_rdma_netdev) + sizeof(*vinfo); |
---|
818 | 618 | netdev = alloc_netdev_mqs(size, name, name_assign_type, setup, |
---|
819 | | - chip_sdma_engines(dd), dd->num_vnic_contexts); |
---|
| 619 | + chip_sdma_engines(dd), |
---|
| 620 | + dd->num_netdev_contexts); |
---|
820 | 621 | if (!netdev) |
---|
821 | 622 | return ERR_PTR(-ENOMEM); |
---|
822 | 623 | |
---|
.. | .. |
---|
824 | 625 | vinfo = opa_vnic_dev_priv(netdev); |
---|
825 | 626 | vinfo->dd = dd; |
---|
826 | 627 | vinfo->num_tx_q = chip_sdma_engines(dd); |
---|
827 | | - vinfo->num_rx_q = dd->num_vnic_contexts; |
---|
| 628 | + vinfo->num_rx_q = dd->num_netdev_contexts; |
---|
828 | 629 | vinfo->netdev = netdev; |
---|
829 | 630 | rn->free_rdma_netdev = hfi1_vnic_free_rn; |
---|
830 | 631 | rn->set_id = hfi1_vnic_set_vesw_id; |
---|
.. | .. |
---|
842 | 643 | rxq->idx = i; |
---|
843 | 644 | rxq->vinfo = vinfo; |
---|
844 | 645 | rxq->netdev = netdev; |
---|
845 | | - netif_napi_add(netdev, &rxq->napi, hfi1_vnic_napi, 64); |
---|
846 | 646 | } |
---|
847 | 647 | |
---|
848 | 648 | rc = hfi1_vnic_init(vinfo); |
---|