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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'linux-can-next-for-6.9-20240220' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next

Marc Kleine-Budde says:

====================
pull-request: can-next 2024-02-20

this is a pull request of 9 patches for net-next/master.

The first patch is by Francesco Dolcini and removes a redundant check
for pm_clock_support from the m_can driver.

Martin Hundebøll contributes 3 patches to the m_can/tcan4x5x driver to
allow resume upon RX of a CAN frame.

3 patches by Srinivas Goud add support for ECC statistics to the
xilinx_can driver.

The last 2 patches are by Oliver Hartkopp and me, target the CAN RAW
protocol and fix an error in the getsockopt() for CAN-XL introduced in
the previous pull request to net-next (linux-can-next-for-6.9-20240213).

linux-can-next-for-6.9-20240220

* tag 'linux-can-next-for-6.9-20240220' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next:
can: raw: raw_getsockopt(): reduce scope of err
can: raw: fix getsockopt() for new CAN_RAW_XL_VCID_OPTS
can: xilinx_can: Add ethtool stats interface for ECC errors
can: xilinx_can: Add ECC support
dt-bindings: can: xilinx_can: Add 'xlnx,has-ecc' optional property
can: tcan4x5x: support resuming from rx interrupt signal
can: m_can: allow keeping the transceiver running in suspend
dt-bindings: can: tcan4x5x: Document the wakeup-source flag
can: m_can: remove redundant check for pm_clock_support
====================

