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 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 7 | #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 4 | 39 | #define DET_CMD_LEN 4 |
| 39 | #define DET_SOF_LEN 2 | 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 | static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff, | 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 | 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 | */ | ||
| 356 | drop: | ||
| 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 | |||
| 509 | static int mse102x_net_open(struct net_device *ndev) | 523 | static 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; |