hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/platform/mellanox/mlxbf-tmfifo.c
....@@ -56,6 +56,7 @@
5656 * @vq: pointer to the virtio virtqueue
5757 * @desc: current descriptor of the pending packet
5858 * @desc_head: head descriptor of the pending packet
59
+ * @drop_desc: dummy desc for packet dropping
5960 * @cur_len: processed length of the current descriptor
6061 * @rem_len: remaining length of the pending packet
6162 * @pkt_len: total length of the pending packet
....@@ -72,6 +73,7 @@
7273 struct virtqueue *vq;
7374 struct vring_desc *desc;
7475 struct vring_desc *desc_head;
76
+ struct vring_desc drop_desc;
7577 int cur_len;
7678 int rem_len;
7779 u32 pkt_len;
....@@ -82,6 +84,14 @@
8284 int vdev_id;
8385 struct mlxbf_tmfifo *fifo;
8486 };
87
+
88
+/* Check whether vring is in drop mode. */
89
+#define IS_VRING_DROP(_r) ({ \
90
+ typeof(_r) (r) = (_r); \
91
+ (r->desc_head == &r->drop_desc ? true : false); })
92
+
93
+/* A stub length to drop maximum length packet. */
94
+#define VRING_DROP_DESC_MAX_LEN GENMASK(15, 0)
8595
8696 /* Interrupt types. */
8797 enum {
....@@ -195,7 +205,7 @@
195205 static efi_char16_t mlxbf_tmfifo_efi_name[] = L"RshimMacAddr";
196206
197207 /* Maximum L2 header length. */
198
-#define MLXBF_TMFIFO_NET_L2_OVERHEAD 36
208
+#define MLXBF_TMFIFO_NET_L2_OVERHEAD (ETH_HLEN + VLAN_HLEN)
199209
200210 /* Supported virtio-net features. */
201211 #define MLXBF_TMFIFO_NET_FEATURES \
....@@ -243,6 +253,7 @@
243253 vring->align = SMP_CACHE_BYTES;
244254 vring->index = i;
245255 vring->vdev_id = tm_vdev->vdev.id.device;
256
+ vring->drop_desc.len = VRING_DROP_DESC_MAX_LEN;
246257 dev = &tm_vdev->vdev.dev;
247258
248259 size = vring_size(vring->num, vring->align);
....@@ -348,7 +359,7 @@
348359 return len;
349360 }
350361
351
-static void mlxbf_tmfifo_release_pending_pkt(struct mlxbf_tmfifo_vring *vring)
362
+static void mlxbf_tmfifo_release_pkt(struct mlxbf_tmfifo_vring *vring)
352363 {
353364 struct vring_desc *desc_head;
354365 u32 len = 0;
....@@ -577,19 +588,25 @@
577588
578589 if (vring->cur_len + sizeof(u64) <= len) {
579590 /* The whole word. */
580
- if (is_rx)
581
- memcpy(addr + vring->cur_len, &data, sizeof(u64));
582
- else
583
- memcpy(&data, addr + vring->cur_len, sizeof(u64));
591
+ if (!IS_VRING_DROP(vring)) {
592
+ if (is_rx)
593
+ memcpy(addr + vring->cur_len, &data,
594
+ sizeof(u64));
595
+ else
596
+ memcpy(&data, addr + vring->cur_len,
597
+ sizeof(u64));
598
+ }
584599 vring->cur_len += sizeof(u64);
585600 } else {
586601 /* Leftover bytes. */
587
- if (is_rx)
588
- memcpy(addr + vring->cur_len, &data,
589
- len - vring->cur_len);
590
- else
591
- memcpy(&data, addr + vring->cur_len,
592
- len - vring->cur_len);
602
+ if (!IS_VRING_DROP(vring)) {
603
+ if (is_rx)
604
+ memcpy(addr + vring->cur_len, &data,
605
+ len - vring->cur_len);
606
+ else
607
+ memcpy(&data, addr + vring->cur_len,
608
+ len - vring->cur_len);
609
+ }
593610 vring->cur_len = len;
594611 }
595612
....@@ -606,13 +623,14 @@
606623 * flag is set.
607624 */
608625 static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring,
609
- struct vring_desc *desc,
626
+ struct vring_desc **desc,
610627 bool is_rx, bool *vring_change)
611628 {
612629 struct mlxbf_tmfifo *fifo = vring->fifo;
613630 struct virtio_net_config *config;
614631 struct mlxbf_tmfifo_msg_hdr hdr;
615632 int vdev_id, hdr_len;
633
+ bool drop_rx = false;
616634
617635 /* Read/Write packet header. */
618636 if (is_rx) {
....@@ -632,8 +650,8 @@
632650 if (ntohs(hdr.len) >
633651 __virtio16_to_cpu(virtio_legacy_is_little_endian(),
634652 config->mtu) +
635
- MLXBF_TMFIFO_NET_L2_OVERHEAD)
636
- return;
653
+ MLXBF_TMFIFO_NET_L2_OVERHEAD)
654
+ drop_rx = true;
637655 } else {
638656 vdev_id = VIRTIO_ID_CONSOLE;
639657 hdr_len = 0;
....@@ -648,16 +666,25 @@
648666
649667 if (!tm_dev2)
650668 return;
651
- vring->desc = desc;
669
+ vring->desc = *desc;
652670 vring = &tm_dev2->vrings[MLXBF_TMFIFO_VRING_RX];
653671 *vring_change = true;
654672 }
673
+
674
+ if (drop_rx && !IS_VRING_DROP(vring)) {
675
+ if (vring->desc_head)
676
+ mlxbf_tmfifo_release_pkt(vring);
677
+ *desc = &vring->drop_desc;
678
+ vring->desc_head = *desc;
679
+ vring->desc = *desc;
680
+ }
681
+
655682 vring->pkt_len = ntohs(hdr.len) + hdr_len;
656683 } else {
657684 /* Network virtio has an extra header. */
658685 hdr_len = (vring->vdev_id == VIRTIO_ID_NET) ?
659686 sizeof(struct virtio_net_hdr) : 0;
660
- vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, desc);
687
+ vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, *desc);
661688 hdr.type = (vring->vdev_id == VIRTIO_ID_NET) ?
662689 VIRTIO_ID_NET : VIRTIO_ID_CONSOLE;
663690 hdr.len = htons(vring->pkt_len - hdr_len);
....@@ -690,15 +717,23 @@
690717 /* Get the descriptor of the next packet. */
691718 if (!vring->desc) {
692719 desc = mlxbf_tmfifo_get_next_pkt(vring, is_rx);
693
- if (!desc)
694
- return false;
720
+ if (!desc) {
721
+ /* Drop next Rx packet to avoid stuck. */
722
+ if (is_rx) {
723
+ desc = &vring->drop_desc;
724
+ vring->desc_head = desc;
725
+ vring->desc = desc;
726
+ } else {
727
+ return false;
728
+ }
729
+ }
695730 } else {
696731 desc = vring->desc;
697732 }
698733
699734 /* Beginning of a packet. Start to Rx/Tx packet header. */
700735 if (vring->pkt_len == 0) {
701
- mlxbf_tmfifo_rxtx_header(vring, desc, is_rx, &vring_change);
736
+ mlxbf_tmfifo_rxtx_header(vring, &desc, is_rx, &vring_change);
702737 (*avail)--;
703738
704739 /* Return if new packet is for another ring. */
....@@ -724,17 +759,24 @@
724759 vring->rem_len -= len;
725760
726761 /* Get the next desc on the chain. */
727
- if (vring->rem_len > 0 &&
762
+ if (!IS_VRING_DROP(vring) && vring->rem_len > 0 &&
728763 (virtio16_to_cpu(vdev, desc->flags) & VRING_DESC_F_NEXT)) {
729764 idx = virtio16_to_cpu(vdev, desc->next);
730765 desc = &vr->desc[idx];
731766 goto mlxbf_tmfifo_desc_done;
732767 }
733768
734
- /* Done and release the pending packet. */
735
- mlxbf_tmfifo_release_pending_pkt(vring);
769
+ /* Done and release the packet. */
736770 desc = NULL;
737771 fifo->vring[is_rx] = NULL;
772
+ if (!IS_VRING_DROP(vring)) {
773
+ mlxbf_tmfifo_release_pkt(vring);
774
+ } else {
775
+ vring->pkt_len = 0;
776
+ vring->desc_head = NULL;
777
+ vring->desc = NULL;
778
+ return false;
779
+ }
738780
739781 /*
740782 * Make sure the load/store are in order before
....@@ -868,6 +910,7 @@
868910 tm_vdev = fifo->vdev[VIRTIO_ID_CONSOLE];
869911 mlxbf_tmfifo_console_output(tm_vdev, vring);
870912 spin_unlock_irqrestore(&fifo->spin_lock[0], flags);
913
+ set_bit(MLXBF_TM_TX_LWM_IRQ, &fifo->pend_events);
871914 } else if (test_and_set_bit(MLXBF_TM_TX_LWM_IRQ,
872915 &fifo->pend_events)) {
873916 return true;
....@@ -913,7 +956,7 @@
913956
914957 /* Release the pending packet. */
915958 if (vring->desc)
916
- mlxbf_tmfifo_release_pending_pkt(vring);
959
+ mlxbf_tmfifo_release_pkt(vring);
917960 vq = vring->vq;
918961 if (vq) {
919962 vring->vq = NULL;