@@ -59,6 +59,7 @@ struct mlxbf_tmfifo;
5959 * @vq: pointer to the virtio virtqueue
6060 * @desc: current descriptor of the pending packet
6161 * @desc_head: head descriptor of the pending packet
62+ * @drop_desc: dummy desc for packet dropping
6263 * @cur_len: processed length of the current descriptor
6364 * @rem_len: remaining length of the pending packet
6465 * @pkt_len: total length of the pending packet
@@ -75,6 +76,7 @@ struct mlxbf_tmfifo_vring {
7576 struct virtqueue * vq ;
7677 struct vring_desc * desc ;
7778 struct vring_desc * desc_head ;
79+ struct vring_desc drop_desc ;
7880 int cur_len ;
7981 int rem_len ;
8082 u32 pkt_len ;
@@ -86,6 +88,14 @@ struct mlxbf_tmfifo_vring {
8688 struct mlxbf_tmfifo * fifo ;
8789};
8890
91+ /* Check whether vring is in drop mode. */
92+ #define IS_VRING_DROP (_r ) ({ \
93+ typeof(_r) (r) = (_r); \
94+ (r->desc_head == &r->drop_desc ? true : false); })
95+
96+ /* A stub length to drop maximum length packet. */
97+ #define VRING_DROP_DESC_MAX_LEN GENMASK(15, 0)
98+
8999/* Interrupt types. */
90100enum {
91101 MLXBF_TM_RX_LWM_IRQ ,
@@ -214,7 +224,7 @@ static u8 mlxbf_tmfifo_net_default_mac[ETH_ALEN] = {
214224static efi_char16_t mlxbf_tmfifo_efi_name [] = L"RshimMacAddr" ;
215225
216226/* Maximum L2 header length. */
217- #define MLXBF_TMFIFO_NET_L2_OVERHEAD 36
227+ #define MLXBF_TMFIFO_NET_L2_OVERHEAD (ETH_HLEN + VLAN_HLEN)
218228
219229/* Supported virtio-net features. */
220230#define MLXBF_TMFIFO_NET_FEATURES \
@@ -262,6 +272,7 @@ static int mlxbf_tmfifo_alloc_vrings(struct mlxbf_tmfifo *fifo,
262272 vring -> align = SMP_CACHE_BYTES ;
263273 vring -> index = i ;
264274 vring -> vdev_id = tm_vdev -> vdev .id .device ;
275+ vring -> drop_desc .len = VRING_DROP_DESC_MAX_LEN ;
265276 dev = & tm_vdev -> vdev .dev ;
266277
267278 size = vring_size (vring -> num , vring -> align );
@@ -367,7 +378,7 @@ static u32 mlxbf_tmfifo_get_pkt_len(struct mlxbf_tmfifo_vring *vring,
367378 return len ;
368379}
369380
370- static void mlxbf_tmfifo_release_pending_pkt (struct mlxbf_tmfifo_vring * vring )
381+ static void mlxbf_tmfifo_release_pkt (struct mlxbf_tmfifo_vring * vring )
371382{
372383 struct vring_desc * desc_head ;
373384 u32 len = 0 ;
@@ -596,19 +607,25 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring,
596607
597608 if (vring -> cur_len + sizeof (u64 ) <= len ) {
598609 /* The whole word. */
599- if (is_rx )
600- memcpy (addr + vring -> cur_len , & data , sizeof (u64 ));
601- else
602- memcpy (& data , addr + vring -> cur_len , sizeof (u64 ));
610+ if (!IS_VRING_DROP (vring )) {
611+ if (is_rx )
612+ memcpy (addr + vring -> cur_len , & data ,
613+ sizeof (u64 ));
614+ else
615+ memcpy (& data , addr + vring -> cur_len ,
616+ sizeof (u64 ));
617+ }
603618 vring -> cur_len += sizeof (u64 );
604619 } else {
605620 /* Leftover bytes. */
606- if (is_rx )
607- memcpy (addr + vring -> cur_len , & data ,
608- len - vring -> cur_len );
609- else
610- memcpy (& data , addr + vring -> cur_len ,
611- len - vring -> cur_len );
621+ if (!IS_VRING_DROP (vring )) {
622+ if (is_rx )
623+ memcpy (addr + vring -> cur_len , & data ,
624+ len - vring -> cur_len );
625+ else
626+ memcpy (& data , addr + vring -> cur_len ,
627+ len - vring -> cur_len );
628+ }
612629 vring -> cur_len = len ;
613630 }
614631
@@ -625,13 +642,14 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring,
625642 * flag is set.
626643 */
627644static void mlxbf_tmfifo_rxtx_header (struct mlxbf_tmfifo_vring * vring ,
628- struct vring_desc * desc ,
645+ struct vring_desc * * desc ,
629646 bool is_rx , bool * vring_change )
630647{
631648 struct mlxbf_tmfifo * fifo = vring -> fifo ;
632649 struct virtio_net_config * config ;
633650 struct mlxbf_tmfifo_msg_hdr hdr ;
634651 int vdev_id , hdr_len ;
652+ bool drop_rx = false;
635653
636654 /* Read/Write packet header. */
637655 if (is_rx ) {
@@ -651,8 +669,8 @@ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring,
651669 if (ntohs (hdr .len ) >
652670 __virtio16_to_cpu (virtio_legacy_is_little_endian (),
653671 config -> mtu ) +
654- MLXBF_TMFIFO_NET_L2_OVERHEAD )
655- return ;
672+ MLXBF_TMFIFO_NET_L2_OVERHEAD )
673+ drop_rx = true ;
656674 } else {
657675 vdev_id = VIRTIO_ID_CONSOLE ;
658676 hdr_len = 0 ;
@@ -667,16 +685,25 @@ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring,
667685
668686 if (!tm_dev2 )
669687 return ;
670- vring -> desc = desc ;
688+ vring -> desc = * desc ;
671689 vring = & tm_dev2 -> vrings [MLXBF_TMFIFO_VRING_RX ];
672690 * vring_change = true;
673691 }
692+
693+ if (drop_rx && !IS_VRING_DROP (vring )) {
694+ if (vring -> desc_head )
695+ mlxbf_tmfifo_release_pkt (vring );
696+ * desc = & vring -> drop_desc ;
697+ vring -> desc_head = * desc ;
698+ vring -> desc = * desc ;
699+ }
700+
674701 vring -> pkt_len = ntohs (hdr .len ) + hdr_len ;
675702 } else {
676703 /* Network virtio has an extra header. */
677704 hdr_len = (vring -> vdev_id == VIRTIO_ID_NET ) ?
678705 sizeof (struct virtio_net_hdr ) : 0 ;
679- vring -> pkt_len = mlxbf_tmfifo_get_pkt_len (vring , desc );
706+ vring -> pkt_len = mlxbf_tmfifo_get_pkt_len (vring , * desc );
680707 hdr .type = (vring -> vdev_id == VIRTIO_ID_NET ) ?
681708 VIRTIO_ID_NET : VIRTIO_ID_CONSOLE ;
682709 hdr .len = htons (vring -> pkt_len - hdr_len );
@@ -709,15 +736,23 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring,
709736 /* Get the descriptor of the next packet. */
710737 if (!vring -> desc ) {
711738 desc = mlxbf_tmfifo_get_next_pkt (vring , is_rx );
712- if (!desc )
713- return false;
739+ if (!desc ) {
740+ /* Drop next Rx packet to avoid stuck. */
741+ if (is_rx ) {
742+ desc = & vring -> drop_desc ;
743+ vring -> desc_head = desc ;
744+ vring -> desc = desc ;
745+ } else {
746+ return false;
747+ }
748+ }
714749 } else {
715750 desc = vring -> desc ;
716751 }
717752
718753 /* Beginning of a packet. Start to Rx/Tx packet header. */
719754 if (vring -> pkt_len == 0 ) {
720- mlxbf_tmfifo_rxtx_header (vring , desc , is_rx , & vring_change );
755+ mlxbf_tmfifo_rxtx_header (vring , & desc , is_rx , & vring_change );
721756 (* avail )-- ;
722757
723758 /* Return if new packet is for another ring. */
@@ -743,17 +778,24 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring,
743778 vring -> rem_len -= len ;
744779
745780 /* Get the next desc on the chain. */
746- if (vring -> rem_len > 0 &&
781+ if (! IS_VRING_DROP ( vring ) && vring -> rem_len > 0 &&
747782 (virtio16_to_cpu (vdev , desc -> flags ) & VRING_DESC_F_NEXT )) {
748783 idx = virtio16_to_cpu (vdev , desc -> next );
749784 desc = & vr -> desc [idx ];
750785 goto mlxbf_tmfifo_desc_done ;
751786 }
752787
753- /* Done and release the pending packet. */
754- mlxbf_tmfifo_release_pending_pkt (vring );
788+ /* Done and release the packet. */
755789 desc = NULL ;
756790 fifo -> vring [is_rx ] = NULL ;
791+ if (!IS_VRING_DROP (vring )) {
792+ mlxbf_tmfifo_release_pkt (vring );
793+ } else {
794+ vring -> pkt_len = 0 ;
795+ vring -> desc_head = NULL ;
796+ vring -> desc = NULL ;
797+ return false;
798+ }
757799
758800 /*
759801 * Make sure the load/store are in order before
@@ -933,7 +975,7 @@ static void mlxbf_tmfifo_virtio_del_vqs(struct virtio_device *vdev)
933975
934976 /* Release the pending packet. */
935977 if (vring -> desc )
936- mlxbf_tmfifo_release_pending_pkt (vring );
978+ mlxbf_tmfifo_release_pkt (vring );
937979 vq = vring -> vq ;
938980 if (vq ) {
939981 vring -> vq = NULL ;
0 commit comments