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. ====================
Unified · Split
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 8 | 8 | |
| 9 | +#include <linux/if_vlan.h> | |
| 9 | 10 | #include <linux/interrupt.h> |
| 10 | 11 | #include <linux/module.h> |
| 11 | 12 | #include <linux/kernel.h> |
| @@ -33,7 +34,7 @@ · 21 unmodified lines | ||
| 33 | 34 | #define CMD_CTR (0x2 << CMD_SHIFT) |
| 34 | 35 | |
| 35 | 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 | 39 | #define DET_CMD_LEN 4 |
| 39 | 40 | #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 | |
| 264 | 265 | static 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 | 268 | struct mse102x_net_spi *mses = to_mse102x_spi(mse); |
| 268 | 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 | 281 | netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n", |
| 281 | 282 | __func__, ret); |
| 282 | 283 | mse->stats.xfer_err++; |
| 284 | + } else if (drop) { | |
| 285 | + netdev_dbg(mse->ndev, "%s: Drop frame\n", __func__); | |
| 286 | + ret = -EINVAL; | |
| 283 | 287 | } else if (*sof != cpu_to_be16(DET_SOF)) { |
| 284 | 288 | netdev_dbg(mse->ndev, "%s: SPI start of frame is invalid (0x%04x)\n", |
| 285 | 289 | __func__, *sof); |
| @@ -307,6 +311,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) · 21 unmodified lines | ||
| 307 | 311 | struct sk_buff *skb; |
| 308 | 312 | unsigned int rxalign; |
| 309 | 313 | unsigned int rxlen; |
| 314 | + bool drop = false; | |
| 310 | 315 | __be16 rx = 0; |
| 311 | 316 | u16 cmd_resp; |
| 312 | 317 | u8 *rxpkt; |
| @@ -329,7 +334,8 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) · 16 unmodified lines | ||
| 329 | 334 | net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n", |
| 330 | 335 | __func__, cmd_resp); |
| 331 | 336 | mse->stats.invalid_rts++; |
| 332 | − return; | |
| 337 | + drop = true; | |
| 338 | + goto drop; | |
| 333 | 339 | } |
| 334 | 340 | |
| 335 | 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 | 345 | 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); | |
| 342 | 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 | + */ | |
| 356 | +drop: | |
| 357 | + if (drop) | |
| 358 | + rxlen = VLAN_ETH_FRAME_LEN; | |
| 359 | + | |
| 346 | 360 | rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4); |
| 347 | 361 | skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign); |
| 348 | 362 | if (!skb) |
| @@ -353,7 +367,7 @@ static void mse102x_rx_pkt_spi(struct mse102x_net *mse) · 4 unmodified lines | ||
| 353 | 367 | * They are copied, but ignored. |
| 354 | 368 | */ |
| 355 | 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 | 371 | mse->ndev->stats.rx_errors++; |
| 358 | 372 | dev_kfree_skb(skb); |
| 359 | 373 | return; |
| @@ -509,6 +523,7 @@ static irqreturn_t mse102x_irq(int irq, void *_mse) · 149 unmodified lines | ||
| 509 | 523 | static int mse102x_net_open(struct net_device *ndev) |
| 510 | 524 | { |
| 511 | 525 | struct mse102x_net *mse = netdev_priv(ndev); |
| 526 | + struct mse102x_net_spi *mses = to_mse102x_spi(mse); | |
| 512 | 527 | int ret; |
| 513 | 528 | |
| 514 | 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 | 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 | 549 | netif_dbg(mse, ifup, ndev, "network device up\n"); |
| 528 | 550 | |
| 529 | 551 | return 0; |