[PATCH net-next v11 08/14] net: ethernet: oa_tc6: Drop frames if footer has FD bit set
From: Selvamani Rajagopal via B4 Relay
Date: Fri Nov 13 2026 - 12:33:31 EST
From: Selvamani Rajagopal <Selvamani.Rajagopal@xxxxxxxxxx>
Drop a receive frame when the data footer of its last chunk has
the Frame Drop (FD) bit set. Dropping the frame with FD bit set
is in OPEN Alliance specification.
Here is one scenario when FD bit will be set. With RX cut-through
enabled, the MAC-PHY can start forwarding a frame before it knows
the frame is bad, and uses FD to tell the host to discard it.
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@xxxxxxxxxx>
---
changes in v11
- Act on FD bit on the footer in the received data chunk.
- New patch in v11
---
drivers/net/ethernet/oa_tc6/oa_tc6_main.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/net/ethernet/oa_tc6/oa_tc6_main.c b/drivers/net/ethernet/oa_tc6/oa_tc6_main.c
index 2b31370da2d2..5d01ef5a13ad 100644
--- a/drivers/net/ethernet/oa_tc6/oa_tc6_main.c
+++ b/drivers/net/ethernet/oa_tc6/oa_tc6_main.c
@@ -1150,6 +1150,7 @@ static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
footer);
bool start_valid = FIELD_GET(OA_TC6_DATA_FOOTER_START_VALID, footer);
bool end_valid = FIELD_GET(OA_TC6_DATA_FOOTER_END_VALID, footer);
+ bool frame_drop = FIELD_GET(OA_TC6_DATA_FOOTER_FRAME_DROP, footer);
u16 size;
/* Restart the new rx frame after receiving rx buffer overflow error */
@@ -1159,6 +1160,25 @@ static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
if (tc6->wait_until_start_valid)
return 0;
+ /* Drop the frame, if footer sets FD bit. Checking FD bit
+ * becomes important, when cut-through operation is enabled.
+ */
+ if (end_valid && frame_drop) {
+ oa_tc6_cleanup_ongoing_rx_skb(tc6);
+
+ /* Full frame in this chunk. Nothing to free. Move on to
+ * next chunk.
+ */
+ if (start_valid && start_byte_offset < end_byte_offset) {
+ tc6->netdev->stats.rx_dropped++;
+ return 0;
+ }
+
+ /* The chunk carries only the end of the dropped frame. */
+ if (!start_valid)
+ return 0;
+ }
+
/* Process the chunk with complete rx frame */
if (start_valid && end_valid && start_byte_offset < end_byte_offset) {
size = end_byte_offset + 1 - start_byte_offset;
--
2.43.0