Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'net-vertexcom-mse102x-improve-rx-handling'

Stefan Wahren says:

====================
net: vertexcom: mse102x: Improve RX handling

This series is the second part of two series for the Vertexcom driver.
It contains some improvements for the RX handling of the Vertexcom MSE102x.
====================

Link: https://patch.msgid.link/20250509120435.43646-1-wahrenst@gmx.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+47 -35
+1 -1
Documentation/devicetree/bindings/net/vertexcom-mse102x.yaml
··· 63 63 compatible = "vertexcom,mse1021"; 64 64 reg = <0>; 65 65 interrupt-parent = <&gpio>; 66 - interrupts = <23 IRQ_TYPE_EDGE_RISING>; 66 + interrupts = <23 IRQ_TYPE_LEVEL_HIGH>; 67 67 spi-cpha; 68 68 spi-cpol; 69 69 spi-max-frequency = <7142857>;
+46 -34
drivers/net/ethernet/vertexcom/mse102x.c
··· 8 8 9 9 #include <linux/if_vlan.h> 10 10 #include <linux/interrupt.h> 11 + #include <linux/irq.h> 11 12 #include <linux/module.h> 12 13 #include <linux/kernel.h> 13 14 #include <linux/netdevice.h> ··· 17 16 #include <linux/cache.h> 18 17 #include <linux/debugfs.h> 19 18 #include <linux/seq_file.h> 19 + #include <linux/string_choices.h> 20 20 21 21 #include <linux/spi/spi.h> 22 22 #include <linux/of_net.h> ··· 47 45 48 46 struct mse102x_stats { 49 47 u64 xfer_err; 50 - u64 invalid_cmd; 51 48 u64 invalid_ctr; 52 49 u64 invalid_dft; 53 50 u64 invalid_len; ··· 57 56 58 57 static const char mse102x_gstrings_stats[][ETH_GSTRING_LEN] = { 59 58 "SPI transfer errors", 60 - "Invalid command", 61 59 "Invalid CTR", 62 60 "Invalid DFT", 63 61 "Invalid frame length", ··· 85 85 struct spi_message spi_msg; 86 86 struct spi_transfer spi_xfer; 87 87 88 + bool valid_cmd_received; 89 + 88 90 #ifdef CONFIG_DEBUG_FS 89 91 struct dentry *device_root; 90 92 #endif ··· 100 98 { 101 99 struct mse102x_net_spi *mses = s->private; 102 100 103 - seq_printf(s, "TX ring size : %u\n", 101 + seq_printf(s, "TX ring size : %u\n", 104 102 skb_queue_len(&mses->mse102x.txq)); 105 103 106 - seq_printf(s, "IRQ : %d\n", 104 + seq_printf(s, "IRQ : %d\n", 107 105 mses->spidev->irq); 108 106 109 - seq_printf(s, "SPI effective speed : %lu\n", 107 + seq_printf(s, "SPI effective speed : %lu\n", 110 108 (unsigned long)mses->spi_xfer.effective_speed_hz); 111 - seq_printf(s, "SPI mode : %x\n", 109 + seq_printf(s, "SPI mode : %x\n", 112 110 mses->spidev->mode); 111 + seq_printf(s, "Received valid CMD once : %s\n", 112 + str_yes_no(mses->valid_cmd_received)); 113 113 114 114 return 0; 115 115 } ··· 198 194 } else if (*cmd != cpu_to_be16(DET_CMD)) { 199 195 net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n", 200 196 __func__, *cmd); 201 - mse->stats.invalid_cmd++; 202 197 ret = -EIO; 203 198 } else { 204 199 memcpy(rxb, trx + 2, 2); 200 + mses->valid_cmd_received = true; 205 201 } 206 202 207 203 return ret; ··· 310 306 data, len, true); 311 307 } 312 308 313 - static void mse102x_rx_pkt_spi(struct mse102x_net *mse) 309 + static irqreturn_t mse102x_rx_pkt_spi(struct mse102x_net *mse) 314 310 { 315 311 struct sk_buff *skb; 316 312 unsigned int rxalign; ··· 319 315 __be16 rx = 0; 320 316 u16 cmd_resp; 321 317 u8 *rxpkt; 322 - int ret; 323 318 324 319 mse102x_tx_cmd_spi(mse, CMD_CTR); 325 - ret = mse102x_rx_cmd_spi(mse, (u8 *)&rx); 326 - cmd_resp = be16_to_cpu(rx); 327 - 328 - if (ret || ((cmd_resp & CMD_MASK) != CMD_RTS)) { 320 + if (mse102x_rx_cmd_spi(mse, (u8 *)&rx)) { 329 321 usleep_range(50, 100); 322 + return IRQ_NONE; 323 + } 330 324 331 - mse102x_tx_cmd_spi(mse, CMD_CTR); 332 - ret = mse102x_rx_cmd_spi(mse, (u8 *)&rx); 333 - if (ret) 334 - return; 335 - 336 - cmd_resp = be16_to_cpu(rx); 337 - if ((cmd_resp & CMD_MASK) != CMD_RTS) { 338 - net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n", 339 - __func__, cmd_resp); 340 - mse->stats.invalid_rts++; 341 - drop = true; 342 - goto drop; 343 - } 344 - 345 - net_dbg_ratelimited("%s: Unexpected response to first CMD\n", 346 - __func__); 325 + cmd_resp = be16_to_cpu(rx); 326 + if ((cmd_resp & CMD_MASK) != CMD_RTS) { 327 + net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n", 328 + __func__, cmd_resp); 329 + mse->stats.invalid_rts++; 330 + drop = true; 331 + goto drop; 347 332 } 348 333 349 334 rxlen = cmd_resp & LEN_MASK; ··· 353 360 rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4); 354 361 skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign); 355 362 if (!skb) 356 - return; 363 + return IRQ_NONE; 357 364 358 365 /* 2 bytes Start of frame (before ethernet header) 359 366 * 2 bytes Data frame tail (after ethernet frame) ··· 363 370 if (mse102x_rx_frame_spi(mse, rxpkt, rxlen, drop)) { 364 371 mse->ndev->stats.rx_errors++; 365 372 dev_kfree_skb(skb); 366 - return; 373 + return IRQ_HANDLED; 367 374 } 368 375 369 376 if (netif_msg_pktdata(mse)) ··· 374 381 375 382 mse->ndev->stats.rx_packets++; 376 383 mse->ndev->stats.rx_bytes += rxlen; 384 + 385 + return IRQ_HANDLED; 377 386 } 378 387 379 388 static int mse102x_tx_pkt_spi(struct mse102x_net *mse, struct sk_buff *txb, ··· 507 512 { 508 513 struct mse102x_net *mse = _mse; 509 514 struct mse102x_net_spi *mses = to_mse102x_spi(mse); 515 + irqreturn_t ret; 510 516 511 517 mutex_lock(&mses->lock); 512 - mse102x_rx_pkt_spi(mse); 518 + ret = mse102x_rx_pkt_spi(mse); 513 519 mutex_unlock(&mses->lock); 514 520 515 - return IRQ_HANDLED; 521 + return ret; 516 522 } 517 523 518 524 static int mse102x_net_open(struct net_device *ndev) 519 525 { 526 + struct irq_data *irq_data = irq_get_irq_data(ndev->irq); 520 527 struct mse102x_net *mse = netdev_priv(ndev); 521 528 struct mse102x_net_spi *mses = to_mse102x_spi(mse); 522 529 int ret; 530 + 531 + if (!irq_data) { 532 + netdev_err(ndev, "Invalid IRQ: %d\n", ndev->irq); 533 + return -EINVAL; 534 + } 535 + 536 + switch (irqd_get_trigger_type(irq_data)) { 537 + case IRQ_TYPE_LEVEL_HIGH: 538 + case IRQ_TYPE_LEVEL_LOW: 539 + break; 540 + default: 541 + netdev_warn_once(ndev, "Only IRQ type level recommended, please update your device tree firmware.\n"); 542 + break; 543 + } 523 544 524 545 ret = request_threaded_irq(ndev->irq, NULL, mse102x_irq, IRQF_ONESHOT, 525 546 ndev->name, mse); ··· 554 543 * So poll for possible packet(s) to re-arm the interrupt. 555 544 */ 556 545 mutex_lock(&mses->lock); 557 - mse102x_rx_pkt_spi(mse); 546 + if (mse102x_rx_pkt_spi(mse) == IRQ_NONE) 547 + mse102x_rx_pkt_spi(mse); 558 548 mutex_unlock(&mses->lock); 559 549 560 550 netif_dbg(mse, ifup, ndev, "network device up\n");