History

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. ====================

Jakub Kicinski committed 1 year ago

Commit 1daa05f2 parents 2f0b0c6 ee512921 file · +29 −7Browse files

Unified · Split

drivers/net/ethernet/vertexcom/mse102x.c+29−7
@@ -6,6 +6,7 @@ · 5 unmodified lines
6 6
7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8 8
9#include <linux/if_vlan.h>
9#include <linux/interrupt.h>10#include <linux/interrupt.h>
10#include <linux/module.h>11#include <linux/module.h>
11#include <linux/kernel.h>12#include <linux/kernel.h>
@@ -33,7 +34,7 @@ · 21 unmodified lines
33#define CMD_CTR (0x2 << CMD_SHIFT)34#define CMD_CTR (0x2 << CMD_SHIFT)
34 35
35#define CMD_MASK GENMASK(15, CMD_SHIFT)36#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)
37 38
38#define DET_CMD_LEN 439#define DET_CMD_LEN 4
39#define DET_SOF_LEN 240#define DET_SOF_LEN 2
@@ -262,7 +263,7 @@ static int mse102x_tx_frame_spi(struct mse102x_net *mse, struct sk_buff *txp, · 222 unmodified lines
262}263}
263 264
264static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff,265static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff,
265 unsigned int frame_len)266 unsigned int frame_len, bool drop)
266{267{
267 struct mse102x_net_spi *mses = to_mse102x_spi(mse);268 struct mse102x_net_spi *mses = to_mse102x_spi(mse);
268 struct spi_transfer *xfer = &mses->spi_xfer;269 struct spi_transfer *xfer = &mses->spi_xfer;
@@ -280,6 +281,9 @@ static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff, · 11 unmodified lines
280 netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n",281 netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n",
281 __func__, ret);282 __func__, ret);
282 mse->stats.xfer_err++;283 mse->stats.xfer_err++;
284 } else if (drop) {
285 netdev_dbg(mse->ndev, "%s: Drop frame\n", __func__);
286 ret = -EINVAL;
283 } else if (*sof != cpu_to_be16(DET_SOF)) {287 } else if (*sof != cpu_to_be16(DET_SOF)) {
284 netdev_dbg(mse->ndev, "%s: SPI start of frame is invalid (0x%04x)\n",288 netdev_dbg(mse->ndev, "%s: SPI start of frame is invalid (0x%04x)\n",
285 __func__, *sof);289 __func__, *sof);
@@ -307,6 +311,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) · 21 unmodified lines
307 struct sk_buff *skb;311 struct sk_buff *skb;
308 unsigned int rxalign;312 unsigned int rxalign;
309 unsigned int rxlen;313 unsigned int rxlen;
314 bool drop = false;
310 __be16 rx = 0;315 __be16 rx = 0;
311 u16 cmd_resp;316 u16 cmd_resp;
312 u8 *rxpkt;317 u8 *rxpkt;
@@ -329,7 +334,8 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) · 16 unmodified lines
329 net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n",334 net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n",
330 __func__, cmd_resp);335 __func__, cmd_resp);
331 mse->stats.invalid_rts++;336 mse->stats.invalid_rts++;
332 return;337 drop = true;
338 goto drop;
333 }339 }
334 340
335 net_dbg_ratelimited("%s: Unexpected response to first CMD\n",341 net_dbg_ratelimited("%s: Unexpected response to first CMD\n",
@@ -337,12 +343,20 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) · 1 unmodified line
337 }343 }
338 344
339 rxlen = cmd_resp & LEN_MASK;345 rxlen = cmd_resp & LEN_MASK;
340 if (!rxlen) {346 if (rxlen < ETH_ZLEN || rxlen > VLAN_ETH_FRAME_LEN) {
341 net_dbg_ratelimited("%s: No frame length defined\n", __func__);347 net_dbg_ratelimited("%s: Invalid frame length: %d\n", __func__,
348 rxlen);
342 mse->stats.invalid_len++;349 mse->stats.invalid_len++;
343 return;350 drop = true;
344 }351 }
345 352
353 /* In case of a invalid CMD_RTS, the frame must be consumed anyway.
354 * So assume the maximum possible frame length.
355 */
356drop:
357 if (drop)
358 rxlen = VLAN_ETH_FRAME_LEN;
359
346 rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4);360 rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4);
347 skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign);361 skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign);
348 if (!skb)362 if (!skb)
@@ -353,7 +367,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) · 4 unmodified lines
353 * They are copied, but ignored.367 * They are copied, but ignored.
354 */368 */
355 rxpkt = skb_put(skb, rxlen) - DET_SOF_LEN;369 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)) {
357 mse->ndev->stats.rx_errors++;371 mse->ndev->stats.rx_errors++;
358 dev_kfree_skb(skb);372 dev_kfree_skb(skb);
359 return;373 return;
@@ -509,6 +523,7 @@ static irqreturn_t mse102x_irq(int irq, void *_mse) · 149 unmodified lines
509static int mse102x_net_open(struct net_device *ndev)523static int mse102x_net_open(struct net_device *ndev)
510{524{
511 struct mse102x_net *mse = netdev_priv(ndev);525 struct mse102x_net *mse = netdev_priv(ndev);
526 struct mse102x_net_spi *mses = to_mse102x_spi(mse);
512 int ret;527 int ret;
513 528
514 ret = request_threaded_irq(ndev->irq, NULL, mse102x_irq, IRQF_ONESHOT,529 ret = request_threaded_irq(ndev->irq, NULL, mse102x_irq, IRQF_ONESHOT,
@@ -524,6 +539,13 @@ static int mse102x_net_open(struct net_device *ndev) · 9 unmodified lines
524 539
525 netif_carrier_on(ndev);540 netif_carrier_on(ndev);
526 541
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
527 netif_dbg(mse, ifup, ndev, "network device up\n");549 netif_dbg(mse, ifup, ndev, "network device up\n");
528 550
529 return 0;551 return 0;