Commit ee512922 authored by Stefan Wahren's avatar Stefan Wahren Committed by Jakub Kicinski
Browse files

net: vertexcom: mse102x: Fix RX error handling



In case the CMD_RTS got corrupted by interferences, the MSE102x
doesn't allow a retransmission of the command. Instead the Ethernet
frame must be shifted out of the SPI FIFO. Since the actual length is
unknown, assume the maximum possible value.

Fixes: 2f207cbf ("net: vertexcom: Add MSE102x SPI support")
Signed-off-by: default avatarStefan Wahren <wahrenst@gmx.net>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20250430133043.7722-5-wahrenst@gmx.net


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent d4dda902
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -263,7 +263,7 @@ static int mse102x_tx_frame_spi(struct mse102x_net *mse, struct sk_buff *txp,
}

static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff,
				unsigned int frame_len)
				unsigned int frame_len, bool drop)
{
	struct mse102x_net_spi *mses = to_mse102x_spi(mse);
	struct spi_transfer *xfer = &mses->spi_xfer;
@@ -281,6 +281,9 @@ static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff,
		netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n",
			   __func__, ret);
		mse->stats.xfer_err++;
	} else if (drop) {
		netdev_dbg(mse->ndev, "%s: Drop frame\n", __func__);
		ret = -EINVAL;
	} else if (*sof != cpu_to_be16(DET_SOF)) {
		netdev_dbg(mse->ndev, "%s: SPI start of frame is invalid (0x%04x)\n",
			   __func__, *sof);
@@ -308,6 +311,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
	struct sk_buff *skb;
	unsigned int rxalign;
	unsigned int rxlen;
	bool drop = false;
	__be16 rx = 0;
	u16 cmd_resp;
	u8 *rxpkt;
@@ -330,7 +334,8 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
			net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n",
					    __func__, cmd_resp);
			mse->stats.invalid_rts++;
			return;
			drop = true;
			goto drop;
		}

		net_dbg_ratelimited("%s: Unexpected response to first CMD\n",
@@ -342,9 +347,16 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
		net_dbg_ratelimited("%s: Invalid frame length: %d\n", __func__,
				    rxlen);
		mse->stats.invalid_len++;
		return;
		drop = true;
	}

	/* In case of a invalid CMD_RTS, the frame must be consumed anyway.
	 * So assume the maximum possible frame length.
	 */
drop:
	if (drop)
		rxlen = VLAN_ETH_FRAME_LEN;

	rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4);
	skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign);
	if (!skb)
@@ -355,7 +367,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
	 * They are copied, but ignored.
	 */
	rxpkt = skb_put(skb, rxlen) - DET_SOF_LEN;
	if (mse102x_rx_frame_spi(mse, rxpkt, rxlen)) {
	if (mse102x_rx_frame_spi(mse, rxpkt, rxlen, drop)) {
		mse->ndev->stats.rx_errors++;
		dev_kfree_skb(skb);
		return;