Skip to content

Commit 1daa05f

Browse files
committed
Merge branch 'net-vertexcom-mse102x-fix-rx-handling'
Stefan Wahren says: ==================== net: vertexcom: mse102x: Fix RX handling This series is the first part of two series for the Vertexcom driver. It contains substantial fixes for the RX handling of the Vertexcom MSE102x. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 2f0b0c6 + ee51292 commit 1daa05f

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

drivers/net/ethernet/vertexcom/mse102x.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
88

9+
#include <linux/if_vlan.h>
910
#include <linux/interrupt.h>
1011
#include <linux/module.h>
1112
#include <linux/kernel.h>
@@ -33,7 +34,7 @@
3334
#define CMD_CTR (0x2 << CMD_SHIFT)
3435

3536
#define CMD_MASK GENMASK(15, CMD_SHIFT)
36-
#define LEN_MASK GENMASK(CMD_SHIFT - 1, 0)
37+
#define LEN_MASK GENMASK(CMD_SHIFT - 2, 0)
3738

3839
#define DET_CMD_LEN 4
3940
#define DET_SOF_LEN 2
@@ -262,7 +263,7 @@ static int mse102x_tx_frame_spi(struct mse102x_net *mse, struct sk_buff *txp,
262263
}
263264

264265
static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff,
265-
unsigned int frame_len)
266+
unsigned int frame_len, bool drop)
266267
{
267268
struct mse102x_net_spi *mses = to_mse102x_spi(mse);
268269
struct spi_transfer *xfer = &mses->spi_xfer;
@@ -280,6 +281,9 @@ static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff,
280281
netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n",
281282
__func__, ret);
282283
mse->stats.xfer_err++;
284+
} else if (drop) {
285+
netdev_dbg(mse->ndev, "%s: Drop frame\n", __func__);
286+
ret = -EINVAL;
283287
} else if (*sof != cpu_to_be16(DET_SOF)) {
284288
netdev_dbg(mse->ndev, "%s: SPI start of frame is invalid (0x%04x)\n",
285289
__func__, *sof);
@@ -307,6 +311,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
307311
struct sk_buff *skb;
308312
unsigned int rxalign;
309313
unsigned int rxlen;
314+
bool drop = false;
310315
__be16 rx = 0;
311316
u16 cmd_resp;
312317
u8 *rxpkt;
@@ -329,20 +334,29 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
329334
net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n",
330335
__func__, cmd_resp);
331336
mse->stats.invalid_rts++;
332-
return;
337+
drop = true;
338+
goto drop;
333339
}
334340

335341
net_dbg_ratelimited("%s: Unexpected response to first CMD\n",
336342
__func__);
337343
}
338344

339345
rxlen = cmd_resp & LEN_MASK;
340-
if (!rxlen) {
341-
net_dbg_ratelimited("%s: No frame length defined\n", __func__);
346+
if (rxlen < ETH_ZLEN || rxlen > VLAN_ETH_FRAME_LEN) {
347+
net_dbg_ratelimited("%s: Invalid frame length: %d\n", __func__,
348+
rxlen);
342349
mse->stats.invalid_len++;
343-
return;
350+
drop = true;
344351
}
345352

353+
/* In case of a invalid CMD_RTS, the frame must be consumed anyway.
354+
* So assume the maximum possible frame length.
355+
*/
356+
drop:
357+
if (drop)
358+
rxlen = VLAN_ETH_FRAME_LEN;
359+
346360
rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4);
347361
skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign);
348362
if (!skb)
@@ -353,7 +367,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse)
353367
* They are copied, but ignored.
354368
*/
355369
rxpkt = skb_put(skb, rxlen) - DET_SOF_LEN;
356-
if (mse102x_rx_frame_spi(mse, rxpkt, rxlen)) {
370+
if (mse102x_rx_frame_spi(mse, rxpkt, rxlen, drop)) {
357371
mse->ndev->stats.rx_errors++;
358372
dev_kfree_skb(skb);
359373
return;
@@ -509,6 +523,7 @@ static irqreturn_t mse102x_irq(int irq, void *_mse)
509523
static int mse102x_net_open(struct net_device *ndev)
510524
{
511525
struct mse102x_net *mse = netdev_priv(ndev);
526+
struct mse102x_net_spi *mses = to_mse102x_spi(mse);
512527
int ret;
513528

514529
ret = request_threaded_irq(ndev->irq, NULL, mse102x_irq, IRQF_ONESHOT,
@@ -524,6 +539,13 @@ static int mse102x_net_open(struct net_device *ndev)
524539

525540
netif_carrier_on(ndev);
526541

542+
/* The SPI interrupt can stuck in case of pending packet(s).
543+
* So poll for possible packet(s) to re-arm the interrupt.
544+
*/
545+
mutex_lock(&mses->lock);
546+
mse102x_rx_pkt_spi(mse);
547+
mutex_unlock(&mses->lock);
548+
527549
netif_dbg(mse, ifup, ndev, "network device up\n");
528550

529551
return 0;

0 commit comments

Comments
 (0)