Link: https://lore.kernel.org/r/20240220085130.2936533-1-mkl@pengutronix.de
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+239 -21
+3
Documentation/devicetree/bindings/net/can/tcan4x5x.txt
··· 28 28 available with tcan4552/4553. 29 29 - device-wake-gpios: Wake up GPIO to wake up the TCAN device. Not 30 30 available with tcan4552/4553. 31 + - wakeup-source: Leave the chip running when suspended, and configure 32 + the RX interrupt to wake up the device. 31 33 32 34 Example: 33 35 tcan4x5x: tcan4x5x@0 { ··· 44 42 device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; 45 43 device-wake-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; 46 44 reset-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>; 45 + wakeup-source; 47 46 };
+5
Documentation/devicetree/bindings/net/can/xilinx,can.yaml
··· 49 49 resets: 50 50 maxItems: 1 51 51 52 + xlnx,has-ecc: 53 + $ref: /schemas/types.yaml#/definitions/flag 54 + description: CAN TX_OL, TX_TL and RX FIFOs have ECC support(AXI CAN) 55 + 52 56 required: 53 57 - compatible 54 58 - reg ··· 141 137 interrupts = <GIC_SPI 59 IRQ_TYPE_EDGE_RISING>; 142 138 tx-fifo-depth = <0x40>; 143 139 rx-fifo-depth = <0x40>; 140 + xlnx,has-ecc; 144 141 }; 145 142 146 143 - |
+20 -10
drivers/net/can/m_can/m_can.c
··· 2312 2312 } 2313 2313 } 2314 2314 2315 - if (cdev->pm_clock_support) { 2316 - ret = m_can_clk_start(cdev); 2317 - if (ret) 2318 - return ret; 2319 - } 2315 + ret = m_can_clk_start(cdev); 2316 + if (ret) 2317 + return ret; 2320 2318 2321 2319 if (cdev->is_peripheral) { 2322 2320 ret = can_rx_offload_add_manual(cdev->net, &cdev->offload, ··· 2382 2384 if (netif_running(ndev)) { 2383 2385 netif_stop_queue(ndev); 2384 2386 netif_device_detach(ndev); 2385 - m_can_stop(ndev); 2387 + 2388 + /* leave the chip running with rx interrupt enabled if it is 2389 + * used as a wake-up source. 2390 + */ 2391 + if (cdev->pm_wake_source) 2392 + m_can_write(cdev, M_CAN_IE, IR_RF0N); 2393 + else 2394 + m_can_stop(ndev); 2395 + 2386 2396 m_can_clk_stop(cdev); 2387 2397 } 2388 2398 ··· 2417 2411 ret = m_can_clk_start(cdev); 2418 2412 if (ret) 2419 2413 return ret; 2420 - ret = m_can_start(ndev); 2421 - if (ret) { 2422 - m_can_clk_stop(cdev); 2423 2414 2424 - return ret; 2415 + if (cdev->pm_wake_source) { 2416 + m_can_write(cdev, M_CAN_IE, cdev->active_interrupts); 2417 + } else { 2418 + ret = m_can_start(ndev); 2419 + if (ret) { 2420 + m_can_clk_stop(cdev); 2421 + return ret; 2422 + } 2425 2423 } 2426 2424 2427 2425 netif_device_attach(ndev);
+1
drivers/net/can/m_can/m_can.h
··· 97 97 u32 irqstatus; 98 98 99 99 int pm_clock_support; 100 + int pm_wake_source; 100 101 int is_peripheral; 101 102 102 103 // Cached M_CAN_IE register content
+1
drivers/net/can/m_can/m_can_pci.c
··· 125 125 mcan_class->dev = &pci->dev; 126 126 mcan_class->net->irq = pci_irq_vector(pci, 0); 127 127 mcan_class->pm_clock_support = 1; 128 + mcan_class->pm_wake_source = 0; 128 129 mcan_class->can.clock.freq = id->driver_data; 129 130 mcan_class->ops = &m_can_pci_ops; 130 131
+1
drivers/net/can/m_can/m_can_platform.c
··· 139 139 140 140 mcan_class->net->irq = irq; 141 141 mcan_class->pm_clock_support = 1; 142 + mcan_class->pm_wake_source = 0; 142 143 mcan_class->can.clock.freq = clk_get_rate(mcan_class->cclk); 143 144 mcan_class->dev = &pdev->dev; 144 145 mcan_class->transceiver = transceiver;
+32 -1
drivers/net/can/m_can/tcan4x5x-core.c
··· 411 411 priv->spi = spi; 412 412 413 413 mcan_class->pm_clock_support = 0; 414 + mcan_class->pm_wake_source = device_property_read_bool(&spi->dev, "wakeup-source"); 414 415 mcan_class->can.clock.freq = freq; 415 416 mcan_class->dev = &spi->dev; 416 417 mcan_class->ops = &tcan4x5x_ops; ··· 460 459 goto out_power; 461 460 } 462 461 462 + if (mcan_class->pm_wake_source) 463 + device_init_wakeup(&spi->dev, true); 464 + 463 465 ret = m_can_class_register(mcan_class); 464 466 if (ret) { 465 467 dev_err(&spi->dev, "Failed registering m_can device %pe\n", ··· 491 487 m_can_class_free_dev(priv->cdev.net); 492 488 } 493 489 490 + static int __maybe_unused tcan4x5x_suspend(struct device *dev) 491 + { 492 + struct m_can_classdev *cdev = dev_get_drvdata(dev); 493 + struct spi_device *spi = to_spi_device(dev); 494 + 495 + if (cdev->pm_wake_source) 496 + enable_irq_wake(spi->irq); 497 + 498 + return m_can_class_suspend(dev); 499 + } 500 + 501 + static int __maybe_unused tcan4x5x_resume(struct device *dev) 502 + { 503 + struct m_can_classdev *cdev = dev_get_drvdata(dev); 504 + struct spi_device *spi = to_spi_device(dev); 505 + int ret = m_can_class_resume(dev); 506 + 507 + if (cdev->pm_wake_source) 508 + disable_irq_wake(spi->irq); 509 + 510 + return ret; 511 + } 512 + 494 513 static const struct of_device_id tcan4x5x_of_match[] = { 495 514 { 496 515 .compatible = "ti,tcan4x5x", ··· 532 505 }; 533 506 MODULE_DEVICE_TABLE(spi, tcan4x5x_id_table); 534 507 508 + static const struct dev_pm_ops tcan4x5x_pm_ops = { 509 + SET_SYSTEM_SLEEP_PM_OPS(tcan4x5x_suspend, tcan4x5x_resume) 510 + }; 511 + 535 512 static struct spi_driver tcan4x5x_can_driver = { 536 513 .driver = { 537 514 .name = KBUILD_MODNAME, 538 515 .of_match_table = tcan4x5x_of_match, 539 - .pm = NULL, 516 + .pm = &tcan4x5x_pm_ops, 540 517 }, 541 518 .id_table = tcan4x5x_id_table, 542 519 .probe = tcan4x5x_can_probe,
+165 -4
drivers/net/can/xilinx_can.c
··· 31 31 #include <linux/phy/phy.h> 32 32 #include <linux/pm_runtime.h> 33 33 #include <linux/reset.h> 34 + #include <linux/u64_stats_sync.h> 34 35 35 36 #define DRIVER_NAME "xilinx_can" 36 37 ··· 59 58 */ 60 59 XCAN_F_BTR_OFFSET = 0x08C, /* Data Phase Bit Timing */ 61 60 XCAN_TRR_OFFSET = 0x0090, /* TX Buffer Ready Request */ 61 + 62 + /* only on AXI CAN cores */ 63 + XCAN_ECC_CFG_OFFSET = 0xC8, /* ECC Configuration */ 64 + XCAN_TXTLFIFO_ECC_OFFSET = 0xCC, /* TXTL FIFO ECC error counter */ 65 + XCAN_TXOLFIFO_ECC_OFFSET = 0xD0, /* TXOL FIFO ECC error counter */ 66 + XCAN_RXFIFO_ECC_OFFSET = 0xD4, /* RX FIFO ECC error counter */ 67 + 62 68 XCAN_AFR_EXT_OFFSET = 0x00E0, /* Acceptance Filter */ 63 69 XCAN_FSR_OFFSET = 0x00E8, /* RX FIFO Status */ 64 70 XCAN_TXMSG_BASE_OFFSET = 0x0100, /* TX Message Space */ ··· 132 124 #define XCAN_IXR_TXFLL_MASK 0x00000004 /* Tx FIFO Full intr */ 133 125 #define XCAN_IXR_TXOK_MASK 0x00000002 /* TX successful intr */ 134 126 #define XCAN_IXR_ARBLST_MASK 0x00000001 /* Arbitration lost intr */ 127 + #define XCAN_IXR_E2BERX_MASK BIT(23) /* RX FIFO two bit ECC error */ 128 + #define XCAN_IXR_E1BERX_MASK BIT(22) /* RX FIFO one bit ECC error */ 129 + #define XCAN_IXR_E2BETXOL_MASK BIT(21) /* TXOL FIFO two bit ECC error */ 130 + #define XCAN_IXR_E1BETXOL_MASK BIT(20) /* TXOL FIFO One bit ECC error */ 131 + #define XCAN_IXR_E2BETXTL_MASK BIT(19) /* TXTL FIFO Two bit ECC error */ 132 + #define XCAN_IXR_E1BETXTL_MASK BIT(18) /* TXTL FIFO One bit ECC error */ 133 + #define XCAN_IXR_ECC_MASK (XCAN_IXR_E2BERX_MASK | \ 134 + XCAN_IXR_E1BERX_MASK | \ 135 + XCAN_IXR_E2BETXOL_MASK | \ 136 + XCAN_IXR_E1BETXOL_MASK | \ 137 + XCAN_IXR_E2BETXTL_MASK | \ 138 + XCAN_IXR_E1BETXTL_MASK) 135 139 #define XCAN_IDR_ID1_MASK 0xFFE00000 /* Standard msg identifier */ 136 140 #define XCAN_IDR_SRR_MASK 0x00100000 /* Substitute remote TXreq */ 137 141 #define XCAN_IDR_IDE_MASK 0x00080000 /* Identifier extension */ ··· 157 137 #define XCAN_2_FSR_RI_MASK 0x0000003F /* RX Read Index */ 158 138 #define XCAN_DLCR_EDL_MASK 0x08000000 /* EDL Mask in DLC */ 159 139 #define XCAN_DLCR_BRS_MASK 0x04000000 /* BRS Mask in DLC */ 140 + #define XCAN_ECC_CFG_REECRX_MASK BIT(2) /* Reset RX FIFO ECC error counters */ 141 + #define XCAN_ECC_CFG_REECTXOL_MASK BIT(1) /* Reset TXOL FIFO ECC error counters */ 142 + #define XCAN_ECC_CFG_REECTXTL_MASK BIT(0) /* Reset TXTL FIFO ECC error counters */ 143 + #define XCAN_ECC_1BIT_CNT_MASK GENMASK(15, 0) /* FIFO ECC 1bit count mask */ 144 + #define XCAN_ECC_2BIT_CNT_MASK GENMASK(31, 16) /* FIFO ECC 2bit count mask */ 160 145 161 146 /* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */ 162 147 #define XCAN_BRPR_TDC_ENABLE BIT(16) /* Transmitter Delay Compensation (TDC) Enable */ ··· 227 202 * @devtype: Device type specific constants 228 203 * @transceiver: Optional pointer to associated CAN transceiver 229 204 * @rstc: Pointer to reset control 205 + * @ecc_enable: ECC enable flag 206 + * @syncp: synchronization for ECC error stats 207 + * @ecc_rx_2_bit_errors: RXFIFO 2bit ECC count 208 + * @ecc_rx_1_bit_errors: RXFIFO 1bit ECC count 209 + * @ecc_txol_2_bit_errors: TXOLFIFO 2bit ECC count 210 + * @ecc_txol_1_bit_errors: TXOLFIFO 1bit ECC count 211 + * @ecc_txtl_2_bit_errors: TXTLFIFO 2bit ECC count 212 + * @ecc_txtl_1_bit_errors: TXTLFIFO 1bit ECC count 230 213 */ 231 214 struct xcan_priv { 232 215 struct can_priv can; ··· 254 221 struct xcan_devtype_data devtype; 255 222 struct phy *transceiver; 256 223 struct reset_control *rstc; 224 + bool ecc_enable; 225 + struct u64_stats_sync syncp; 226 + u64_stats_t ecc_rx_2_bit_errors; 227 + u64_stats_t ecc_rx_1_bit_errors; 228 + u64_stats_t ecc_txol_2_bit_errors; 229 + u64_stats_t ecc_txol_1_bit_errors; 230 + u64_stats_t ecc_txtl_2_bit_errors; 231 + u64_stats_t ecc_txtl_1_bit_errors; 257 232 }; 258 233 259 234 /* CAN Bittiming constants as per Xilinx CAN specs */ ··· 347 306 .tdco_max = 64, 348 307 .tdcf_min = 0, /* Filter window not supported */ 349 308 .tdcf_max = 0, 309 + }; 310 + 311 + enum xcan_stats_type { 312 + XCAN_ECC_RX_2_BIT_ERRORS, 313 + XCAN_ECC_RX_1_BIT_ERRORS, 314 + XCAN_ECC_TXOL_2_BIT_ERRORS, 315 + XCAN_ECC_TXOL_1_BIT_ERRORS, 316 + XCAN_ECC_TXTL_2_BIT_ERRORS, 317 + XCAN_ECC_TXTL_1_BIT_ERRORS, 318 + }; 319 + 320 + static const char xcan_priv_flags_strings[][ETH_GSTRING_LEN] = { 321 + [XCAN_ECC_RX_2_BIT_ERRORS] = "ecc_rx_2_bit_errors", 322 + [XCAN_ECC_RX_1_BIT_ERRORS] = "ecc_rx_1_bit_errors", 323 + [XCAN_ECC_TXOL_2_BIT_ERRORS] = "ecc_txol_2_bit_errors", 324 + [XCAN_ECC_TXOL_1_BIT_ERRORS] = "ecc_txol_1_bit_errors", 325 + [XCAN_ECC_TXTL_2_BIT_ERRORS] = "ecc_txtl_2_bit_errors", 326 + [XCAN_ECC_TXTL_1_BIT_ERRORS] = "ecc_txtl_1_bit_errors", 350 327 }; 351 328 352 329 /** ··· 581 522 XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | 582 523 XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK | 583 524 XCAN_IXR_ARBLST_MASK | xcan_rx_int_mask(priv); 525 + 526 + if (priv->ecc_enable) 527 + ier |= XCAN_IXR_ECC_MASK; 584 528 585 529 if (priv->devtype.flags & XCAN_FLAG_RXMNF) 586 530 ier |= XCAN_IXR_RXMNF_MASK; ··· 1189 1127 priv->can.can_stats.bus_error++; 1190 1128 } 1191 1129 1130 + if (priv->ecc_enable && isr & XCAN_IXR_ECC_MASK) { 1131 + u32 reg_rx_ecc, reg_txol_ecc, reg_txtl_ecc; 1132 + 1133 + reg_rx_ecc = priv->read_reg(priv, XCAN_RXFIFO_ECC_OFFSET); 1134 + reg_txol_ecc = priv->read_reg(priv, XCAN_TXOLFIFO_ECC_OFFSET); 1135 + reg_txtl_ecc = priv->read_reg(priv, XCAN_TXTLFIFO_ECC_OFFSET); 1136 + 1137 + /* The counter reaches its maximum at 0xffff and does not overflow. 1138 + * Accept the small race window between reading and resetting ECC counters. 1139 + */ 1140 + priv->write_reg(priv, XCAN_ECC_CFG_OFFSET, XCAN_ECC_CFG_REECRX_MASK | 1141 + XCAN_ECC_CFG_REECTXOL_MASK | XCAN_ECC_CFG_REECTXTL_MASK); 1142 + 1143 + u64_stats_update_begin(&priv->syncp); 1144 + 1145 + if (isr & XCAN_IXR_E2BERX_MASK) { 1146 + u64_stats_add(&priv->ecc_rx_2_bit_errors, 1147 + FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, reg_rx_ecc)); 1148 + } 1149 + 1150 + if (isr & XCAN_IXR_E1BERX_MASK) { 1151 + u64_stats_add(&priv->ecc_rx_1_bit_errors, 1152 + FIELD_GET(XCAN_ECC_1BIT_CNT_MASK, reg_rx_ecc)); 1153 + } 1154 + 1155 + if (isr & XCAN_IXR_E2BETXOL_MASK) { 1156 + u64_stats_add(&priv->ecc_txol_2_bit_errors, 1157 + FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, reg_txol_ecc)); 1158 + } 1159 + 1160 + if (isr & XCAN_IXR_E1BETXOL_MASK) { 1161 + u64_stats_add(&priv->ecc_txol_1_bit_errors, 1162 + FIELD_GET(XCAN_ECC_1BIT_CNT_MASK, reg_txol_ecc)); 1163 + } 1164 + 1165 + if (isr & XCAN_IXR_E2BETXTL_MASK) { 1166 + u64_stats_add(&priv->ecc_txtl_2_bit_errors, 1167 + FIELD_GET(XCAN_ECC_2BIT_CNT_MASK, reg_txtl_ecc)); 1168 + } 1169 + 1170 + if (isr & XCAN_IXR_E1BETXTL_MASK) { 1171 + u64_stats_add(&priv->ecc_txtl_1_bit_errors, 1172 + FIELD_GET(XCAN_ECC_1BIT_CNT_MASK, reg_txtl_ecc)); 1173 + } 1174 + 1175 + u64_stats_update_end(&priv->syncp); 1176 + } 1177 + 1192 1178 if (cf.can_id) { 1193 1179 struct can_frame *skb_cf; 1194 1180 struct sk_buff *skb = alloc_can_err_skb(ndev, &skb_cf); ··· 1464 1354 { 1465 1355 struct net_device *ndev = (struct net_device *)dev_id; 1466 1356 struct xcan_priv *priv = netdev_priv(ndev); 1357 + u32 isr_errors, mask; 1467 1358 u32 isr, ier; 1468 - u32 isr_errors; 1469 1359 u32 rx_int_mask = xcan_rx_int_mask(priv); 1470 1360 1471 1361 /* Get the interrupt status from Xilinx CAN */ ··· 1484 1374 if (isr & XCAN_IXR_TXOK_MASK) 1485 1375 xcan_tx_interrupt(ndev, isr); 1486 1376 1377 + mask = XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK | 1378 + XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK | 1379 + XCAN_IXR_RXMNF_MASK; 1380 + 1381 + if (priv->ecc_enable) 1382 + mask |= XCAN_IXR_ECC_MASK; 1383 + 1487 1384 /* Check for the type of error interrupt and Processing it */ 1488 - isr_errors = isr & (XCAN_IXR_ERROR_MASK | XCAN_IXR_RXOFLW_MASK | 1489 - XCAN_IXR_BSOFF_MASK | XCAN_IXR_ARBLST_MASK | 1490 - XCAN_IXR_RXMNF_MASK); 1385 + isr_errors = isr & mask; 1491 1386 if (isr_errors) { 1492 1387 priv->write_reg(priv, XCAN_ICR_OFFSET, isr_errors); 1493 1388 xcan_err_interrupt(ndev, isr); ··· 1661 1546 return 0; 1662 1547 } 1663 1548 1549 + static void xcan_get_strings(struct net_device *ndev, u32 stringset, u8 *buf) 1550 + { 1551 + switch (stringset) { 1552 + case ETH_SS_STATS: 1553 + memcpy(buf, &xcan_priv_flags_strings, 1554 + sizeof(xcan_priv_flags_strings)); 1555 + } 1556 + } 1557 + 1558 + static int xcan_get_sset_count(struct net_device *netdev, int sset) 1559 + { 1560 + switch (sset) { 1561 + case ETH_SS_STATS: 1562 + return ARRAY_SIZE(xcan_priv_flags_strings); 1563 + default: 1564 + return -EOPNOTSUPP; 1565 + } 1566 + } 1567 + 1568 + static void xcan_get_ethtool_stats(struct net_device *ndev, 1569 + struct ethtool_stats *stats, u64 *data) 1570 + { 1571 + struct xcan_priv *priv = netdev_priv(ndev); 1572 + unsigned int start; 1573 + 1574 + do { 1575 + start = u64_stats_fetch_begin(&priv->syncp); 1576 + 1577 + data[XCAN_ECC_RX_2_BIT_ERRORS] = u64_stats_read(&priv->ecc_rx_2_bit_errors); 1578 + data[XCAN_ECC_RX_1_BIT_ERRORS] = u64_stats_read(&priv->ecc_rx_1_bit_errors); 1579 + data[XCAN_ECC_TXOL_2_BIT_ERRORS] = u64_stats_read(&priv->ecc_txol_2_bit_errors); 1580 + data[XCAN_ECC_TXOL_1_BIT_ERRORS] = u64_stats_read(&priv->ecc_txol_1_bit_errors); 1581 + data[XCAN_ECC_TXTL_2_BIT_ERRORS] = u64_stats_read(&priv->ecc_txtl_2_bit_errors); 1582 + data[XCAN_ECC_TXTL_1_BIT_ERRORS] = u64_stats_read(&priv->ecc_txtl_1_bit_errors); 1583 + } while (u64_stats_fetch_retry(&priv->syncp, start)); 1584 + } 1585 + 1664 1586 static const struct net_device_ops xcan_netdev_ops = { 1665 1587 .ndo_open = xcan_open, 1666 1588 .ndo_stop = xcan_close, ··· 1707 1555 1708 1556 static const struct ethtool_ops xcan_ethtool_ops = { 1709 1557 .get_ts_info = ethtool_op_get_ts_info, 1558 + .get_strings = xcan_get_strings, 1559 + .get_sset_count = xcan_get_sset_count, 1560 + .get_ethtool_stats = xcan_get_ethtool_stats, 1710 1561 }; 1711 1562 1712 1563 /** ··· 1948 1793 return -ENOMEM; 1949 1794 1950 1795 priv = netdev_priv(ndev); 1796 + priv->ecc_enable = of_property_read_bool(pdev->dev.of_node, "xlnx,has-ecc"); 1951 1797 priv->dev = &pdev->dev; 1952 1798 priv->can.bittiming_const = devtype->bittiming_const; 1953 1799 priv->can.do_set_mode = xcan_do_set_mode; ··· 2065 1909 priv->reg_base, ndev->irq, priv->can.clock.freq, 2066 1910 hw_tx_max, priv->tx_max); 2067 1911 1912 + if (priv->ecc_enable) { 1913 + /* Reset FIFO ECC counters */ 1914 + priv->write_reg(priv, XCAN_ECC_CFG_OFFSET, XCAN_ECC_CFG_REECRX_MASK | 1915 + XCAN_ECC_CFG_REECTXOL_MASK | XCAN_ECC_CFG_REECTXTL_MASK); 1916 + } 2068 1917 return 0; 2069 1918 2070 1919 err_disableclks:
+11 -6
net/can/raw.c
··· 756 756 struct raw_sock *ro = raw_sk(sk); 757 757 int len; 758 758 void *val; 759 - int err = 0; 760 759 761 760 if (level != SOL_CAN_RAW) 762 761 return -EINVAL; ··· 765 766 return -EINVAL; 766 767 767 768 switch (optname) { 768 - case CAN_RAW_FILTER: 769 + case CAN_RAW_FILTER: { 770 + int err = 0; 771 + 769 772 lock_sock(sk); 770 773 if (ro->count > 0) { 771 774 int fsize = ro->count * sizeof(struct can_filter); ··· 792 791 if (!err) 793 792 err = put_user(len, optlen); 794 793 return err; 795 - 794 + } 796 795 case CAN_RAW_ERR_FILTER: 797 796 if (len > sizeof(can_err_mask_t)) 798 797 len = sizeof(can_err_mask_t); ··· 823 822 val = &ro->xl_frames; 824 823 break; 825 824 826 - case CAN_RAW_XL_VCID_OPTS: 825 + case CAN_RAW_XL_VCID_OPTS: { 826 + int err = 0; 827 + 827 828 /* user space buffer to small for VCID opts? */ 828 829 if (len < sizeof(ro->raw_vcid_opts)) { 829 830 /* return -ERANGE and needed space in optlen */ ··· 838 835 if (copy_to_user(optval, &ro->raw_vcid_opts, len)) 839 836 err = -EFAULT; 840 837 } 841 - break; 842 - 838 + if (!err) 839 + err = put_user(len, optlen); 840 + return err; 841 + } 843 842 case CAN_RAW_JOIN_FILTERS: 844 843 if (len > sizeof(int)) 845 844 len = sizeof(int);