All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/37] pull-request: can-next 2023-10-05
@ 2023-10-05 19:57 Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 01/37] can: sja1000: Fix comment Marc Kleine-Budde
                   ` (36 more replies)
  0 siblings, 37 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel

Hello netdev-team,

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

The first patch is by Miquel Raynal and fixes a comment in the sja1000
driver.

Vincent Mailhol contributes 2 patches that fix W=1 compiler warnings
in the etas_es58x driver.

Jiapeng Chong's patch removes an unneeded NULL pointer check before
dev_put() in the CAN raw protocol.

A patch by Justin Stittreplaces a strncpy() by strscpy() in the
peak_pci sja1000 driver.

The next 5 patches are by me and fix the can_restart() handler and
replace BUG_ON()s in the CAN dev helpers with proper error handling.

The last 27 patches are also by me and target the at91_can driver.
First a new helper function is introduced, the at91_can driver is
cleaned up and updated to use the rx-offload helper.

regards,
Marc

---

The following changes since commit 473267a4911f2469722c74ca58087d951072f72a:

  net: add sysctl to disable rfc4862 5.5.3e lifetime handling (2023-10-03 15:51:04 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git tags/linux-can-next-for-6.7-20231005

for you to fetch changes up to bf176313c62ec4f97daa893888aa4fde86749cb2:

  Merge patch series "can: at91: add can_state_get_by_berr_counter() helper, cleanup and convert to rx_offload" (2023-10-05 21:48:09 +0200)

----------------------------------------------------------------
linux-can-next-for-6.7-20231005

----------------------------------------------------------------
Jiapeng Chong (1):
      can: raw: Remove NULL check before dev_{put, hold}

Justin Stitt (1):
      can: peak_pci: replace deprecated strncpy with strscpy

Marc Kleine-Budde (35):
      Merge patch series "can: etas_es58x: clean-up of new GCC W=1 and old checkpatch warnings"
      can: dev: can_restart(): don't crash kernel if carrier is OK
      can: dev: can_restart(): fix race condition between controller restart and netif_carrier_on()
      can: dev: can_restart(): reverse logic to remove need for goto
      can: dev: can_restart(): move debug message and stats after successful restart
      can: dev: can_put_echo_skb(): don't crash kernel if can_priv::echo_skb is accessed out of bounds
      Merge patch series "can: dev: fix can_restart() and replace BUG_ON() by error handling"
      can: dev: add can_state_get_by_berr_counter() to return the CAN state based on the current error counters
      can: at91_can: use a consistent indention
      can: at91_can: at91_irq_tx(): remove one level of indention
      can: at91_can: BR register: convert to FIELD_PREP()
      can: at91_can: ECR register: convert to FIELD_GET()
      can: at91_can: MMR registers: convert to FIELD_PREP()
      can: at91_can: MID registers: convert access to FIELD_PREP(), FIELD_GET()
      can: at91_can: MSR Register: convert to FIELD_PREP()
      can: at91_can: MCR Register: convert to FIELD_PREP()
      can: at91_can: add more register definitions
      can: at91_can: at91_setup_mailboxes(): update comments
      can: at91_can: rename struct at91_priv::{tx_next,tx_echo} to {tx_head,tx_tail}
      can: at91_can: at91_set_bittiming(): demote register output to debug level
      can: at91_can: at91_chip_start(): don't disable IRQs twice
      can: at91_can: at91_open(): forward request_irq()'s return value in case or an error
      can: at91_can: add CAN transceiver support
      can: at91_can: at91_poll_err(): fold in at91_poll_err_frame()
      can: at91_can: at91_poll_err(): increase stats even if no quota left or OOM
      can: at91_can: at91_irq_err_frame(): call directly from IRQ handler
      can: at91_can: at91_irq_err_frame(): move next to at91_irq_err()
      can: at91_can: at91_irq_err(): rename to at91_irq_err_line()
      can: at91_can: at91_irq_err_line(): make use of can_state_get_by_berr_counter()
      can: at91_can: at91_irq_err_line(): take reg_sr into account for bus off
      can: at91_can: at91_irq_err_line(): make use of can_change_state() and can_bus_off()
      can: at91_can: at91_irq_err_line(): send error counters with state change
      can: at91_can: at91_alloc_can_err_skb() introduce new function
      can: at91_can: switch to rx-offload implementation
      Merge patch series "can: at91: add can_state_get_by_berr_counter() helper, cleanup and convert to rx_offload"

Miquel Raynal (1):
      can: sja1000: Fix comment

Vincent Mailhol (2):
      can: etas_es58x: rework the version check logic to silence -Wformat-truncation
      can: etas_es58x: add missing a blank line after declaration

 drivers/net/can/Kconfig                        |   1 +
 drivers/net/can/at91_can.c                     | 998 ++++++++++---------------
 drivers/net/can/dev/dev.c                      |  51 +-
 drivers/net/can/dev/skb.c                      |   6 +-
 drivers/net/can/sja1000/peak_pci.c             |   2 +-
 drivers/net/can/sja1000/sja1000.c              |   2 +-
 drivers/net/can/usb/etas_es58x/es58x_core.c    |   1 +
 drivers/net/can/usb/etas_es58x/es58x_core.h    |   6 +-
 drivers/net/can/usb/etas_es58x/es58x_devlink.c |  57 +-
 include/linux/can/dev.h                        |   4 +
 net/can/raw.c                                  |   3 +-
 11 files changed, 497 insertions(+), 634 deletions(-)



^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH net-next 01/37] can: sja1000: Fix comment
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-06 22:50   ` patchwork-bot+netdevbpf
  2023-10-05 19:57 ` [PATCH net-next 02/37] can: etas_es58x: rework the version check logic to silence -Wformat-truncation Marc Kleine-Budde
                   ` (35 subsequent siblings)
  36 siblings, 1 reply; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, linux-can, kernel, Miquel Raynal, Simon Horman,
	Marc Kleine-Budde

From: Miquel Raynal <miquel.raynal@bootlin.com>

There is likely a copy-paste error here, as the exact same comment
appears below in this function, one time calling set_reset_mode(), the
other set_normal_mode().

Fixes: 429da1cc841b ("can: Driver for the SJA1000 CAN controller")
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/all/20230922155130.592187-1-miquel.raynal@bootlin.com
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/sja1000/sja1000.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 0ada0e160e93..7ffa6c04765e 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -206,7 +206,7 @@ static void sja1000_start(struct net_device *dev)
 {
 	struct sja1000_priv *priv = netdev_priv(dev);
 
-	/* leave reset mode */
+	/* enter reset mode */
 	if (priv->can.state != CAN_STATE_STOPPED)
 		set_reset_mode(dev);
 

base-commit: 473267a4911f2469722c74ca58087d951072f72a
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 02/37] can: etas_es58x: rework the version check logic to silence -Wformat-truncation
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 01/37] can: sja1000: Fix comment Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 03/37] can: etas_es58x: add missing a blank line after declaration Marc Kleine-Budde
                   ` (34 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Vincent Mailhol,
	Marc Kleine-Budde

From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>

Following [1], es58x_devlink.c now triggers the following
format-truncation GCC warnings:

  drivers/net/can/usb/etas_es58x/es58x_devlink.c: In function ‘es58x_devlink_info_get’:
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:201:41: warning: ‘%02u’ directive output may be truncated writing between 2 and 3 bytes into a region of size between 1 and 3 [-Wformat-truncation=]
    201 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |                                         ^~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:201:30: note: directive argument in the range [0, 255]
    201 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |                              ^~~~~~~~~~~~~~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:201:3: note: ‘snprintf’ output between 9 and 12 bytes into a destination of size 9
    201 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    202 |     fw_ver->major, fw_ver->minor, fw_ver->revision);
        |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:211:41: warning: ‘%02u’ directive output may be truncated writing between 2 and 3 bytes into a region of size between 1 and 3 [-Wformat-truncation=]
    211 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |                                         ^~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:211:30: note: directive argument in the range [0, 255]
    211 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |                              ^~~~~~~~~~~~~~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:211:3: note: ‘snprintf’ output between 9 and 12 bytes into a destination of size 9
    211 |   snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
        |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    212 |     bl_ver->major, bl_ver->minor, bl_ver->revision);
        |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:221:38: warning: ‘%03u’ directive output may be truncated writing between 3 and 5 bytes into a region of size between 2 and 4 [-Wformat-truncation=]
    221 |   snprintf(buf, sizeof(buf), "%c%03u/%03u",
        |                                      ^~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:221:30: note: directive argument in the range [0, 65535]
    221 |   snprintf(buf, sizeof(buf), "%c%03u/%03u",
        |                              ^~~~~~~~~~~~~
  drivers/net/can/usb/etas_es58x/es58x_devlink.c:221:3: note: ‘snprintf’ output between 9 and 13 bytes into a destination of size 9
    221 |   snprintf(buf, sizeof(buf), "%c%03u/%03u",
        |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    222 |     hw_rev->letter, hw_rev->major, hw_rev->minor);
        |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is not an actual bug because the sscanf() parsing makes sure that
the u8 are only two digits long and the u16 only three digits long.
Thus below declaration:

	char buf[max(sizeof("xx.xx.xx"), sizeof("axxx/xxx"))];

allocates just what is needed to represent either of the versions.

This warning was known but ignored because, at the time of writing,
-Wformat-truncation was not present in the kernel, not even at W=3 [2].

One way to silence this warning is to check the range of all sub
version numbers are valid: [0, 99] for u8 and range [0, 999] for u16.

The module already has a logic which considers that when all the sub
version numbers are zero, the version number is not set. Note that not
having access to the device specification, this was an arbitrary
decision. This logic can thus be removed in favor of global check that
would cover both cases:

  - the version number is not set (parsing failed)
  - the version number is not valid (paranoiac check to please gcc)

Before starting to parse the product info string, set the version
sub-numbers to the maximum unsigned integer thus violating the
definitions of struct es58x_sw_version or struct es58x_hw_revision.

Then, rework the es58x_sw_version_is_set() and
es58x_hw_revision_is_set() functions: remove the check that the
sub-numbers are non zero and replace it by a check that they fit in
the expected number of digits. This done, rename the functions to
reflect the change and rewrite the documentation. While doing so, also
add a description of the return value.

Finally, the previous version only checked that
&es58x_hw_revision.letter was not the null character. Replace this
check by an alphanumeric character check to make sure that we never
return a special character or a non-printable one and update the
documentation of struct es58x_hw_revision accordingly.

All those extra checks are paranoid but have the merit to silence the
newly introduced W=1 format-truncation warning [1].

[1] commit 6d4ab2e97dcf ("extrawarn: enable format and stringop overflow warnings in W=1")
Link: https://git.kernel.org/torvalds/c/6d4ab2e97dcf

[2] https://lore.kernel.org/all/CAMZ6Rq+K+6gbaZ35SOJcR9qQaTJ7KR0jW=XoDKFkobjhj8CHhw@mail.gmail.com/

Reported-by: Marc Kleine-Budde <mkl@pengutronix.de>
Closes: https://lore.kernel.org/linux-can/20230914-carrousel-wrecker-720a08e173e9-mkl@pengutronix.de/
Fixes: 9f06631c3f1f ("can: etas_es58x: export product information through devlink_ops::info_get()")
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Link: https://lore.kernel.org/all/20230924110914.183898-2-mailhol.vincent@wanadoo.fr
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/usb/etas_es58x/es58x_core.h   |  6 +-
 .../net/can/usb/etas_es58x/es58x_devlink.c    | 57 +++++++++++++------
 2 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.h b/drivers/net/can/usb/etas_es58x/es58x_core.h
index c1ba1a4e8857..2e183bdeedd7 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_core.h
+++ b/drivers/net/can/usb/etas_es58x/es58x_core.h
@@ -378,13 +378,13 @@ struct es58x_sw_version {
 
 /**
  * struct es58x_hw_revision - Hardware revision number.
- * @letter: Revision letter.
+ * @letter: Revision letter, an alphanumeric character.
  * @major: Version major number, represented on three digits.
  * @minor: Version minor number, represented on three digits.
  *
  * The hardware revision uses its own format: "axxx/xxx" where 'a' is
- * a letter and 'x' a digit. It can be retrieved from the product
- * information string.
+ * an alphanumeric character and 'x' a digit. It can be retrieved from
+ * the product information string.
  */
 struct es58x_hw_revision {
 	char letter;
diff --git a/drivers/net/can/usb/etas_es58x/es58x_devlink.c b/drivers/net/can/usb/etas_es58x/es58x_devlink.c
index 9fba29e2f57c..635edeb8f68c 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_devlink.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_devlink.c
@@ -125,14 +125,28 @@ static int es58x_parse_hw_rev(struct es58x_device *es58x_dev,
  * firmware version, the bootloader version and the hardware
  * revision.
  *
- * If the function fails, simply emit a log message and continue
- * because product information is not critical for the driver to
- * operate.
+ * If the function fails, set the version or revision to an invalid
+ * value and emit an informal message. Continue probing because the
+ * product information is not critical for the driver to operate.
  */
 void es58x_parse_product_info(struct es58x_device *es58x_dev)
 {
+	static const struct es58x_sw_version sw_version_not_set = {
+		.major = -1,
+		.minor = -1,
+		.revision = -1,
+	};
+	static const struct es58x_hw_revision hw_revision_not_set = {
+		.letter = '\0',
+		.major = -1,
+		.minor = -1,
+	};
 	char *prod_info;
 
+	es58x_dev->firmware_version = sw_version_not_set;
+	es58x_dev->bootloader_version = sw_version_not_set;
+	es58x_dev->hardware_revision = hw_revision_not_set;
+
 	prod_info = usb_cache_string(es58x_dev->udev, ES58X_PROD_INFO_IDX);
 	if (!prod_info) {
 		dev_warn(es58x_dev->dev,
@@ -150,29 +164,36 @@ void es58x_parse_product_info(struct es58x_device *es58x_dev)
 }
 
 /**
- * es58x_sw_version_is_set() - Check if the version is a valid number.
+ * es58x_sw_version_is_valid() - Check if the version is a valid number.
  * @sw_ver: Version number of either the firmware or the bootloader.
  *
- * If &es58x_sw_version.major, &es58x_sw_version.minor and
- * &es58x_sw_version.revision are all zero, the product string could
- * not be parsed and the version number is invalid.
+ * If any of the software version sub-numbers do not fit on two
+ * digits, the version is invalid, most probably because the product
+ * string could not be parsed.
+ *
+ * Return: @true if the software version is valid, @false otherwise.
  */
-static inline bool es58x_sw_version_is_set(struct es58x_sw_version *sw_ver)
+static inline bool es58x_sw_version_is_valid(struct es58x_sw_version *sw_ver)
 {
-	return sw_ver->major || sw_ver->minor || sw_ver->revision;
+	return sw_ver->major < 100 && sw_ver->minor < 100 &&
+		sw_ver->revision < 100;
 }
 
 /**
- * es58x_hw_revision_is_set() - Check if the revision is a valid number.
+ * es58x_hw_revision_is_valid() - Check if the revision is a valid number.
  * @hw_rev: Revision number of the hardware.
  *
- * If &es58x_hw_revision.letter is the null character, the product
- * string could not be parsed and the hardware revision number is
- * invalid.
+ * If &es58x_hw_revision.letter is not a alphanumeric character or if
+ * any of the hardware revision sub-numbers do not fit on three
+ * digits, the revision is invalid, most probably because the product
+ * string could not be parsed.
+ *
+ * Return: @true if the hardware revision is valid, @false otherwise.
  */
-static inline bool es58x_hw_revision_is_set(struct es58x_hw_revision *hw_rev)
+static inline bool es58x_hw_revision_is_valid(struct es58x_hw_revision *hw_rev)
 {
-	return hw_rev->letter != '\0';
+	return isalnum(hw_rev->letter) && hw_rev->major < 1000 &&
+		hw_rev->minor < 1000;
 }
 
 /**
@@ -197,7 +218,7 @@ static int es58x_devlink_info_get(struct devlink *devlink,
 	char buf[max(sizeof("xx.xx.xx"), sizeof("axxx/xxx"))];
 	int ret = 0;
 
-	if (es58x_sw_version_is_set(fw_ver)) {
+	if (es58x_sw_version_is_valid(fw_ver)) {
 		snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
 			 fw_ver->major, fw_ver->minor, fw_ver->revision);
 		ret = devlink_info_version_running_put(req,
@@ -207,7 +228,7 @@ static int es58x_devlink_info_get(struct devlink *devlink,
 			return ret;
 	}
 
-	if (es58x_sw_version_is_set(bl_ver)) {
+	if (es58x_sw_version_is_valid(bl_ver)) {
 		snprintf(buf, sizeof(buf), "%02u.%02u.%02u",
 			 bl_ver->major, bl_ver->minor, bl_ver->revision);
 		ret = devlink_info_version_running_put(req,
@@ -217,7 +238,7 @@ static int es58x_devlink_info_get(struct devlink *devlink,
 			return ret;
 	}
 
-	if (es58x_hw_revision_is_set(hw_rev)) {
+	if (es58x_hw_revision_is_valid(hw_rev)) {
 		snprintf(buf, sizeof(buf), "%c%03u/%03u",
 			 hw_rev->letter, hw_rev->major, hw_rev->minor);
 		ret = devlink_info_version_fixed_put(req,
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 03/37] can: etas_es58x: add missing a blank line after declaration
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 01/37] can: sja1000: Fix comment Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 02/37] can: etas_es58x: rework the version check logic to silence -Wformat-truncation Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 04/37] can: raw: Remove NULL check before dev_{put, hold} Marc Kleine-Budde
                   ` (33 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Vincent Mailhol,
	Marc Kleine-Budde

From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>

Fix below checkpatch warning:

  WARNING: Missing a blank line after declarations
  #2233: FILE: drivers/net/can/usb/etas_es58x/es58x_core.c:2233:
  +		int ret = es58x_init_netdev(es58x_dev, ch_idx);
  +		if (ret) {

Fixes: d8f26fd689dd ("can: etas_es58x: remove es58x_get_product_info()")
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Link: https://lore.kernel.org/all/20230924110914.183898-3-mailhol.vincent@wanadoo.fr
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/usb/etas_es58x/es58x_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
index 0c7f7505632c..5e3a72b7c469 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
@@ -2230,6 +2230,7 @@ static int es58x_probe(struct usb_interface *intf,
 
 	for (ch_idx = 0; ch_idx < es58x_dev->num_can_ch; ch_idx++) {
 		int ret = es58x_init_netdev(es58x_dev, ch_idx);
+
 		if (ret) {
 			es58x_free_netdevs(es58x_dev);
 			return ret;
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 04/37] can: raw: Remove NULL check before dev_{put, hold}
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (2 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 03/37] can: etas_es58x: add missing a blank line after declaration Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 05/37] can: peak_pci: replace deprecated strncpy with strscpy Marc Kleine-Budde
                   ` (32 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, linux-can, kernel, Jiapeng Chong, Abaci Robot,
	Simon Horman, Oliver Hartkopp, Marc Kleine-Budde

From: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>

The call netdev_{put, hold} of dev_{put, hold} will check NULL, so there
is no need to check before using dev_{put, hold}, remove it to silence
the warning:

./net/can/raw.c:497:2-9: WARNING: NULL check before dev_{put, hold} functions is not needed.

Reported-by: Abaci Robot <abaci@linux.alibaba.com>
Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=6231
Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
Reported-by: Simon Horman <horms@kernel.org>
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://lore.kernel.org/all/20230825064656.87751-1-jiapeng.chong@linux.alibaba.com
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 net/can/raw.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/can/raw.c b/net/can/raw.c
index 73468d2ebd51..e6b822624ba2 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -493,8 +493,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
 
 out_put_dev:
 	/* remove potential reference from dev_get_by_index() */
-	if (dev)
-		dev_put(dev);
+	dev_put(dev);
 out:
 	release_sock(sk);
 	rtnl_unlock();
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 05/37] can: peak_pci: replace deprecated strncpy with strscpy
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (3 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 04/37] can: raw: Remove NULL check before dev_{put, hold} Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 06/37] can: dev: can_restart(): don't crash kernel if carrier is OK Marc Kleine-Budde
                   ` (31 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, linux-can, kernel, Justin Stitt, linux-hardening,
	Kees Cook, Marc Kleine-Budde

From: Justin Stitt <justinstitt@google.com>

`strncpy` is deprecated for use on NUL-terminated destination strings
[1] and as such we should prefer more robust and less ambiguous string
interfaces.

NUL-padding is not required since card is already zero-initialized:
|       card = kzalloc(sizeof(*card), GFP_KERNEL);

A suitable replacement is `strscpy` [2] due to the fact that it
guarantees NUL-termination on the destination buffer without
unnecessarily NUL-padding.

Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1]
Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2]
Link: https://github.com/KSPP/linux/issues/90
Cc: linux-hardening@vger.kernel.org
Signed-off-by: Justin Stitt <justinstitt@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/all/20231005-strncpy-drivers-net-can-sja1000-peak_pci-c-v1-1-c36e1702cd56@google.com
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/sja1000/peak_pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c
index 84f34020aafb..da396d641e24 100644
--- a/drivers/net/can/sja1000/peak_pci.c
+++ b/drivers/net/can/sja1000/peak_pci.c
@@ -462,7 +462,7 @@ static int peak_pciec_probe(struct pci_dev *pdev, struct net_device *dev)
 		card->led_chip.owner = THIS_MODULE;
 		card->led_chip.dev.parent = &pdev->dev;
 		card->led_chip.algo_data = &card->i2c_bit;
-		strncpy(card->led_chip.name, "peak_i2c",
+		strscpy(card->led_chip.name, "peak_i2c",
 			sizeof(card->led_chip.name));
 
 		card->i2c_bit = peak_pciec_i2c_bit_ops;
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 06/37] can: dev: can_restart(): don't crash kernel if carrier is OK
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (4 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 05/37] can: peak_pci: replace deprecated strncpy with strscpy Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 07/37] can: dev: can_restart(): fix race condition between controller restart and netif_carrier_on() Marc Kleine-Budde
                   ` (30 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde,
	Vincent Mailhol

During testing, I triggered a can_restart() with the netif carrier
being OK [1]. The BUG_ON, which checks if the carrier is OK, results
in a fatal kernel crash. This is neither helpful for debugging nor for
a production system.

[1] The root cause is a race condition in can_restart() which will be
fixed in the next patch.

Do not crash the kernel, issue an error message instead, and continue
restarting the CAN device anyway.

Fixes: 39549eef3587 ("can: CAN Network device driver and Netlink interface")
Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-1-91b5c1fd922c@pengutronix.de
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/dev/dev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 7f9334a8af50..a5bbdfa9a269 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -132,7 +132,8 @@ static void can_restart(struct net_device *dev)
 	struct can_frame *cf;
 	int err;
 
-	BUG_ON(netif_carrier_ok(dev));
+	if (netif_carrier_ok(dev))
+		netdev_err(dev, "Attempt to restart for bus-off recovery, but carrier is OK?\n");
 
 	/* No synchronization needed because the device is bus-off and
 	 * no messages can come in or go out.
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 07/37] can: dev: can_restart(): fix race condition between controller restart and netif_carrier_on()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (5 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 06/37] can: dev: can_restart(): don't crash kernel if carrier is OK Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 08/37] can: dev: can_restart(): reverse logic to remove need for goto Marc Kleine-Budde
                   ` (29 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde,
	Vincent Mailhol

This race condition was discovered while updating the at91_can driver
to use can_bus_off(). The following scenario describes how the
converted at91_can driver would behave.

When a CAN device goes into BUS-OFF state, the driver usually
stops/resets the CAN device and calls can_bus_off().

This function sets the netif carrier to off, and (if configured by
user space) schedules a delayed work that calls can_restart() to
restart the CAN device.

The can_restart() function first checks if the carrier is off and
triggers an error message if the carrier is OK.

Then it calls the driver's do_set_mode() function to restart the
device, then it sets the netif carrier to on. There is a race window
between these two calls.

The at91 CAN controller (observed on the sama5d3, a single core 32 bit
ARM CPU) has a hardware limitation. If the device goes into bus-off
while sending a CAN frame, there is no way to abort the sending of
this frame. After the controller is enabled again, another attempt is
made to send it.

If the bus is still faulty, the device immediately goes back to the
bus-off state. The driver calls can_bus_off(), the netif carrier is
switched off and another can_restart is scheduled. This occurs within
the race window before the original can_restart() handler marks the
netif carrier as OK. This would cause the 2nd can_restart() to be
called with an OK netif carrier, resulting in an error message.

The flow of the 1st can_restart() looks like this:

can_restart()
    // bail out if netif_carrier is OK

    netif_carrier_ok(dev)
    priv->do_set_mode(dev, CAN_MODE_START)
        // enable CAN controller
        // sama5d3 restarts sending old message

        // CAN devices goes into BUS_OFF, triggers IRQ

// IRQ handler start
    at91_irq()
        at91_irq_err_line()
            can_bus_off()
                netif_carrier_off()
                schedule_delayed_work()
// IRQ handler end

    netif_carrier_on()

The 2nd can_restart() will be called with an OK netif carrier and the
error message will be printed.

To close the race window, first set the netif carrier to on, then
restart the controller. In case the restart fails with an error code,
roll back the netif carrier to off.

Fixes: 39549eef3587 ("can: CAN Network device driver and Netlink interface")
Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-2-91b5c1fd922c@pengutronix.de
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/dev/dev.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index a5bbdfa9a269..735d5de3caa0 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -154,11 +154,12 @@ static void can_restart(struct net_device *dev)
 	priv->can_stats.restarts++;
 
 	/* Now restart the device */
-	err = priv->do_set_mode(dev, CAN_MODE_START);
-
 	netif_carrier_on(dev);
-	if (err)
+	err = priv->do_set_mode(dev, CAN_MODE_START);
+	if (err) {
 		netdev_err(dev, "Error %d during restart", err);
+		netif_carrier_off(dev);
+	}
 }
 
 static void can_restart_work(struct work_struct *work)
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 08/37] can: dev: can_restart(): reverse logic to remove need for goto
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (6 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 07/37] can: dev: can_restart(): fix race condition between controller restart and netif_carrier_on() Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 09/37] can: dev: can_restart(): move debug message and stats after successful restart Marc Kleine-Budde
                   ` (28 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde,
	Vincent Mailhol

Reverse the logic in the if statement and eliminate the need for a
goto to simplify code readability.

Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-3-91b5c1fd922c@pengutronix.de
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/dev/dev.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 735d5de3caa0..9014256c486a 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -142,14 +142,11 @@ static void can_restart(struct net_device *dev)
 
 	/* send restart message upstream */
 	skb = alloc_can_err_skb(dev, &cf);
-	if (!skb)
-		goto restart;
+	if (skb) {
+		cf->can_id |= CAN_ERR_RESTARTED;
+		netif_rx(skb);
+	}
 
-	cf->can_id |= CAN_ERR_RESTARTED;
-
-	netif_rx(skb);
-
-restart:
 	netdev_dbg(dev, "restarted\n");
 	priv->can_stats.restarts++;
 
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 09/37] can: dev: can_restart(): move debug message and stats after successful restart
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (7 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 08/37] can: dev: can_restart(): reverse logic to remove need for goto Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 10/37] can: dev: can_put_echo_skb(): don't crash kernel if can_priv::echo_skb is accessed out of bounds Marc Kleine-Budde
                   ` (27 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde,
	Vincent Mailhol

Move the debug message "restarted" and the CAN restart stats_after_
the successful restart of the CAN device, because the restart may
fail.

While there update the error message from printing the error number to
printing symbolic error names.

Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-4-91b5c1fd922c@pengutronix.de
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
[mkl: mention stats in subject and description, too]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/dev/dev.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 9014256c486a..82b12902fc35 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -147,15 +147,15 @@ static void can_restart(struct net_device *dev)
 		netif_rx(skb);
 	}
 
-	netdev_dbg(dev, "restarted\n");
-	priv->can_stats.restarts++;
-
 	/* Now restart the device */
 	netif_carrier_on(dev);
 	err = priv->do_set_mode(dev, CAN_MODE_START);
 	if (err) {
-		netdev_err(dev, "Error %d during restart", err);
+		netdev_err(dev, "Restart failed, error %pe\n", ERR_PTR(err));
 		netif_carrier_off(dev);
+	} else {
+		netdev_dbg(dev, "Restarted\n");
+		priv->can_stats.restarts++;
 	}
 }
 
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 10/37] can: dev: can_put_echo_skb(): don't crash kernel if can_priv::echo_skb is accessed out of bounds
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (8 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 09/37] can: dev: can_restart(): move debug message and stats after successful restart Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 11/37] can: dev: add can_state_get_by_berr_counter() to return the CAN state based on the current error counters Marc Kleine-Budde
                   ` (26 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde,
	Vincent Mailhol

If the "struct can_priv::echoo_skb" is accessed out of bounds, this
would cause a kernel crash. Instead, issue a meaningful warning
message and return with an error.

Fixes: a6e4bc530403 ("can: make the number of echo skb's configurable")
Link: https://lore.kernel.org/all/20231005-can-dev-fix-can-restart-v2-5-91b5c1fd922c@pengutronix.de
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/dev/skb.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index f6d05b3ef59a..3ebd4f779b9b 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -49,7 +49,11 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
 {
 	struct can_priv *priv = netdev_priv(dev);
 
-	BUG_ON(idx >= priv->echo_skb_max);
+	if (idx >= priv->echo_skb_max) {
+		netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
+			   __func__, idx, priv->echo_skb_max);
+		return -EINVAL;
+	}
 
 	/* check flag whether this packet has to be looped back */
 	if (!(dev->flags & IFF_ECHO) ||
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 11/37] can: dev: add can_state_get_by_berr_counter() to return the CAN state based on the current error counters
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (9 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 10/37] can: dev: can_put_echo_skb(): don't crash kernel if can_priv::echo_skb is accessed out of bounds Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 12/37] can: at91_can: use a consistent indention Marc Kleine-Budde
                   ` (25 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Some CAN controllers do not have a register that contains the current
CAN state, but only a register that contains the error counters.

Introduce a new function can_state_get_by_berr_counter() that returns
the current TX and RX state depending on the provided CAN bit error
counters.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-1-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/dev/dev.c | 22 ++++++++++++++++++++++
 include/linux/can/dev.h   |  4 ++++
 2 files changed, 26 insertions(+)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 82b12902fc35..3a3be5cdfc1f 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -90,6 +90,28 @@ const char *can_get_state_str(const enum can_state state)
 }
 EXPORT_SYMBOL_GPL(can_get_state_str);
 
+static enum can_state can_state_err_to_state(u16 err)
+{
+	if (err < CAN_ERROR_WARNING_THRESHOLD)
+		return CAN_STATE_ERROR_ACTIVE;
+	if (err < CAN_ERROR_PASSIVE_THRESHOLD)
+		return CAN_STATE_ERROR_WARNING;
+	if (err < CAN_BUS_OFF_THRESHOLD)
+		return CAN_STATE_ERROR_PASSIVE;
+
+	return CAN_STATE_BUS_OFF;
+}
+
+void can_state_get_by_berr_counter(const struct net_device *dev,
+				   const struct can_berr_counter *bec,
+				   enum can_state *tx_state,
+				   enum can_state *rx_state)
+{
+	*tx_state = can_state_err_to_state(bec->txerr);
+	*rx_state = can_state_err_to_state(bec->rxerr);
+}
+EXPORT_SYMBOL_GPL(can_state_get_by_berr_counter);
+
 void can_change_state(struct net_device *dev, struct can_frame *cf,
 		      enum can_state tx_state, enum can_state rx_state)
 {
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 982ba245eb41..1b92aed49363 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -195,6 +195,10 @@ int can_restart_now(struct net_device *dev);
 void can_bus_off(struct net_device *dev);
 
 const char *can_get_state_str(const enum can_state state);
+void can_state_get_by_berr_counter(const struct net_device *dev,
+				   const struct can_berr_counter *bec,
+				   enum can_state *tx_state,
+				   enum can_state *rx_state);
 void can_change_state(struct net_device *dev, struct can_frame *cf,
 		      enum can_state tx_state, enum can_state rx_state);
 
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 12/37] can: at91_can: use a consistent indention
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (10 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 11/37] can: dev: add can_state_get_by_berr_counter() to return the CAN state based on the current error counters Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 13/37] can: at91_can: at91_irq_tx(): remove one level of indention Marc Kleine-Budde
                   ` (24 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Convert the driver to use a consistent indention of one space after
defines and in enums. That makes it easier to add new defines, which
will be done in the coming patches.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-2-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 124 ++++++++++++++++++-------------------
 1 file changed, 62 insertions(+), 62 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 4621266851ed..367ccf109652 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -25,89 +25,89 @@
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
 
-#define AT91_MB_MASK(i)		((1 << (i)) - 1)
+#define AT91_MB_MASK(i) ((1 << (i)) - 1)
 
 /* Common registers */
 enum at91_reg {
-	AT91_MR		= 0x000,
-	AT91_IER	= 0x004,
-	AT91_IDR	= 0x008,
-	AT91_IMR	= 0x00C,
-	AT91_SR		= 0x010,
-	AT91_BR		= 0x014,
-	AT91_TIM	= 0x018,
-	AT91_TIMESTP	= 0x01C,
-	AT91_ECR	= 0x020,
-	AT91_TCR	= 0x024,
-	AT91_ACR	= 0x028,
+	AT91_MR = 0x000,
+	AT91_IER = 0x004,
+	AT91_IDR = 0x008,
+	AT91_IMR = 0x00C,
+	AT91_SR = 0x010,
+	AT91_BR = 0x014,
+	AT91_TIM = 0x018,
+	AT91_TIMESTP = 0x01C,
+	AT91_ECR = 0x020,
+	AT91_TCR = 0x024,
+	AT91_ACR = 0x028,
 };
 
 /* Mailbox registers (0 <= i <= 15) */
-#define AT91_MMR(i)		((enum at91_reg)(0x200 + ((i) * 0x20)))
-#define AT91_MAM(i)		((enum at91_reg)(0x204 + ((i) * 0x20)))
-#define AT91_MID(i)		((enum at91_reg)(0x208 + ((i) * 0x20)))
-#define AT91_MFID(i)		((enum at91_reg)(0x20C + ((i) * 0x20)))
-#define AT91_MSR(i)		((enum at91_reg)(0x210 + ((i) * 0x20)))
-#define AT91_MDL(i)		((enum at91_reg)(0x214 + ((i) * 0x20)))
-#define AT91_MDH(i)		((enum at91_reg)(0x218 + ((i) * 0x20)))
-#define AT91_MCR(i)		((enum at91_reg)(0x21C + ((i) * 0x20)))
+#define AT91_MMR(i) ((enum at91_reg)(0x200 + ((i) * 0x20)))
+#define AT91_MAM(i) ((enum at91_reg)(0x204 + ((i) * 0x20)))
+#define AT91_MID(i) ((enum at91_reg)(0x208 + ((i) * 0x20)))
+#define AT91_MFID(i) ((enum at91_reg)(0x20C + ((i) * 0x20)))
+#define AT91_MSR(i) ((enum at91_reg)(0x210 + ((i) * 0x20)))
+#define AT91_MDL(i) ((enum at91_reg)(0x214 + ((i) * 0x20)))
+#define AT91_MDH(i) ((enum at91_reg)(0x218 + ((i) * 0x20)))
+#define AT91_MCR(i) ((enum at91_reg)(0x21C + ((i) * 0x20)))
 
 /* Register bits */
-#define AT91_MR_CANEN		BIT(0)
-#define AT91_MR_LPM		BIT(1)
-#define AT91_MR_ABM		BIT(2)
-#define AT91_MR_OVL		BIT(3)
-#define AT91_MR_TEOF		BIT(4)
-#define AT91_MR_TTM		BIT(5)
-#define AT91_MR_TIMFRZ		BIT(6)
-#define AT91_MR_DRPT		BIT(7)
+#define AT91_MR_CANEN BIT(0)
+#define AT91_MR_LPM BIT(1)
+#define AT91_MR_ABM BIT(2)
+#define AT91_MR_OVL BIT(3)
+#define AT91_MR_TEOF BIT(4)
+#define AT91_MR_TTM BIT(5)
+#define AT91_MR_TIMFRZ BIT(6)
+#define AT91_MR_DRPT BIT(7)
 
-#define AT91_SR_RBSY		BIT(29)
+#define AT91_SR_RBSY BIT(29)
 
-#define AT91_MMR_PRIO_SHIFT	(16)
+#define AT91_MMR_PRIO_SHIFT (16)
 
-#define AT91_MID_MIDE		BIT(29)
+#define AT91_MID_MIDE BIT(29)
 
-#define AT91_MSR_MRTR		BIT(20)
-#define AT91_MSR_MABT		BIT(22)
-#define AT91_MSR_MRDY		BIT(23)
-#define AT91_MSR_MMI		BIT(24)
+#define AT91_MSR_MRTR BIT(20)
+#define AT91_MSR_MABT BIT(22)
+#define AT91_MSR_MRDY BIT(23)
+#define AT91_MSR_MMI BIT(24)
 
-#define AT91_MCR_MRTR		BIT(20)
-#define AT91_MCR_MTCR		BIT(23)
+#define AT91_MCR_MRTR BIT(20)
+#define AT91_MCR_MTCR BIT(23)
 
 /* Mailbox Modes */
 enum at91_mb_mode {
-	AT91_MB_MODE_DISABLED	= 0,
-	AT91_MB_MODE_RX		= 1,
-	AT91_MB_MODE_RX_OVRWR	= 2,
-	AT91_MB_MODE_TX		= 3,
-	AT91_MB_MODE_CONSUMER	= 4,
-	AT91_MB_MODE_PRODUCER	= 5,
+	AT91_MB_MODE_DISABLED = 0,
+	AT91_MB_MODE_RX = 1,
+	AT91_MB_MODE_RX_OVRWR = 2,
+	AT91_MB_MODE_TX = 3,
+	AT91_MB_MODE_CONSUMER = 4,
+	AT91_MB_MODE_PRODUCER = 5,
 };
 
 /* Interrupt mask bits */
-#define AT91_IRQ_ERRA		BIT(16)
-#define AT91_IRQ_WARN		BIT(17)
-#define AT91_IRQ_ERRP		BIT(18)
-#define AT91_IRQ_BOFF		BIT(19)
-#define AT91_IRQ_SLEEP		BIT(20)
-#define AT91_IRQ_WAKEUP		BIT(21)
-#define AT91_IRQ_TOVF		BIT(22)
-#define AT91_IRQ_TSTP		BIT(23)
-#define AT91_IRQ_CERR		BIT(24)
-#define AT91_IRQ_SERR		BIT(25)
-#define AT91_IRQ_AERR		BIT(26)
-#define AT91_IRQ_FERR		BIT(27)
-#define AT91_IRQ_BERR		BIT(28)
+#define AT91_IRQ_ERRA BIT(16)
+#define AT91_IRQ_WARN BIT(17)
+#define AT91_IRQ_ERRP BIT(18)
+#define AT91_IRQ_BOFF BIT(19)
+#define AT91_IRQ_SLEEP BIT(20)
+#define AT91_IRQ_WAKEUP BIT(21)
+#define AT91_IRQ_TOVF BIT(22)
+#define AT91_IRQ_TSTP BIT(23)
+#define AT91_IRQ_CERR BIT(24)
+#define AT91_IRQ_SERR BIT(25)
+#define AT91_IRQ_AERR BIT(26)
+#define AT91_IRQ_FERR BIT(27)
+#define AT91_IRQ_BERR BIT(28)
 
-#define AT91_IRQ_ERR_ALL	(0x1fff0000)
-#define AT91_IRQ_ERR_FRAME	(AT91_IRQ_CERR | AT91_IRQ_SERR | \
-				 AT91_IRQ_AERR | AT91_IRQ_FERR | AT91_IRQ_BERR)
-#define AT91_IRQ_ERR_LINE	(AT91_IRQ_ERRA | AT91_IRQ_WARN | \
-				 AT91_IRQ_ERRP | AT91_IRQ_BOFF)
+#define AT91_IRQ_ERR_ALL (0x1fff0000)
+#define AT91_IRQ_ERR_FRAME (AT91_IRQ_CERR | AT91_IRQ_SERR | \
+			    AT91_IRQ_AERR | AT91_IRQ_FERR | AT91_IRQ_BERR)
+#define AT91_IRQ_ERR_LINE (AT91_IRQ_ERRA | AT91_IRQ_WARN | \
+			   AT91_IRQ_ERRP | AT91_IRQ_BOFF)
 
-#define AT91_IRQ_ALL		(0x1fffffff)
+#define AT91_IRQ_ALL (0x1fffffff)
 
 enum at91_devtype {
 	AT91_DEVTYPE_SAM9263,
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 13/37] can: at91_can: at91_irq_tx(): remove one level of indention
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (11 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 12/37] can: at91_can: use a consistent indention Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 14/37] can: at91_can: BR register: convert to FIELD_PREP() Marc Kleine-Budde
                   ` (23 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Improve code readability by removing one level of indention.

If a mailbox is not ready, continue the loop early.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-3-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 367ccf109652..966980d4b5dd 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -844,15 +844,14 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr)
 		 * parked in the echo queue.
 		 */
 		reg_msr = at91_read(priv, AT91_MSR(mb));
-		if (likely(reg_msr & AT91_MSR_MRDY &&
-			   ~reg_msr & AT91_MSR_MABT)) {
-			/* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */
-			dev->stats.tx_bytes +=
-				can_get_echo_skb(dev,
-						 mb - get_mb_tx_first(priv),
-						 NULL);
-			dev->stats.tx_packets++;
-		}
+		if (unlikely(!(reg_msr & AT91_MSR_MRDY &&
+			       ~reg_msr & AT91_MSR_MABT)))
+			continue;
+
+		/* _NOTE_: subtract AT91_MB_TX_FIRST offset from mb! */
+		dev->stats.tx_bytes +=
+			can_get_echo_skb(dev, mb - get_mb_tx_first(priv), NULL);
+		dev->stats.tx_packets++;
 	}
 
 	/* restart queue if we don't have a wrap around but restart if
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 14/37] can: at91_can: BR register: convert to FIELD_PREP()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (12 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 13/37] can: at91_can: at91_irq_tx(): remove one level of indention Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 15/37] can: at91_can: ECR register: convert to FIELD_GET() Marc Kleine-Budde
                   ` (22 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Use FIELD_PREP() to access the individual fields of the BR register.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-4-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 966980d4b5dd..79eb78b9f8ae 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -6,6 +6,7 @@
  * (C) 2008, 2009, 2010, 2011 by Marc Kleine-Budde <kernel@pengutronix.de>
  */
 
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/errno.h>
 #include <linux/ethtool.h>
@@ -64,6 +65,13 @@ enum at91_reg {
 
 #define AT91_SR_RBSY BIT(29)
 
+#define AT91_BR_PHASE2_MASK GENMASK(2, 0)
+#define AT91_BR_PHASE1_MASK GENMASK(6, 4)
+#define AT91_BR_PROPAG_MASK GENMASK(10, 8)
+#define AT91_BR_SJW_MASK GENMASK(13, 12)
+#define AT91_BR_BRP_MASK GENMASK(22, 16)
+#define AT91_BR_SMP BIT(24)
+
 #define AT91_MMR_PRIO_SHIFT (16)
 
 #define AT91_MID_MIDE BIT(29)
@@ -353,12 +361,16 @@ static int at91_set_bittiming(struct net_device *dev)
 {
 	const struct at91_priv *priv = netdev_priv(dev);
 	const struct can_bittiming *bt = &priv->can.bittiming;
-	u32 reg_br;
+	u32 reg_br = 0;
 
-	reg_br = ((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 << 24 : 0) |
-		((bt->brp - 1) << 16) | ((bt->sjw - 1) << 12) |
-		((bt->prop_seg - 1) << 8) | ((bt->phase_seg1 - 1) << 4) |
-		((bt->phase_seg2 - 1) << 0);
+	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+		reg_br |= AT91_BR_SMP;
+
+	reg_br |= FIELD_PREP(AT91_BR_BRP_MASK, bt->brp - 1) |
+		FIELD_PREP(AT91_BR_SJW_MASK, bt->sjw - 1) |
+		FIELD_PREP(AT91_BR_PROPAG_MASK, bt->prop_seg - 1) |
+		FIELD_PREP(AT91_BR_PHASE1_MASK, bt->phase_seg1 - 1) |
+		FIELD_PREP(AT91_BR_PHASE2_MASK, bt->phase_seg2 - 1);
 
 	netdev_info(dev, "writing AT91_BR: 0x%08x\n", reg_br);
 
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 15/37] can: at91_can: ECR register: convert to FIELD_GET()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (13 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 14/37] can: at91_can: BR register: convert to FIELD_PREP() Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 16/37] can: at91_can: MMR registers: convert to FIELD_PREP() Marc Kleine-Budde
                   ` (21 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Use FIELD_GET() to access the individual fields of the ECR register.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-5-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 79eb78b9f8ae..7597da543348 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -72,6 +72,9 @@ enum at91_reg {
 #define AT91_BR_BRP_MASK GENMASK(22, 16)
 #define AT91_BR_SMP BIT(24)
 
+#define AT91_ECR_REC_MASK GENMASK(8, 0)
+#define AT91_ECR_TEC_MASK GENMASK(23, 16)
+
 #define AT91_MMR_PRIO_SHIFT (16)
 
 #define AT91_MID_MIDE BIT(29)
@@ -385,8 +388,8 @@ static int at91_get_berr_counter(const struct net_device *dev,
 	const struct at91_priv *priv = netdev_priv(dev);
 	u32 reg_ecr = at91_read(priv, AT91_ECR);
 
-	bec->rxerr = reg_ecr & 0xff;
-	bec->txerr = reg_ecr >> 16;
+	bec->rxerr = FIELD_GET(AT91_ECR_REC_MASK, reg_ecr);
+	bec->txerr = FIELD_GET(AT91_ECR_TEC_MASK, reg_ecr);
 
 	return 0;
 }
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 16/37] can: at91_can: MMR registers: convert to FIELD_PREP()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (14 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 15/37] can: at91_can: ECR register: convert to FIELD_GET() Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 17/37] can: at91_can: MID registers: convert access to FIELD_PREP(), FIELD_GET() Marc Kleine-Budde
                   ` (20 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Use FIELD_PREP() to access the individual fields of the MMR register.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-6-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 7597da543348..16a62f649418 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -75,7 +75,9 @@ enum at91_reg {
 #define AT91_ECR_REC_MASK GENMASK(8, 0)
 #define AT91_ECR_TEC_MASK GENMASK(23, 16)
 
-#define AT91_MMR_PRIO_SHIFT (16)
+#define AT91_MMR_MTIMEMARK_MASK GENMASK(15, 0)
+#define AT91_MMR_PRIOR_MASK GENMASK(19, 16)
+#define AT91_MMR_MOT_MASK GENMASK(26, 24)
 
 #define AT91_MID_MIDE BIT(29)
 
@@ -299,9 +301,12 @@ static inline void at91_write(const struct at91_priv *priv, enum at91_reg reg,
 
 static inline void set_mb_mode_prio(const struct at91_priv *priv,
 				    unsigned int mb, enum at91_mb_mode mode,
-				    int prio)
+				    u8 prio)
 {
-	at91_write(priv, AT91_MMR(mb), (mode << 24) | (prio << 16));
+	const u32 reg_mmr = FIELD_PREP(AT91_MMR_MOT_MASK, mode) |
+		FIELD_PREP(AT91_MMR_PRIOR_MASK, prio);
+
+	at91_write(priv, AT91_MMR(mb), reg_mmr);
 }
 
 static inline void set_mb_mode(const struct at91_priv *priv, unsigned int mb,
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 17/37] can: at91_can: MID registers: convert access to FIELD_PREP(), FIELD_GET()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (15 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 16/37] can: at91_can: MMR registers: convert to FIELD_PREP() Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 18/37] can: at91_can: MSR Register: convert to FIELD_PREP() Marc Kleine-Budde
                   ` (19 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Use FIELD_PREP() and FIELD_GET() to access the individual fields of
the MID register.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-7-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 16a62f649418..ec028fe833f0 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -79,6 +79,8 @@ enum at91_reg {
 #define AT91_MMR_PRIOR_MASK GENMASK(19, 16)
 #define AT91_MMR_MOT_MASK GENMASK(26, 24)
 
+#define AT91_MID_MIDVB_MASK GENMASK(17, 0)
+#define AT91_MID_MIDVA_MASK GENMASK(28, 18)
 #define AT91_MID_MIDE BIT(29)
 
 #define AT91_MSR_MRTR BIT(20)
@@ -320,9 +322,10 @@ static inline u32 at91_can_id_to_reg_mid(canid_t can_id)
 	u32 reg_mid;
 
 	if (can_id & CAN_EFF_FLAG)
-		reg_mid = (can_id & CAN_EFF_MASK) | AT91_MID_MIDE;
+		reg_mid = FIELD_PREP(AT91_MID_MIDVA_MASK | AT91_MID_MIDVB_MASK, can_id) |
+			AT91_MID_MIDE;
 	else
-		reg_mid = (can_id & CAN_SFF_MASK) << 18;
+		reg_mid = FIELD_PREP(AT91_MID_MIDVA_MASK, can_id);
 
 	return reg_mid;
 }
@@ -590,9 +593,10 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb,
 
 	reg_mid = at91_read(priv, AT91_MID(mb));
 	if (reg_mid & AT91_MID_MIDE)
-		cf->can_id = ((reg_mid >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
+		cf->can_id = FIELD_GET(AT91_MID_MIDVA_MASK | AT91_MID_MIDVB_MASK, reg_mid) |
+			CAN_EFF_FLAG;
 	else
-		cf->can_id = (reg_mid >> 18) & CAN_SFF_MASK;
+		cf->can_id = FIELD_GET(AT91_MID_MIDVA_MASK, reg_mid);
 
 	reg_msr = at91_read(priv, AT91_MSR(mb));
 	cf->len = can_cc_dlc2len((reg_msr >> 16) & 0xf);
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 18/37] can: at91_can: MSR Register: convert to FIELD_PREP()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (16 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 17/37] can: at91_can: MID registers: convert access to FIELD_PREP(), FIELD_GET() Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 19/37] can: at91_can: MCR " Marc Kleine-Budde
                   ` (18 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Use FIELD_PREP() to access the individual fields of the MSR register.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-8-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index ec028fe833f0..41dd2ea239b9 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -83,6 +83,8 @@ enum at91_reg {
 #define AT91_MID_MIDVA_MASK GENMASK(28, 18)
 #define AT91_MID_MIDE BIT(29)
 
+#define AT91_MSR_MTIMESTAMP_MASK GENMASK(15, 0)
+#define AT91_MSR_MDLC_MASK GENMASK(19, 16)
 #define AT91_MSR_MRTR BIT(20)
 #define AT91_MSR_MABT BIT(22)
 #define AT91_MSR_MRDY BIT(23)
@@ -599,7 +601,7 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb,
 		cf->can_id = FIELD_GET(AT91_MID_MIDVA_MASK, reg_mid);
 
 	reg_msr = at91_read(priv, AT91_MSR(mb));
-	cf->len = can_cc_dlc2len((reg_msr >> 16) & 0xf);
+	cf->len = can_cc_dlc2len(FIELD_GET(AT91_MSR_MDLC_MASK, reg_msr));
 
 	if (reg_msr & AT91_MSR_MRTR) {
 		cf->can_id |= CAN_RTR_FLAG;
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 19/37] can: at91_can: MCR Register: convert to FIELD_PREP()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (17 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 18/37] can: at91_can: MSR Register: convert to FIELD_PREP() Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 20/37] can: at91_can: add more register definitions Marc Kleine-Budde
                   ` (17 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Use FIELD_PREP() to access the individual fields of the MCR register.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-9-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 41dd2ea239b9..0269e2a6508a 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -90,7 +90,9 @@ enum at91_reg {
 #define AT91_MSR_MRDY BIT(23)
 #define AT91_MSR_MMI BIT(24)
 
+#define AT91_MCR_MDLC_MASK GENMASK(19, 16)
 #define AT91_MCR_MRTR BIT(20)
+#define AT91_MCR_MACR BIT(22)
 #define AT91_MCR_MTCR BIT(23)
 
 /* Mailbox Modes */
@@ -490,8 +492,12 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		return NETDEV_TX_BUSY;
 	}
 	reg_mid = at91_can_id_to_reg_mid(cf->can_id);
-	reg_mcr = ((cf->can_id & CAN_RTR_FLAG) ? AT91_MCR_MRTR : 0) |
-		(cf->len << 16) | AT91_MCR_MTCR;
+
+	reg_mcr = FIELD_PREP(AT91_MCR_MDLC_MASK, cf->len) |
+		AT91_MCR_MTCR;
+
+	if (cf->can_id & CAN_RTR_FLAG)
+		reg_mcr |= AT91_MCR_MRTR;
 
 	/* disable MB while writing ID (see datasheet) */
 	set_mb_mode(priv, mb, AT91_MB_MODE_DISABLED);
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 20/37] can: at91_can: add more register definitions
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (18 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 19/37] can: at91_can: MCR " Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 21/37] can: at91_can: at91_setup_mailboxes(): update comments Marc Kleine-Budde
                   ` (16 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Add more register definitions found in the data sheet.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-10-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 0269e2a6508a..f23d036d947d 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -64,6 +64,8 @@ enum at91_reg {
 #define AT91_MR_DRPT BIT(7)
 
 #define AT91_SR_RBSY BIT(29)
+#define AT91_SR_TBSY BIT(30)
+#define AT91_SR_OVLSY BIT(31)
 
 #define AT91_BR_PHASE2_MASK GENMASK(2, 0)
 #define AT91_BR_PHASE1_MASK GENMASK(6, 4)
@@ -72,9 +74,13 @@ enum at91_reg {
 #define AT91_BR_BRP_MASK GENMASK(22, 16)
 #define AT91_BR_SMP BIT(24)
 
+#define AT91_TIM_TIMER_MASK GENMASK(15, 0)
+
 #define AT91_ECR_REC_MASK GENMASK(8, 0)
 #define AT91_ECR_TEC_MASK GENMASK(23, 16)
 
+#define AT91_TCR_TIMRST BIT(31)
+
 #define AT91_MMR_MTIMEMARK_MASK GENMASK(15, 0)
 #define AT91_MMR_PRIOR_MASK GENMASK(19, 16)
 #define AT91_MMR_MOT_MASK GENMASK(26, 24)
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 21/37] can: at91_can: at91_setup_mailboxes(): update comments
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (19 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 20/37] can: at91_can: add more register definitions Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 22/37] can: at91_can: rename struct at91_priv::{tx_next,tx_echo} to {tx_head,tx_tail} Marc Kleine-Budde
                   ` (15 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Since 6388b3961420 ("can: at91_can: add support for the AT91SAM9X5
SOCs") the number of mailboxes used for RX and TX is no longer
constant, but depends on the IP core used.

Remove the fixed number of mailboxes from the comment.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-11-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index f23d036d947d..b94fb35dc59e 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -347,8 +347,8 @@ static void at91_setup_mailboxes(struct net_device *dev)
 	u32 reg_mid;
 
 	/* Due to a chip bug (errata 50.2.6.3 & 50.3.5.3) the first
-	 * mailbox is disabled. The next 11 mailboxes are used as a
-	 * reception FIFO. The last mailbox is configured with
+	 * mailbox is disabled. The next mailboxes are used as a
+	 * reception FIFO. The last of the RX mailboxes is configured with
 	 * overwrite option. The overwrite flag indicates a FIFO
 	 * overflow.
 	 */
@@ -369,7 +369,7 @@ static void at91_setup_mailboxes(struct net_device *dev)
 		at91_write(priv, AT91_MID(i), AT91_MID_MIDE);
 	}
 
-	/* The last 4 mailboxes are used for transmitting. */
+	/* The last mailboxes are used for transmitting. */
 	for (i = get_mb_tx_first(priv); i <= get_mb_tx_last(priv); i++)
 		set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0);
 
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 22/37] can: at91_can: rename struct at91_priv::{tx_next,tx_echo} to {tx_head,tx_tail}
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (20 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 21/37] can: at91_can: at91_setup_mailboxes(): update comments Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 23/37] can: at91_can: at91_set_bittiming(): demote register output to debug level Marc Kleine-Budde
                   ` (14 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

To increase code readability, use the same naming of the counters for
the TX FIFO as in the other drivers implementing the same algorithm.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-12-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 56 +++++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index b94fb35dc59e..092652fd7352 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -154,8 +154,8 @@ struct at91_priv {
 	void __iomem *reg_base;
 
 	u32 reg_sr;
-	unsigned int tx_next;
-	unsigned int tx_echo;
+	unsigned int tx_head;
+	unsigned int tx_tail;
 	unsigned int rx_next;
 	struct at91_devtype_data devtype_data;
 
@@ -253,24 +253,24 @@ static inline unsigned int get_mb_tx_last(const struct at91_priv *priv)
 	return get_mb_tx_first(priv) + get_mb_tx_num(priv) - 1;
 }
 
-static inline unsigned int get_next_prio_shift(const struct at91_priv *priv)
+static inline unsigned int get_head_prio_shift(const struct at91_priv *priv)
 {
 	return get_mb_tx_shift(priv);
 }
 
-static inline unsigned int get_next_prio_mask(const struct at91_priv *priv)
+static inline unsigned int get_head_prio_mask(const struct at91_priv *priv)
 {
 	return 0xf << get_mb_tx_shift(priv);
 }
 
-static inline unsigned int get_next_mb_mask(const struct at91_priv *priv)
+static inline unsigned int get_head_mb_mask(const struct at91_priv *priv)
 {
 	return AT91_MB_MASK(get_mb_tx_shift(priv));
 }
 
-static inline unsigned int get_next_mask(const struct at91_priv *priv)
+static inline unsigned int get_head_mask(const struct at91_priv *priv)
 {
-	return get_next_mb_mask(priv) | get_next_prio_mask(priv);
+	return get_head_mb_mask(priv) | get_head_prio_mask(priv);
 }
 
 static inline unsigned int get_irq_mb_rx(const struct at91_priv *priv)
@@ -285,19 +285,19 @@ static inline unsigned int get_irq_mb_tx(const struct at91_priv *priv)
 		~AT91_MB_MASK(get_mb_tx_first(priv));
 }
 
-static inline unsigned int get_tx_next_mb(const struct at91_priv *priv)
+static inline unsigned int get_tx_head_mb(const struct at91_priv *priv)
 {
-	return (priv->tx_next & get_next_mb_mask(priv)) + get_mb_tx_first(priv);
+	return (priv->tx_head & get_head_mb_mask(priv)) + get_mb_tx_first(priv);
 }
 
-static inline unsigned int get_tx_next_prio(const struct at91_priv *priv)
+static inline unsigned int get_tx_head_prio(const struct at91_priv *priv)
 {
-	return (priv->tx_next >> get_next_prio_shift(priv)) & 0xf;
+	return (priv->tx_head >> get_head_prio_shift(priv)) & 0xf;
 }
 
-static inline unsigned int get_tx_echo_mb(const struct at91_priv *priv)
+static inline unsigned int get_tx_tail_mb(const struct at91_priv *priv)
 {
-	return (priv->tx_echo & get_next_mb_mask(priv)) + get_mb_tx_first(priv);
+	return (priv->tx_tail & get_head_mb_mask(priv)) + get_mb_tx_first(priv);
 }
 
 static inline u32 at91_read(const struct at91_priv *priv, enum at91_reg reg)
@@ -374,7 +374,7 @@ static void at91_setup_mailboxes(struct net_device *dev)
 		set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0);
 
 	/* Reset tx and rx helper pointers */
-	priv->tx_next = priv->tx_echo = 0;
+	priv->tx_head = priv->tx_tail = 0;
 	priv->rx_next = get_mb_rx_first(priv);
 }
 
@@ -470,11 +470,11 @@ static void at91_chip_stop(struct net_device *dev, enum can_state state)
  * stop sending, waiting for all messages to be delivered, then start
  * again with mailbox AT91_MB_TX_FIRST prio 0.
  *
- * We use the priv->tx_next as counter for the next transmission
+ * We use the priv->tx_head as counter for the next transmission
  * mailbox, but without the offset AT91_MB_TX_FIRST. The lower bits
  * encode the mailbox number, the upper 4 bits the mailbox priority:
  *
- * priv->tx_next = (prio << get_next_prio_shift(priv)) |
+ * priv->tx_head = (prio << get_next_prio_shift(priv)) |
  *                 (mb - get_mb_tx_first(priv));
  *
  */
@@ -488,8 +488,8 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (can_dev_dropped_skb(dev, skb))
 		return NETDEV_TX_OK;
 
-	mb = get_tx_next_mb(priv);
-	prio = get_tx_next_prio(priv);
+	mb = get_tx_head_mb(priv);
+	prio = get_tx_head_prio(priv);
 
 	if (unlikely(!(at91_read(priv, AT91_MSR(mb)) & AT91_MSR_MRDY))) {
 		netif_stop_queue(dev);
@@ -521,15 +521,15 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* we have to stop the queue and deliver all messages in case
 	 * of a prio+mb counter wrap around. This is the case if
-	 * tx_next buffer prio and mailbox equals 0.
+	 * tx_head buffer prio and mailbox equals 0.
 	 *
 	 * also stop the queue if next buffer is still in use
 	 * (== not ready)
 	 */
-	priv->tx_next++;
-	if (!(at91_read(priv, AT91_MSR(get_tx_next_mb(priv))) &
+	priv->tx_head++;
+	if (!(at91_read(priv, AT91_MSR(get_tx_head_mb(priv))) &
 	      AT91_MSR_MRDY) ||
-	    (priv->tx_next & get_next_mask(priv)) == 0)
+	    (priv->tx_head & get_head_mask(priv)) == 0)
 		netif_stop_queue(dev);
 
 	/* Enable interrupt for this mailbox */
@@ -849,11 +849,11 @@ static int at91_poll(struct napi_struct *napi, int quota)
 
 /* theory of operation:
  *
- * priv->tx_echo holds the number of the oldest can_frame put for
+ * priv->tx_tail holds the number of the oldest can_frame put for
  * transmission into the hardware, but not yet ACKed by the CAN tx
  * complete IRQ.
  *
- * We iterate from priv->tx_echo to priv->tx_next and check if the
+ * We iterate from priv->tx_tail to priv->tx_head and check if the
  * packet has been transmitted, echo it back to the CAN framework. If
  * we discover a not yet transmitted package, stop looking for more.
  *
@@ -866,8 +866,8 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr)
 
 	/* masking of reg_sr not needed, already done by at91_irq */
 
-	for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) {
-		mb = get_tx_echo_mb(priv);
+	for (/* nix */; (priv->tx_head - priv->tx_tail) > 0; priv->tx_tail++) {
+		mb = get_tx_tail_mb(priv);
 
 		/* no event in mailbox? */
 		if (!(reg_sr & (1 << mb)))
@@ -896,8 +896,8 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr)
 	 * we get a TX int for the last can frame directly before a
 	 * wrap around.
 	 */
-	if ((priv->tx_next & get_next_mask(priv)) != 0 ||
-	    (priv->tx_echo & get_next_mask(priv)) == 0)
+	if ((priv->tx_head & get_head_mask(priv)) != 0 ||
+	    (priv->tx_tail & get_head_mask(priv)) == 0)
 		netif_wake_queue(dev);
 }
 
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 23/37] can: at91_can: at91_set_bittiming(): demote register output to debug level
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (21 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 22/37] can: at91_can: rename struct at91_priv::{tx_next,tx_echo} to {tx_head,tx_tail} Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:57 ` [PATCH net-next 24/37] can: at91_can: at91_chip_start(): don't disable IRQs twice Marc Kleine-Budde
                   ` (13 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

This message isn't really helpful for the general reader of the kernel
logs, so should not be printed with info level.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-13-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 092652fd7352..f92d8a75d1b1 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -393,7 +393,7 @@ static int at91_set_bittiming(struct net_device *dev)
 		FIELD_PREP(AT91_BR_PHASE1_MASK, bt->phase_seg1 - 1) |
 		FIELD_PREP(AT91_BR_PHASE2_MASK, bt->phase_seg2 - 1);
 
-	netdev_info(dev, "writing AT91_BR: 0x%08x\n", reg_br);
+	netdev_dbg(dev, "writing AT91_BR: 0x%08x\n", reg_br);
 
 	at91_write(priv, AT91_BR, reg_br);
 
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 24/37] can: at91_can: at91_chip_start(): don't disable IRQs twice
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (22 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 23/37] can: at91_can: at91_set_bittiming(): demote register output to debug level Marc Kleine-Budde
@ 2023-10-05 19:57 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 25/37] can: at91_can: at91_open(): forward request_irq()'s return value in case or an error Marc Kleine-Budde
                   ` (12 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:57 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

In at91_chip_start() first all IRQs are disabled, they do not have to
be disabled again at the end of the function before the requested IRQs
are enabled.

Remove the 2nd disable of all IRQs at the end of the function.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-14-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index f92d8a75d1b1..3f3c6f2107a8 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -438,7 +438,6 @@ static void at91_chip_start(struct net_device *dev)
 
 	/* Enable interrupts */
 	reg_ier = get_irq_mb_rx(priv) | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME;
-	at91_write(priv, AT91_IDR, AT91_IRQ_ALL);
 	at91_write(priv, AT91_IER, reg_ier);
 }
 
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 25/37] can: at91_can: at91_open(): forward request_irq()'s return value in case or an error
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (23 preceding siblings ...)
  2023-10-05 19:57 ` [PATCH net-next 24/37] can: at91_can: at91_chip_start(): don't disable IRQs twice Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 26/37] can: at91_can: add CAN transceiver support Marc Kleine-Budde
                   ` (11 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

If request_irq() fails, forward the return value.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-15-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 3f3c6f2107a8..bfe414581fa1 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -1128,11 +1128,10 @@ static int at91_open(struct net_device *dev)
 		goto out;
 
 	/* register interrupt handler */
-	if (request_irq(dev->irq, at91_irq, IRQF_SHARED,
-			dev->name, dev)) {
-		err = -EAGAIN;
+	err = request_irq(dev->irq, at91_irq, IRQF_SHARED,
+			  dev->name, dev);
+	if (err)
 		goto out_close;
-	}
 
 	/* start chip and queuing */
 	at91_chip_start(dev);
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 26/37] can: at91_can: add CAN transceiver support
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (24 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 25/37] can: at91_can: at91_open(): forward request_irq()'s return value in case or an error Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 27/37] can: at91_can: at91_poll_err(): fold in at91_poll_err_frame() Marc Kleine-Budde
                   ` (10 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Add support for Linux-PHY based CAN transceivers.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-16-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index bfe414581fa1..94e9740c80de 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/of.h>
+#include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
@@ -150,6 +151,7 @@ struct at91_devtype_data {
 struct at91_priv {
 	struct can_priv can;		/* must be the first member! */
 	struct napi_struct napi;
+	struct phy *transceiver;
 
 	void __iomem *reg_base;
 
@@ -1118,20 +1120,24 @@ static int at91_open(struct net_device *dev)
 	struct at91_priv *priv = netdev_priv(dev);
 	int err;
 
-	err = clk_prepare_enable(priv->clk);
+	err = phy_power_on(priv->transceiver);
 	if (err)
 		return err;
 
 	/* check or determine and set bittime */
 	err = open_candev(dev);
 	if (err)
-		goto out;
+		goto out_phy_power_off;
+
+	err = clk_prepare_enable(priv->clk);
+	if (err)
+		goto out_close_candev;
 
 	/* register interrupt handler */
 	err = request_irq(dev->irq, at91_irq, IRQF_SHARED,
 			  dev->name, dev);
 	if (err)
-		goto out_close;
+		goto out_clock_disable_unprepare;
 
 	/* start chip and queuing */
 	at91_chip_start(dev);
@@ -1140,10 +1146,12 @@ static int at91_open(struct net_device *dev)
 
 	return 0;
 
- out_close:
-	close_candev(dev);
- out:
+ out_clock_disable_unprepare:
 	clk_disable_unprepare(priv->clk);
+ out_close_candev:
+	close_candev(dev);
+ out_phy_power_off:
+	phy_power_off(priv->transceiver);
 
 	return err;
 }
@@ -1160,6 +1168,7 @@ static int at91_close(struct net_device *dev)
 
 	free_irq(dev->irq, dev);
 	clk_disable_unprepare(priv->clk);
+	phy_power_off(priv->transceiver);
 
 	close_candev(dev);
 
@@ -1284,6 +1293,7 @@ static const struct at91_devtype_data *at91_can_get_driver_data(struct platform_
 static int at91_can_probe(struct platform_device *pdev)
 {
 	const struct at91_devtype_data *devtype_data;
+	struct phy *transceiver;
 	struct net_device *dev;
 	struct at91_priv *priv;
 	struct resource *res;
@@ -1332,6 +1342,13 @@ static int at91_can_probe(struct platform_device *pdev)
 		goto exit_iounmap;
 	}
 
+	transceiver = devm_phy_optional_get(&pdev->dev, NULL);
+	if (IS_ERR(transceiver)) {
+		err = PTR_ERR(transceiver);
+		dev_err_probe(&pdev->dev, err, "failed to get phy\n");
+		goto exit_iounmap;
+	}
+
 	dev->netdev_ops	= &at91_netdev_ops;
 	dev->ethtool_ops = &at91_ethtool_ops;
 	dev->irq = irq;
@@ -1352,6 +1369,9 @@ static int at91_can_probe(struct platform_device *pdev)
 
 	netif_napi_add_weight(dev, &priv->napi, at91_poll, get_mb_rx_num(priv));
 
+	if (transceiver)
+		priv->can.bitrate_max = transceiver->attrs.max_link_rate;
+
 	if (at91_is_sam9263(priv))
 		dev->sysfs_groups[0] = &at91_sysfs_attr_group;
 
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 27/37] can: at91_can: at91_poll_err(): fold in at91_poll_err_frame()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (25 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 26/37] can: at91_can: add CAN transceiver support Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 28/37] can: at91_can: at91_poll_err(): increase stats even if no quota left or OOM Marc Kleine-Budde
                   ` (9 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

This is a preparation patch for the cleanup of at91_poll_err(). Fold
at91_poll_err_frame() into at91_poll_err() so that it can be easier
modified.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-17-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 27 ++++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 94e9740c80de..2071011ee812 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -751,10 +751,18 @@ static int at91_poll_rx(struct net_device *dev, int quota)
 	return received;
 }
 
-static void at91_poll_err_frame(struct net_device *dev,
-				struct can_frame *cf, u32 reg_sr)
+static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
 {
 	struct at91_priv *priv = netdev_priv(dev);
+	struct sk_buff *skb;
+	struct can_frame *cf;
+
+	if (quota == 0)
+		return 0;
+
+	skb = alloc_can_err_skb(dev, &cf);
+	if (unlikely(!skb))
+		return 0;
 
 	/* CRC error */
 	if (reg_sr & AT91_IRQ_CERR) {
@@ -797,21 +805,6 @@ static void at91_poll_err_frame(struct net_device *dev,
 		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 		cf->data[2] |= CAN_ERR_PROT_BIT;
 	}
-}
-
-static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
-{
-	struct sk_buff *skb;
-	struct can_frame *cf;
-
-	if (quota == 0)
-		return 0;
-
-	skb = alloc_can_err_skb(dev, &cf);
-	if (unlikely(!skb))
-		return 0;
-
-	at91_poll_err_frame(dev, cf, reg_sr);
 
 	netif_receive_skb(skb);
 
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 28/37] can: at91_can: at91_poll_err(): increase stats even if no quota left or OOM
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (26 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 27/37] can: at91_can: at91_poll_err(): fold in at91_poll_err_frame() Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 29/37] can: at91_can: at91_irq_err_frame(): call directly from IRQ handler Marc Kleine-Budde
                   ` (8 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

at91_poll_err() allocates a can error SKB, to inform the user space
about the CAN error. Then it fills the SKB with information the error
information and increases the net device error stats.

In case no SBK can be allocated (e.g. due to an OOM) or the NAPI quota
is 0 the function is left early and no stats are updated. This is not
helpful to the user, as there is no information about the faulty CAN
bus.

Increase the error stats even if no quota is left or no SKB can be
allocated.

While there treat No-Acknowledgment as a bus error, too.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-18-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 71 ++++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 33 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 2071011ee812..5b611657b41f 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -753,59 +753,64 @@ static int at91_poll_rx(struct net_device *dev, int quota)
 
 static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
 {
+	struct net_device_stats *stats = &dev->stats;
 	struct at91_priv *priv = netdev_priv(dev);
 	struct sk_buff *skb;
-	struct can_frame *cf;
+	struct can_frame *cf = NULL;
 
-	if (quota == 0)
-		return 0;
+	priv->can.can_stats.bus_error++;
 
-	skb = alloc_can_err_skb(dev, &cf);
-	if (unlikely(!skb))
-		return 0;
+	if (quota) {
+		skb = alloc_can_err_skb(dev, &cf);
+		if (cf)
+			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+	}
 
-	/* CRC error */
 	if (reg_sr & AT91_IRQ_CERR) {
-		netdev_dbg(dev, "CERR irq\n");
-		dev->stats.rx_errors++;
-		priv->can.can_stats.bus_error++;
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+		netdev_dbg(dev, "CRC error\n");
+
+		stats->rx_errors++;
+		if (cf)
+			cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
 	}
 
-	/* Stuffing Error */
 	if (reg_sr & AT91_IRQ_SERR) {
-		netdev_dbg(dev, "SERR irq\n");
-		dev->stats.rx_errors++;
-		priv->can.can_stats.bus_error++;
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-		cf->data[2] |= CAN_ERR_PROT_STUFF;
+		netdev_dbg(dev, "Stuff error\n");
+
+		stats->rx_errors++;
+		if (cf)
+			cf->data[2] |= CAN_ERR_PROT_STUFF;
 	}
 
-	/* Acknowledgement Error */
 	if (reg_sr & AT91_IRQ_AERR) {
-		netdev_dbg(dev, "AERR irq\n");
-		dev->stats.tx_errors++;
-		cf->can_id |= CAN_ERR_ACK;
+		netdev_dbg(dev, "NACK error\n");
+
+		stats->tx_errors++;
+		if (cf) {
+			cf->can_id |= CAN_ERR_ACK;
+			cf->data[2] |= CAN_ERR_PROT_TX;
+		}
 	}
 
-	/* Form error */
 	if (reg_sr & AT91_IRQ_FERR) {
-		netdev_dbg(dev, "FERR irq\n");
-		dev->stats.rx_errors++;
-		priv->can.can_stats.bus_error++;
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-		cf->data[2] |= CAN_ERR_PROT_FORM;
+		netdev_dbg(dev, "Format error\n");
+
+		stats->rx_errors++;
+		if (cf)
+			cf->data[2] |= CAN_ERR_PROT_FORM;
 	}
 
-	/* Bit Error */
 	if (reg_sr & AT91_IRQ_BERR) {
-		netdev_dbg(dev, "BERR irq\n");
-		dev->stats.tx_errors++;
-		priv->can.can_stats.bus_error++;
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-		cf->data[2] |= CAN_ERR_PROT_BIT;
+		netdev_dbg(dev, "Bit error\n");
+
+		stats->tx_errors++;
+		if (cf)
+			cf->data[2] |= CAN_ERR_PROT_TX | CAN_ERR_PROT_BIT;
 	}
 
+	if (!cf)
+		return 0;
+
 	netif_receive_skb(skb);
 
 	return 1;
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 29/37] can: at91_can: at91_irq_err_frame(): call directly from IRQ handler
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (27 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 28/37] can: at91_can: at91_poll_err(): increase stats even if no quota left or OOM Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 30/37] can: at91_can: at91_irq_err_frame(): move next to at91_irq_err() Marc Kleine-Budde
                   ` (7 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

This is a preparation patch to convert the driver to the rx-offload
helper. In rx-offload RX, TX-done and CAN error handling are done in
the IRQ handler, SKB are pushed to the network stack in the NAPI poll
function.

Move the CAN frame error handling from the NAPI function at91_poll()
to the IRQ handler at91_poll(). To reflect this change, rename
at91_poll_err() to at91_irq_err_frame().

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-19-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 36 ++++++++++++------------------------
 1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 5b611657b41f..a84da1995816 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -155,7 +155,6 @@ struct at91_priv {
 
 	void __iomem *reg_base;
 
-	u32 reg_sr;
 	unsigned int tx_head;
 	unsigned int tx_tail;
 	unsigned int rx_next;
@@ -751,7 +750,7 @@ static int at91_poll_rx(struct net_device *dev, int quota)
 	return received;
 }
 
-static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
+static void at91_irq_err_frame(struct net_device *dev, const u32 reg_sr)
 {
 	struct net_device_stats *stats = &dev->stats;
 	struct at91_priv *priv = netdev_priv(dev);
@@ -760,11 +759,9 @@ static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
 
 	priv->can.can_stats.bus_error++;
 
-	if (quota) {
-		skb = alloc_can_err_skb(dev, &cf);
-		if (cf)
-			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-	}
+	skb = alloc_can_err_skb(dev, &cf);
+	if (cf)
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
 	if (reg_sr & AT91_IRQ_CERR) {
 		netdev_dbg(dev, "CRC error\n");
@@ -809,11 +806,9 @@ static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
 	}
 
 	if (!cf)
-		return 0;
+		return;
 
 	netif_receive_skb(skb);
-
-	return 1;
 }
 
 static int at91_poll(struct napi_struct *napi, int quota)
@@ -826,13 +821,6 @@ static int at91_poll(struct napi_struct *napi, int quota)
 	if (reg_sr & get_irq_mb_rx(priv))
 		work_done += at91_poll_rx(dev, quota - work_done);
 
-	/* The error bits are clear on read,
-	 * so use saved value from irq handler.
-	 */
-	reg_sr |= priv->reg_sr;
-	if (reg_sr & AT91_IRQ_ERR_FRAME)
-		work_done += at91_poll_err(dev, quota - work_done, reg_sr);
-
 	if (work_done < quota) {
 		/* enable IRQs for frame errors and all mailboxes >= rx_next */
 		u32 reg_ier = AT91_IRQ_ERR_FRAME;
@@ -1092,14 +1080,10 @@ static irqreturn_t at91_irq(int irq, void *dev_id)
 
 	handled = IRQ_HANDLED;
 
-	/* Receive or error interrupt? -> napi */
-	if (reg_sr & (get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME)) {
-		/* The error bits are clear on read,
-		 * save for later use.
-		 */
-		priv->reg_sr = reg_sr;
+	/* Receive interrupt? -> napi */
+	if (reg_sr & get_irq_mb_rx(priv)) {
 		at91_write(priv, AT91_IDR,
-			   get_irq_mb_rx(priv) | AT91_IRQ_ERR_FRAME);
+			   get_irq_mb_rx(priv));
 		napi_schedule(&priv->napi);
 	}
 
@@ -1109,6 +1093,10 @@ static irqreturn_t at91_irq(int irq, void *dev_id)
 
 	at91_irq_err(dev);
 
+	/* Frame Error Interrupt */
+	if (reg_sr & AT91_IRQ_ERR_FRAME)
+		at91_irq_err_frame(dev, reg_sr);
+
  exit:
 	return handled;
 }
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 30/37] can: at91_can: at91_irq_err_frame(): move next to at91_irq_err()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (28 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 29/37] can: at91_can: at91_irq_err_frame(): call directly from IRQ handler Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 31/37] can: at91_can: at91_irq_err(): rename to at91_irq_err_line() Marc Kleine-Budde
                   ` (6 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

This is a cleanup patch, no functional change intended. As
at91_irq_err_frame() is called from the IRQ handler move it in front
of the IRQ handler next to at91_irq_err().

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-20-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 122 ++++++++++++++++++-------------------
 1 file changed, 61 insertions(+), 61 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index a84da1995816..6b017fd695c0 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -750,67 +750,6 @@ static int at91_poll_rx(struct net_device *dev, int quota)
 	return received;
 }
 
-static void at91_irq_err_frame(struct net_device *dev, const u32 reg_sr)
-{
-	struct net_device_stats *stats = &dev->stats;
-	struct at91_priv *priv = netdev_priv(dev);
-	struct sk_buff *skb;
-	struct can_frame *cf = NULL;
-
-	priv->can.can_stats.bus_error++;
-
-	skb = alloc_can_err_skb(dev, &cf);
-	if (cf)
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-
-	if (reg_sr & AT91_IRQ_CERR) {
-		netdev_dbg(dev, "CRC error\n");
-
-		stats->rx_errors++;
-		if (cf)
-			cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
-	}
-
-	if (reg_sr & AT91_IRQ_SERR) {
-		netdev_dbg(dev, "Stuff error\n");
-
-		stats->rx_errors++;
-		if (cf)
-			cf->data[2] |= CAN_ERR_PROT_STUFF;
-	}
-
-	if (reg_sr & AT91_IRQ_AERR) {
-		netdev_dbg(dev, "NACK error\n");
-
-		stats->tx_errors++;
-		if (cf) {
-			cf->can_id |= CAN_ERR_ACK;
-			cf->data[2] |= CAN_ERR_PROT_TX;
-		}
-	}
-
-	if (reg_sr & AT91_IRQ_FERR) {
-		netdev_dbg(dev, "Format error\n");
-
-		stats->rx_errors++;
-		if (cf)
-			cf->data[2] |= CAN_ERR_PROT_FORM;
-	}
-
-	if (reg_sr & AT91_IRQ_BERR) {
-		netdev_dbg(dev, "Bit error\n");
-
-		stats->tx_errors++;
-		if (cf)
-			cf->data[2] |= CAN_ERR_PROT_TX | CAN_ERR_PROT_BIT;
-	}
-
-	if (!cf)
-		return;
-
-	netif_receive_skb(skb);
-}
-
 static int at91_poll(struct napi_struct *napi, int quota)
 {
 	struct net_device *dev = napi->dev;
@@ -1061,6 +1000,67 @@ static void at91_irq_err(struct net_device *dev)
 	priv->can.state = new_state;
 }
 
+static void at91_irq_err_frame(struct net_device *dev, const u32 reg_sr)
+{
+	struct net_device_stats *stats = &dev->stats;
+	struct at91_priv *priv = netdev_priv(dev);
+	struct sk_buff *skb;
+	struct can_frame *cf = NULL;
+
+	priv->can.can_stats.bus_error++;
+
+	skb = alloc_can_err_skb(dev, &cf);
+	if (cf)
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+	if (reg_sr & AT91_IRQ_CERR) {
+		netdev_dbg(dev, "CRC error\n");
+
+		stats->rx_errors++;
+		if (cf)
+			cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+	}
+
+	if (reg_sr & AT91_IRQ_SERR) {
+		netdev_dbg(dev, "Stuff error\n");
+
+		stats->rx_errors++;
+		if (cf)
+			cf->data[2] |= CAN_ERR_PROT_STUFF;
+	}
+
+	if (reg_sr & AT91_IRQ_AERR) {
+		netdev_dbg(dev, "NACK error\n");
+
+		stats->tx_errors++;
+		if (cf) {
+			cf->can_id |= CAN_ERR_ACK;
+			cf->data[2] |= CAN_ERR_PROT_TX;
+		}
+	}
+
+	if (reg_sr & AT91_IRQ_FERR) {
+		netdev_dbg(dev, "Format error\n");
+
+		stats->rx_errors++;
+		if (cf)
+			cf->data[2] |= CAN_ERR_PROT_FORM;
+	}
+
+	if (reg_sr & AT91_IRQ_BERR) {
+		netdev_dbg(dev, "Bit error\n");
+
+		stats->tx_errors++;
+		if (cf)
+			cf->data[2] |= CAN_ERR_PROT_TX | CAN_ERR_PROT_BIT;
+	}
+
+	if (!cf)
+		return;
+
+	netif_receive_skb(skb);
+}
+
 /* interrupt handler
  */
 static irqreturn_t at91_irq(int irq, void *dev_id)
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 31/37] can: at91_can: at91_irq_err(): rename to at91_irq_err_line()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (29 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 30/37] can: at91_can: at91_irq_err_frame(): move next to at91_irq_err() Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 32/37] can: at91_can: at91_irq_err_line(): make use of can_state_get_by_berr_counter() Marc Kleine-Budde
                   ` (5 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

This is a cleanup patch, no functional change intended.

The function at91_irq_err() only handles the CAN line errors, so
rename it accordingly to at91_irq_err_line().

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-21-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 6b017fd695c0..4249a1c95769 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -954,7 +954,7 @@ static int at91_get_state_by_bec(const struct net_device *dev,
 	return 0;
 }
 
-static void at91_irq_err(struct net_device *dev)
+static void at91_irq_err_line(struct net_device *dev)
 {
 	struct at91_priv *priv = netdev_priv(dev);
 	struct sk_buff *skb;
@@ -1091,7 +1091,7 @@ static irqreturn_t at91_irq(int irq, void *dev_id)
 	if (reg_sr & get_irq_mb_tx(priv))
 		at91_irq_tx(dev, reg_sr);
 
-	at91_irq_err(dev);
+	at91_irq_err_line(dev);
 
 	/* Frame Error Interrupt */
 	if (reg_sr & AT91_IRQ_ERR_FRAME)
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 32/37] can: at91_can: at91_irq_err_line(): make use of can_state_get_by_berr_counter()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (30 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 31/37] can: at91_can: at91_irq_err(): rename to at91_irq_err_line() Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 33/37] can: at91_can: at91_irq_err_line(): take reg_sr into account for bus off Marc Kleine-Budde
                   ` (4 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

On the sam9263 the SR bits for bus off, error passive, warning limit,
and error active are not latched and reflect the current status of the
controller. On the sam9x5 and newer SoCs these bits are latched.

To simplify the code, use can_state_get_by_berr_counter() to get the
state of the controller regardless of the SoC version.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-22-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 51 ++++----------------------------------
 1 file changed, 5 insertions(+), 46 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 4249a1c95769..68b611d0fa6c 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -932,58 +932,17 @@ static void at91_irq_err_state(struct net_device *dev,
 	at91_write(priv, AT91_IER, reg_ier);
 }
 
-static int at91_get_state_by_bec(const struct net_device *dev,
-				 enum can_state *state)
-{
-	struct can_berr_counter bec;
-	int err;
-
-	err = at91_get_berr_counter(dev, &bec);
-	if (err)
-		return err;
-
-	if (bec.txerr < 96 && bec.rxerr < 96)
-		*state = CAN_STATE_ERROR_ACTIVE;
-	else if (bec.txerr < 128 && bec.rxerr < 128)
-		*state = CAN_STATE_ERROR_WARNING;
-	else if (bec.txerr < 256 && bec.rxerr < 256)
-		*state = CAN_STATE_ERROR_PASSIVE;
-	else
-		*state = CAN_STATE_BUS_OFF;
-
-	return 0;
-}
-
 static void at91_irq_err_line(struct net_device *dev)
 {
+	enum can_state new_state, rx_state, tx_state;
 	struct at91_priv *priv = netdev_priv(dev);
+	struct can_berr_counter bec;
 	struct sk_buff *skb;
 	struct can_frame *cf;
-	enum can_state new_state;
-	u32 reg_sr;
-	int err;
 
-	if (at91_is_sam9263(priv)) {
-		reg_sr = at91_read(priv, AT91_SR);
-
-		/* we need to look at the unmasked reg_sr */
-		if (unlikely(reg_sr & AT91_IRQ_BOFF)) {
-			new_state = CAN_STATE_BUS_OFF;
-		} else if (unlikely(reg_sr & AT91_IRQ_ERRP)) {
-			new_state = CAN_STATE_ERROR_PASSIVE;
-		} else if (unlikely(reg_sr & AT91_IRQ_WARN)) {
-			new_state = CAN_STATE_ERROR_WARNING;
-		} else if (likely(reg_sr & AT91_IRQ_ERRA)) {
-			new_state = CAN_STATE_ERROR_ACTIVE;
-		} else {
-			netdev_err(dev, "BUG! hardware in undefined state\n");
-			return;
-		}
-	} else {
-		err = at91_get_state_by_bec(dev, &new_state);
-		if (err)
-			return;
-	}
+	at91_get_berr_counter(dev, &bec);
+	can_state_get_by_berr_counter(dev, &bec, &tx_state, &rx_state);
+	new_state = max(tx_state, rx_state);
 
 	/* state hasn't changed */
 	if (likely(new_state == priv->can.state))
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 33/37] can: at91_can: at91_irq_err_line(): take reg_sr into account for bus off
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (31 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 32/37] can: at91_can: at91_irq_err_line(): make use of can_state_get_by_berr_counter() Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 34/37] can: at91_can: at91_irq_err_line(): make use of can_change_state() and can_bus_off() Marc Kleine-Budde
                   ` (3 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

The at91 CAN controller automatically recovers from bus-off after 128
occurrences of 11 consecutive recessive bits.

After an auto-recovered bus-off, the error counters no longer reflect
this fact. On the sam9263 the state bits in the SR register show the
current state (based on the current error counters), while on sam9x5
and newer SoCs these bits are latched.

Take any latched bus-off information from the SR register into account
when calculating the CAN new state, to start the standard CAN bus off
handling.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-23-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 68b611d0fa6c..fbe58a1a1989 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -437,6 +437,11 @@ static void at91_chip_start(struct net_device *dev)
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
+	/* Dummy read to clear latched line error interrupts on
+	 * sam9x5 and newer SoCs.
+	 */
+	at91_read(priv, AT91_SR);
+
 	/* Enable interrupts */
 	reg_ier = get_irq_mb_rx(priv) | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME;
 	at91_write(priv, AT91_IER, reg_ier);
@@ -932,7 +937,7 @@ static void at91_irq_err_state(struct net_device *dev,
 	at91_write(priv, AT91_IER, reg_ier);
 }
 
-static void at91_irq_err_line(struct net_device *dev)
+static void at91_irq_err_line(struct net_device *dev, const u32 reg_sr)
 {
 	enum can_state new_state, rx_state, tx_state;
 	struct at91_priv *priv = netdev_priv(dev);
@@ -942,6 +947,23 @@ static void at91_irq_err_line(struct net_device *dev)
 
 	at91_get_berr_counter(dev, &bec);
 	can_state_get_by_berr_counter(dev, &bec, &tx_state, &rx_state);
+
+	/* The chip automatically recovers from bus-off after 128
+	 * occurrences of 11 consecutive recessive bits.
+	 *
+	 * After an auto-recovered bus-off, the error counters no
+	 * longer reflect this fact. On the sam9263 the state bits in
+	 * the SR register show the current state (based on the
+	 * current error counters), while on sam9x5 and newer SoCs
+	 * these bits are latched.
+	 *
+	 * Take any latched bus-off information from the SR register
+	 * into account when calculating the CAN new state, to start
+	 * the standard CAN bus off handling.
+	 */
+	if (reg_sr & AT91_IRQ_BOFF)
+		rx_state = CAN_STATE_BUS_OFF;
+
 	new_state = max(tx_state, rx_state);
 
 	/* state hasn't changed */
@@ -1050,7 +1072,7 @@ static irqreturn_t at91_irq(int irq, void *dev_id)
 	if (reg_sr & get_irq_mb_tx(priv))
 		at91_irq_tx(dev, reg_sr);
 
-	at91_irq_err_line(dev);
+	at91_irq_err_line(dev, reg_sr);
 
 	/* Frame Error Interrupt */
 	if (reg_sr & AT91_IRQ_ERR_FRAME)
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 34/37] can: at91_can: at91_irq_err_line(): make use of can_change_state() and can_bus_off()
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (32 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 33/37] can: at91_can: at91_irq_err_line(): take reg_sr into account for bus off Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 35/37] can: at91_can: at91_irq_err_line(): send error counters with state change Marc Kleine-Budde
                   ` (2 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

The driver implements a hand crafted CAN state handling. Update the
driver to make use of can_change_state(), introduced in ("can: dev:
Consolidate and unify state change handling")

Also switch from hand crafted CAN bus off handling to can_bus_off():
In case of a bus off, abort all pending TX requests, switch off the
device and let can_bus_off() handle the device restart.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-24-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 131 ++++++-------------------------------
 1 file changed, 21 insertions(+), 110 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index fbe58a1a1989..a413589109b2 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -443,7 +443,7 @@ static void at91_chip_start(struct net_device *dev)
 	at91_read(priv, AT91_SR);
 
 	/* Enable interrupts */
-	reg_ier = get_irq_mb_rx(priv) | AT91_IRQ_ERRP | AT91_IRQ_ERR_FRAME;
+	reg_ier = get_irq_mb_rx(priv) | AT91_IRQ_ERR_LINE | AT91_IRQ_ERR_FRAME;
 	at91_write(priv, AT91_IER, reg_ier);
 }
 
@@ -452,6 +452,11 @@ static void at91_chip_stop(struct net_device *dev, enum can_state state)
 	struct at91_priv *priv = netdev_priv(dev);
 	u32 reg_mr;
 
+	/* Abort any pending TX requests. However this doesn't seem to
+	 * work in case of bus-off on sama5d3.
+	 */
+	at91_write(priv, AT91_ACR, get_irq_mb_tx(priv));
+
 	/* disable interrupts */
 	at91_write(priv, AT91_IDR, AT91_IRQ_ALL);
 
@@ -832,111 +837,6 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr)
 		netif_wake_queue(dev);
 }
 
-static void at91_irq_err_state(struct net_device *dev,
-			       struct can_frame *cf, enum can_state new_state)
-{
-	struct at91_priv *priv = netdev_priv(dev);
-	u32 reg_idr = 0, reg_ier = 0;
-	struct can_berr_counter bec;
-
-	at91_get_berr_counter(dev, &bec);
-
-	switch (priv->can.state) {
-	case CAN_STATE_ERROR_ACTIVE:
-		/* from: ERROR_ACTIVE
-		 * to  : ERROR_WARNING, ERROR_PASSIVE, BUS_OFF
-		 * =>  : there was a warning int
-		 */
-		if (new_state >= CAN_STATE_ERROR_WARNING &&
-		    new_state <= CAN_STATE_BUS_OFF) {
-			netdev_dbg(dev, "Error Warning IRQ\n");
-			priv->can.can_stats.error_warning++;
-
-			cf->can_id |= CAN_ERR_CRTL;
-			cf->data[1] = (bec.txerr > bec.rxerr) ?
-				CAN_ERR_CRTL_TX_WARNING :
-				CAN_ERR_CRTL_RX_WARNING;
-		}
-		fallthrough;
-	case CAN_STATE_ERROR_WARNING:
-		/* from: ERROR_ACTIVE, ERROR_WARNING
-		 * to  : ERROR_PASSIVE, BUS_OFF
-		 * =>  : error passive int
-		 */
-		if (new_state >= CAN_STATE_ERROR_PASSIVE &&
-		    new_state <= CAN_STATE_BUS_OFF) {
-			netdev_dbg(dev, "Error Passive IRQ\n");
-			priv->can.can_stats.error_passive++;
-
-			cf->can_id |= CAN_ERR_CRTL;
-			cf->data[1] = (bec.txerr > bec.rxerr) ?
-				CAN_ERR_CRTL_TX_PASSIVE :
-				CAN_ERR_CRTL_RX_PASSIVE;
-		}
-		break;
-	case CAN_STATE_BUS_OFF:
-		/* from: BUS_OFF
-		 * to  : ERROR_ACTIVE, ERROR_WARNING, ERROR_PASSIVE
-		 */
-		if (new_state <= CAN_STATE_ERROR_PASSIVE) {
-			cf->can_id |= CAN_ERR_RESTARTED;
-
-			netdev_dbg(dev, "restarted\n");
-			priv->can.can_stats.restarts++;
-
-			netif_carrier_on(dev);
-			netif_wake_queue(dev);
-		}
-		break;
-	default:
-		break;
-	}
-
-	/* process state changes depending on the new state */
-	switch (new_state) {
-	case CAN_STATE_ERROR_ACTIVE:
-		/* actually we want to enable AT91_IRQ_WARN here, but
-		 * it screws up the system under certain
-		 * circumstances. so just enable AT91_IRQ_ERRP, thus
-		 * the "fallthrough"
-		 */
-		netdev_dbg(dev, "Error Active\n");
-		cf->can_id |= CAN_ERR_PROT;
-		cf->data[2] = CAN_ERR_PROT_ACTIVE;
-		fallthrough;
-	case CAN_STATE_ERROR_WARNING:
-		reg_idr = AT91_IRQ_ERRA | AT91_IRQ_WARN | AT91_IRQ_BOFF;
-		reg_ier = AT91_IRQ_ERRP;
-		break;
-	case CAN_STATE_ERROR_PASSIVE:
-		reg_idr = AT91_IRQ_ERRA | AT91_IRQ_WARN | AT91_IRQ_ERRP;
-		reg_ier = AT91_IRQ_BOFF;
-		break;
-	case CAN_STATE_BUS_OFF:
-		reg_idr = AT91_IRQ_ERRA | AT91_IRQ_ERRP |
-			AT91_IRQ_WARN | AT91_IRQ_BOFF;
-		reg_ier = 0;
-
-		cf->can_id |= CAN_ERR_BUSOFF;
-
-		netdev_dbg(dev, "bus-off\n");
-		netif_carrier_off(dev);
-		priv->can.can_stats.bus_off++;
-
-		/* turn off chip, if restart is disabled */
-		if (!priv->can.restart_ms) {
-			at91_chip_stop(dev, CAN_STATE_BUS_OFF);
-			return;
-		}
-		break;
-	default:
-		break;
-	}
-
-	at91_write(priv, AT91_IDR, reg_idr);
-	at91_write(priv, AT91_IER, reg_ier);
-}
-
 static void at91_irq_err_line(struct net_device *dev, const u32 reg_sr)
 {
 	enum can_state new_state, rx_state, tx_state;
@@ -970,15 +870,22 @@ static void at91_irq_err_line(struct net_device *dev, const u32 reg_sr)
 	if (likely(new_state == priv->can.state))
 		return;
 
+	/* The skb allocation might fail, but can_change_state()
+	 * handles cf == NULL.
+	 */
 	skb = alloc_can_err_skb(dev, &cf);
+	can_change_state(dev, cf, tx_state, rx_state);
+
+	if (new_state == CAN_STATE_BUS_OFF) {
+		at91_chip_stop(dev, CAN_STATE_BUS_OFF);
+		can_bus_off(dev);
+	}
+
 	if (unlikely(!skb))
 		return;
 
-	at91_irq_err_state(dev, cf, new_state);
 
 	netif_rx(skb);
-
-	priv->can.state = new_state;
 }
 
 static void at91_irq_err_frame(struct net_device *dev, const u32 reg_sr)
@@ -1072,7 +979,11 @@ static irqreturn_t at91_irq(int irq, void *dev_id)
 	if (reg_sr & get_irq_mb_tx(priv))
 		at91_irq_tx(dev, reg_sr);
 
-	at91_irq_err_line(dev, reg_sr);
+	/* Line Error interrupt */
+	if (reg_sr & AT91_IRQ_ERR_LINE ||
+	    priv->can.state > CAN_STATE_ERROR_ACTIVE) {
+		at91_irq_err_line(dev, reg_sr);
+	}
 
 	/* Frame Error Interrupt */
 	if (reg_sr & AT91_IRQ_ERR_FRAME)
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 35/37] can: at91_can: at91_irq_err_line(): send error counters with state change
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (33 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 34/37] can: at91_can: at91_irq_err_line(): make use of can_change_state() and can_bus_off() Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 36/37] can: at91_can: at91_alloc_can_err_skb() introduce new function Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 37/37] can: at91_can: switch to rx-offload implementation Marc Kleine-Budde
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

Since 3e5c291c7942 ("can: add CAN_ERR_CNT flag to notify availability
of error counter") there is a dedicated flag to inform the user space,
that there are CAN error counters in the CAN error frame.

In case the device is not in bus off mode, send the error counters to
user space and set CAN_ERR_CNT.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-25-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index a413589109b2..d5e1d1b2cdd1 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -884,6 +884,11 @@ static void at91_irq_err_line(struct net_device *dev, const u32 reg_sr)
 	if (unlikely(!skb))
 		return;
 
+	if (new_state != CAN_STATE_BUS_OFF) {
+		cf->can_id |= CAN_ERR_CNT;
+		cf->data[6] = bec.txerr;
+		cf->data[7] = bec.rxerr;
+	}
 
 	netif_rx(skb);
 }
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 36/37] can: at91_can: at91_alloc_can_err_skb() introduce new function
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (34 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 35/37] can: at91_can: at91_irq_err_line(): send error counters with state change Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  2023-10-05 19:58 ` [PATCH net-next 37/37] can: at91_can: switch to rx-offload implementation Marc Kleine-Budde
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

This is a preparation patch to convert the driver to make use of the
rx-offload helper. With rx-offload the received CAN frames are sorted
by their timestamp. Regular CAN RX'ed and TX'ed CAN frames are
timestamped by the hardware. Error events are not.

Introduce a new function at91_alloc_can_err_skb() the allocates an
error SKB and reads the current timestamp from the controller.

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-26-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/at91_can.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index d5e1d1b2cdd1..ca62aa027e5f 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -576,6 +576,22 @@ static inline void at91_activate_rx_mb(const struct at91_priv *priv,
 	at91_write(priv, AT91_TCR, mask);
 }
 
+static inline u32 at91_get_timestamp(const struct at91_priv *priv)
+{
+	return at91_read(priv, AT91_TIM);
+}
+
+static inline struct sk_buff *
+at91_alloc_can_err_skb(struct net_device *dev,
+		       struct can_frame **cf, u32 *timestamp)
+{
+	const struct at91_priv *priv = netdev_priv(dev);
+
+	*timestamp = at91_get_timestamp(priv);
+
+	return alloc_can_err_skb(dev, cf);
+}
+
 /**
  * at91_rx_overflow_err - send error frame due to rx overflow
  * @dev: net device
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* [PATCH net-next 37/37] can: at91_can: switch to rx-offload implementation
  2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
                   ` (35 preceding siblings ...)
  2023-10-05 19:58 ` [PATCH net-next 36/37] can: at91_can: at91_alloc_can_err_skb() introduce new function Marc Kleine-Budde
@ 2023-10-05 19:58 ` Marc Kleine-Budde
  36 siblings, 0 replies; 39+ messages in thread
From: Marc Kleine-Budde @ 2023-10-05 19:58 UTC (permalink / raw)
  To: netdev; +Cc: davem, kuba, linux-can, kernel, Marc Kleine-Budde

The current at91_can driver uses NAPI to handle RX'ed CAN frames, the
RX IRQ is disabled and a NAPI poll is scheduled. Then in
at91_poll_rx() the RX'ed CAN frames are tried to read in order from
the device.

This approach has 2 drawbacks:

- Under high system load it might take too long from the initial RX
  IRQ to the NAPI poll function to run. This causes RX buffer
  overflows.
- The algorithm to read the CAN frames in order is not bullet proof
  and may fail under certain use cases/system loads.

The rx-offload helper fixes these problems by reading the RX'ed CAN
frames in the interrupt handler and adding it to a list sorted by RX
timestamp. This list of RX'ed SKBs is then passed to the networking
stack via NAPI.

Convert the RX path to rx-offload, pass all CAN error frames with
can_rx_offload_queue_timestamp().

Link: https://lore.kernel.org/all/20231005-at91_can-rx_offload-v2-27-9987d53600e0@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/can/Kconfig    |   1 +
 drivers/net/can/at91_can.c | 340 +++++++++++--------------------------
 2 files changed, 100 insertions(+), 241 deletions(-)

diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 649453a3c858..8d6fc0852bf7 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -89,6 +89,7 @@ config CAN_RX_OFFLOAD
 config CAN_AT91
 	tristate "Atmel AT91 onchip CAN controller"
 	depends on (ARCH_AT91 || COMPILE_TEST) && HAS_IOMEM
+	select CAN_RX_OFFLOAD
 	help
 	  This is a driver for the SoC CAN controller in Atmel's AT91SAM9263
 	  and AT91SAM9X5 processors.
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index ca62aa027e5f..11f434d708b3 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -3,7 +3,7 @@
  * at91_can.c - CAN network driver for AT91 SoC CAN controller
  *
  * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de>
- * (C) 2008, 2009, 2010, 2011 by Marc Kleine-Budde <kernel@pengutronix.de>
+ * (C) 2008, 2009, 2010, 2011, 2023 by Marc Kleine-Budde <kernel@pengutronix.de>
  */
 
 #include <linux/bitfield.h>
@@ -26,6 +26,7 @@
 
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
+#include <linux/can/rx-offload.h>
 
 #define AT91_MB_MASK(i) ((1 << (i)) - 1)
 
@@ -142,7 +143,6 @@ enum at91_devtype {
 
 struct at91_devtype_data {
 	unsigned int rx_first;
-	unsigned int rx_split;
 	unsigned int rx_last;
 	unsigned int tx_shift;
 	enum at91_devtype type;
@@ -150,14 +150,13 @@ struct at91_devtype_data {
 
 struct at91_priv {
 	struct can_priv can;		/* must be the first member! */
-	struct napi_struct napi;
+	struct can_rx_offload offload;
 	struct phy *transceiver;
 
 	void __iomem *reg_base;
 
 	unsigned int tx_head;
 	unsigned int tx_tail;
-	unsigned int rx_next;
 	struct at91_devtype_data devtype_data;
 
 	struct clk *clk;
@@ -166,9 +165,13 @@ struct at91_priv {
 	canid_t mb0_id;
 };
 
+static inline struct at91_priv *rx_offload_to_priv(struct can_rx_offload *offload)
+{
+	return container_of(offload, struct at91_priv, offload);
+}
+
 static const struct at91_devtype_data at91_at91sam9263_data = {
 	.rx_first = 1,
-	.rx_split = 8,
 	.rx_last = 11,
 	.tx_shift = 2,
 	.type = AT91_DEVTYPE_SAM9263,
@@ -176,7 +179,6 @@ static const struct at91_devtype_data at91_at91sam9263_data = {
 
 static const struct at91_devtype_data at91_at91sam9x5_data = {
 	.rx_first = 0,
-	.rx_split = 4,
 	.rx_last = 5,
 	.tx_shift = 1,
 	.type = AT91_DEVTYPE_SAM9X5,
@@ -213,27 +215,6 @@ static inline unsigned int get_mb_rx_last(const struct at91_priv *priv)
 	return priv->devtype_data.rx_last;
 }
 
-static inline unsigned int get_mb_rx_split(const struct at91_priv *priv)
-{
-	return priv->devtype_data.rx_split;
-}
-
-static inline unsigned int get_mb_rx_num(const struct at91_priv *priv)
-{
-	return get_mb_rx_last(priv) - get_mb_rx_first(priv) + 1;
-}
-
-static inline unsigned int get_mb_rx_low_last(const struct at91_priv *priv)
-{
-	return get_mb_rx_split(priv) - 1;
-}
-
-static inline unsigned int get_mb_rx_low_mask(const struct at91_priv *priv)
-{
-	return AT91_MB_MASK(get_mb_rx_split(priv)) &
-		~AT91_MB_MASK(get_mb_rx_first(priv));
-}
-
 static inline unsigned int get_mb_tx_shift(const struct at91_priv *priv)
 {
 	return priv->devtype_data.tx_shift;
@@ -374,9 +355,8 @@ static void at91_setup_mailboxes(struct net_device *dev)
 	for (i = get_mb_tx_first(priv); i <= get_mb_tx_last(priv); i++)
 		set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0);
 
-	/* Reset tx and rx helper pointers */
+	/* Reset tx helper pointers */
 	priv->tx_head = priv->tx_tail = 0;
-	priv->rx_next = get_mb_rx_first(priv);
 }
 
 static int at91_set_bittiming(struct net_device *dev)
@@ -548,34 +528,6 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	return NETDEV_TX_OK;
 }
 
-/**
- * at91_activate_rx_low - activate lower rx mailboxes
- * @priv: a91 context
- *
- * Reenables the lower mailboxes for reception of new CAN messages
- */
-static inline void at91_activate_rx_low(const struct at91_priv *priv)
-{
-	u32 mask = get_mb_rx_low_mask(priv);
-
-	at91_write(priv, AT91_TCR, mask);
-}
-
-/**
- * at91_activate_rx_mb - reactive single rx mailbox
- * @priv: a91 context
- * @mb: mailbox to reactivate
- *
- * Reenables given mailbox for reception of new CAN messages
- */
-static inline void at91_activate_rx_mb(const struct at91_priv *priv,
-				       unsigned int mb)
-{
-	u32 mask = 1 << mb;
-
-	at91_write(priv, AT91_TCR, mask);
-}
-
 static inline u32 at91_get_timestamp(const struct at91_priv *priv)
 {
 	return at91_read(priv, AT91_TIM);
@@ -600,37 +552,60 @@ static void at91_rx_overflow_err(struct net_device *dev)
 {
 	struct net_device_stats *stats = &dev->stats;
 	struct sk_buff *skb;
+	struct at91_priv *priv = netdev_priv(dev);
 	struct can_frame *cf;
+	u32 timestamp;
+	int err;
 
 	netdev_dbg(dev, "RX buffer overflow\n");
 	stats->rx_over_errors++;
 	stats->rx_errors++;
 
-	skb = alloc_can_err_skb(dev, &cf);
+	skb = at91_alloc_can_err_skb(dev, &cf, &timestamp);
 	if (unlikely(!skb))
 		return;
 
 	cf->can_id |= CAN_ERR_CRTL;
 	cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
 
-	netif_receive_skb(skb);
+	err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
+	if (err)
+		stats->rx_fifo_errors++;
 }
 
 /**
- * at91_read_mb - read CAN msg from mailbox (lowlevel impl)
- * @dev: net device
+ * at91_mailbox_read - read CAN msg from mailbox
+ * @offload: rx-offload
  * @mb: mailbox number to read from
- * @cf: can frame where to store message
+ * @timestamp: pointer to 32 bit timestamp
+ * @drop: true indicated mailbox to mark as read and drop frame
  *
- * Reads a CAN message from the given mailbox and stores data into
- * given can frame. "mb" and "cf" must be valid.
+ * Reads a CAN message from the given mailbox if not empty.
  */
-static void at91_read_mb(struct net_device *dev, unsigned int mb,
-			 struct can_frame *cf)
+static struct sk_buff *at91_mailbox_read(struct can_rx_offload *offload,
+					 unsigned int mb, u32 *timestamp,
+					 bool drop)
 {
-	const struct at91_priv *priv = netdev_priv(dev);
+	const struct at91_priv *priv = rx_offload_to_priv(offload);
+	struct can_frame *cf;
+	struct sk_buff *skb;
 	u32 reg_msr, reg_mid;
 
+	reg_msr = at91_read(priv, AT91_MSR(mb));
+	if (!(reg_msr & AT91_MSR_MRDY))
+		return NULL;
+
+	if (unlikely(drop)) {
+		skb = ERR_PTR(-ENOBUFS);
+		goto mark_as_read;
+	}
+
+	skb = alloc_can_skb(offload->dev, &cf);
+	if (unlikely(!skb)) {
+		skb = ERR_PTR(-ENOMEM);
+		goto mark_as_read;
+	}
+
 	reg_mid = at91_read(priv, AT91_MID(mb));
 	if (reg_mid & AT91_MID_MIDE)
 		cf->can_id = FIELD_GET(AT91_MID_MIDVA_MASK | AT91_MID_MIDVB_MASK, reg_mid) |
@@ -638,7 +613,9 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb,
 	else
 		cf->can_id = FIELD_GET(AT91_MID_MIDVA_MASK, reg_mid);
 
-	reg_msr = at91_read(priv, AT91_MSR(mb));
+	/* extend timestamp to full 32 bit */
+	*timestamp = FIELD_GET(AT91_MSR_MTIMESTAMP_MASK, reg_msr) << 16;
+
 	cf->len = can_cc_dlc2len(FIELD_GET(AT91_MSR_MDLC_MASK, reg_msr));
 
 	if (reg_msr & AT91_MSR_MRTR) {
@@ -652,151 +629,12 @@ static void at91_read_mb(struct net_device *dev, unsigned int mb,
 	at91_write(priv, AT91_MID(mb), AT91_MID_MIDE);
 
 	if (unlikely(mb == get_mb_rx_last(priv) && reg_msr & AT91_MSR_MMI))
-		at91_rx_overflow_err(dev);
-}
+		at91_rx_overflow_err(offload->dev);
 
-/**
- * at91_read_msg - read CAN message from mailbox
- * @dev: net device
- * @mb: mail box to read from
- *
- * Reads a CAN message from given mailbox, and put into linux network
- * RX queue, does all housekeeping chores (stats, ...)
- */
-static void at91_read_msg(struct net_device *dev, unsigned int mb)
-{
-	struct net_device_stats *stats = &dev->stats;
-	struct can_frame *cf;
-	struct sk_buff *skb;
+ mark_as_read:
+	at91_write(priv, AT91_MCR(mb), AT91_MCR_MTCR);
 
-	skb = alloc_can_skb(dev, &cf);
-	if (unlikely(!skb)) {
-		stats->rx_dropped++;
-		return;
-	}
-
-	at91_read_mb(dev, mb, cf);
-
-	stats->rx_packets++;
-	if (!(cf->can_id & CAN_RTR_FLAG))
-		stats->rx_bytes += cf->len;
-
-	netif_receive_skb(skb);
-}
-
-/**
- * at91_poll_rx - read multiple CAN messages from mailboxes
- * @dev: net device
- * @quota: max number of pkgs we're allowed to receive
- *
- * Theory of Operation:
- *
- * About 3/4 of the mailboxes (get_mb_rx_first()...get_mb_rx_last())
- * on the chip are reserved for RX. We split them into 2 groups. The
- * lower group ranges from get_mb_rx_first() to get_mb_rx_low_last().
- *
- * Like it or not, but the chip always saves a received CAN message
- * into the first free mailbox it finds (starting with the
- * lowest). This makes it very difficult to read the messages in the
- * right order from the chip. This is how we work around that problem:
- *
- * The first message goes into mb nr. 1 and issues an interrupt. All
- * rx ints are disabled in the interrupt handler and a napi poll is
- * scheduled. We read the mailbox, but do _not_ re-enable the mb (to
- * receive another message).
- *
- *    lower mbxs      upper
- *     ____^______    __^__
- *    /           \  /     \
- * +-+-+-+-+-+-+-+-++-+-+-+-+
- * | |x|x|x|x|x|x|x|| | | | |
- * +-+-+-+-+-+-+-+-++-+-+-+-+
- *  0 0 0 0 0 0  0 0 0 0 1 1  \ mail
- *  0 1 2 3 4 5  6 7 8 9 0 1  / box
- *  ^
- *  |
- *   \
- *     unused, due to chip bug
- *
- * The variable priv->rx_next points to the next mailbox to read a
- * message from. As long we're in the lower mailboxes we just read the
- * mailbox but not re-enable it.
- *
- * With completion of the last of the lower mailboxes, we re-enable the
- * whole first group, but continue to look for filled mailboxes in the
- * upper mailboxes. Imagine the second group like overflow mailboxes,
- * which takes CAN messages if the lower goup is full. While in the
- * upper group we re-enable the mailbox right after reading it. Giving
- * the chip more room to store messages.
- *
- * After finishing we look again in the lower group if we've still
- * quota.
- *
- */
-static int at91_poll_rx(struct net_device *dev, int quota)
-{
-	struct at91_priv *priv = netdev_priv(dev);
-	u32 reg_sr = at91_read(priv, AT91_SR);
-	const unsigned long *addr = (unsigned long *)&reg_sr;
-	unsigned int mb;
-	int received = 0;
-
-	if (priv->rx_next > get_mb_rx_low_last(priv) &&
-	    reg_sr & get_mb_rx_low_mask(priv))
-		netdev_info(dev,
-			    "order of incoming frames cannot be guaranteed\n");
-
- again:
-	for (mb = find_next_bit(addr, get_mb_tx_first(priv), priv->rx_next);
-	     mb < get_mb_tx_first(priv) && quota > 0;
-	     reg_sr = at91_read(priv, AT91_SR),
-	     mb = find_next_bit(addr, get_mb_tx_first(priv), ++priv->rx_next)) {
-		at91_read_msg(dev, mb);
-
-		/* reactivate mailboxes */
-		if (mb == get_mb_rx_low_last(priv))
-			/* all lower mailboxed, if just finished it */
-			at91_activate_rx_low(priv);
-		else if (mb > get_mb_rx_low_last(priv))
-			/* only the mailbox we read */
-			at91_activate_rx_mb(priv, mb);
-
-		received++;
-		quota--;
-	}
-
-	/* upper group completed, look again in lower */
-	if (priv->rx_next > get_mb_rx_low_last(priv) &&
-	    mb > get_mb_rx_last(priv)) {
-		priv->rx_next = get_mb_rx_first(priv);
-		if (quota > 0)
-			goto again;
-	}
-
-	return received;
-}
-
-static int at91_poll(struct napi_struct *napi, int quota)
-{
-	struct net_device *dev = napi->dev;
-	const struct at91_priv *priv = netdev_priv(dev);
-	u32 reg_sr = at91_read(priv, AT91_SR);
-	int work_done = 0;
-
-	if (reg_sr & get_irq_mb_rx(priv))
-		work_done += at91_poll_rx(dev, quota - work_done);
-
-	if (work_done < quota) {
-		/* enable IRQs for frame errors and all mailboxes >= rx_next */
-		u32 reg_ier = AT91_IRQ_ERR_FRAME;
-
-		reg_ier |= get_irq_mb_rx(priv) & ~AT91_MB_MASK(priv->rx_next);
-
-		napi_complete_done(napi, work_done);
-		at91_write(priv, AT91_IER, reg_ier);
-	}
-
-	return work_done;
+	return skb;
 }
 
 /* theory of operation:
@@ -816,8 +654,6 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr)
 	u32 reg_msr;
 	unsigned int mb;
 
-	/* masking of reg_sr not needed, already done by at91_irq */
-
 	for (/* nix */; (priv->tx_head - priv->tx_tail) > 0; priv->tx_tail++) {
 		mb = get_tx_tail_mb(priv);
 
@@ -855,11 +691,14 @@ static void at91_irq_tx(struct net_device *dev, u32 reg_sr)
 
 static void at91_irq_err_line(struct net_device *dev, const u32 reg_sr)
 {
+	struct net_device_stats *stats = &dev->stats;
 	enum can_state new_state, rx_state, tx_state;
 	struct at91_priv *priv = netdev_priv(dev);
 	struct can_berr_counter bec;
 	struct sk_buff *skb;
 	struct can_frame *cf;
+	u32 timestamp;
+	int err;
 
 	at91_get_berr_counter(dev, &bec);
 	can_state_get_by_berr_counter(dev, &bec, &tx_state, &rx_state);
@@ -889,7 +728,7 @@ static void at91_irq_err_line(struct net_device *dev, const u32 reg_sr)
 	/* The skb allocation might fail, but can_change_state()
 	 * handles cf == NULL.
 	 */
-	skb = alloc_can_err_skb(dev, &cf);
+	skb = at91_alloc_can_err_skb(dev, &cf, &timestamp);
 	can_change_state(dev, cf, tx_state, rx_state);
 
 	if (new_state == CAN_STATE_BUS_OFF) {
@@ -906,19 +745,23 @@ static void at91_irq_err_line(struct net_device *dev, const u32 reg_sr)
 		cf->data[7] = bec.rxerr;
 	}
 
-	netif_rx(skb);
+	err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
+	if (err)
+		stats->rx_fifo_errors++;
 }
 
 static void at91_irq_err_frame(struct net_device *dev, const u32 reg_sr)
 {
 	struct net_device_stats *stats = &dev->stats;
 	struct at91_priv *priv = netdev_priv(dev);
+	struct can_frame *cf;
 	struct sk_buff *skb;
-	struct can_frame *cf = NULL;
+	u32 timestamp;
+	int err;
 
 	priv->can.can_stats.bus_error++;
 
-	skb = alloc_can_err_skb(dev, &cf);
+	skb = at91_alloc_can_err_skb(dev, &cf, &timestamp);
 	if (cf)
 		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
@@ -967,50 +810,62 @@ static void at91_irq_err_frame(struct net_device *dev, const u32 reg_sr)
 	if (!cf)
 		return;
 
-	netif_receive_skb(skb);
+	err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
+	if (err)
+		stats->rx_fifo_errors++;
+}
+
+static u32 at91_get_reg_sr_rx(const struct at91_priv *priv, u32 *reg_sr_p)
+{
+	const u32 reg_sr = at91_read(priv, AT91_SR);
+
+	*reg_sr_p |= reg_sr;
+
+	return reg_sr & get_irq_mb_rx(priv);
 }
 
-/* interrupt handler
- */
 static irqreturn_t at91_irq(int irq, void *dev_id)
 {
 	struct net_device *dev = dev_id;
 	struct at91_priv *priv = netdev_priv(dev);
 	irqreturn_t handled = IRQ_NONE;
-	u32 reg_sr, reg_imr;
+	u32 reg_sr = 0, reg_sr_rx;
+	int ret;
 
-	reg_sr = at91_read(priv, AT91_SR);
-	reg_imr = at91_read(priv, AT91_IMR);
+	/* Receive interrupt
+	 * Some bits of AT91_SR are cleared on read, keep them in reg_sr.
+	 */
+	while ((reg_sr_rx = at91_get_reg_sr_rx(priv, &reg_sr))) {
+		ret = can_rx_offload_irq_offload_timestamp(&priv->offload,
+							   reg_sr_rx);
+		handled = IRQ_HANDLED;
 
-	/* Ignore masked interrupts */
-	reg_sr &= reg_imr;
-	if (!reg_sr)
-		goto exit;
-
-	handled = IRQ_HANDLED;
-
-	/* Receive interrupt? -> napi */
-	if (reg_sr & get_irq_mb_rx(priv)) {
-		at91_write(priv, AT91_IDR,
-			   get_irq_mb_rx(priv));
-		napi_schedule(&priv->napi);
+		if (!ret)
+			break;
 	}
 
 	/* Transmission complete interrupt */
-	if (reg_sr & get_irq_mb_tx(priv))
+	if (reg_sr & get_irq_mb_tx(priv)) {
 		at91_irq_tx(dev, reg_sr);
+		handled = IRQ_HANDLED;
+	}
 
 	/* Line Error interrupt */
 	if (reg_sr & AT91_IRQ_ERR_LINE ||
 	    priv->can.state > CAN_STATE_ERROR_ACTIVE) {
 		at91_irq_err_line(dev, reg_sr);
+		handled = IRQ_HANDLED;
 	}
 
 	/* Frame Error Interrupt */
-	if (reg_sr & AT91_IRQ_ERR_FRAME)
+	if (reg_sr & AT91_IRQ_ERR_FRAME) {
 		at91_irq_err_frame(dev, reg_sr);
+		handled = IRQ_HANDLED;
+	}
+
+	if (handled)
+		can_rx_offload_irq_finish(&priv->offload);
 
- exit:
 	return handled;
 }
 
@@ -1040,7 +895,7 @@ static int at91_open(struct net_device *dev)
 
 	/* start chip and queuing */
 	at91_chip_start(dev);
-	napi_enable(&priv->napi);
+	can_rx_offload_enable(&priv->offload);
 	netif_start_queue(dev);
 
 	return 0;
@@ -1062,7 +917,7 @@ static int at91_close(struct net_device *dev)
 	struct at91_priv *priv = netdev_priv(dev);
 
 	netif_stop_queue(dev);
-	napi_disable(&priv->napi);
+	can_rx_offload_disable(&priv->offload);
 	at91_chip_stop(dev, CAN_STATE_STOPPED);
 
 	free_irq(dev->irq, dev);
@@ -1265,8 +1120,11 @@ static int at91_can_probe(struct platform_device *pdev)
 	priv->clk = clk;
 	priv->pdata = dev_get_platdata(&pdev->dev);
 	priv->mb0_id = 0x7ff;
+	priv->offload.mailbox_read = at91_mailbox_read;
+	priv->offload.mb_first = devtype_data->rx_first;
+	priv->offload.mb_last = devtype_data->rx_last;
 
-	netif_napi_add_weight(dev, &priv->napi, at91_poll, get_mb_rx_num(priv));
+	can_rx_offload_add_timestamp(dev, &priv->offload);
 
 	if (transceiver)
 		priv->can.bitrate_max = transceiver->attrs.max_link_rate;
-- 
2.40.1



^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH net-next 01/37] can: sja1000: Fix comment
  2023-10-05 19:57 ` [PATCH net-next 01/37] can: sja1000: Fix comment Marc Kleine-Budde
@ 2023-10-06 22:50   ` patchwork-bot+netdevbpf
  0 siblings, 0 replies; 39+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-10-06 22:50 UTC (permalink / raw)
  To: Marc Kleine-Budde
  Cc: netdev, davem, kuba, linux-can, kernel, miquel.raynal, horms

Hello:

This series was applied to netdev/net-next.git (main)
by Marc Kleine-Budde <mkl@pengutronix.de>:

On Thu,  5 Oct 2023 21:57:36 +0200 you wrote:
> From: Miquel Raynal <miquel.raynal@bootlin.com>
> 
> There is likely a copy-paste error here, as the exact same comment
> appears below in this function, one time calling set_reset_mode(), the
> other set_normal_mode().
> 
> Fixes: 429da1cc841b ("can: Driver for the SJA1000 CAN controller")
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> Reviewed-by: Simon Horman <horms@kernel.org>
> Link: https://lore.kernel.org/all/20230922155130.592187-1-miquel.raynal@bootlin.com
> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
> 
> [...]

Here is the summary with links:
  - [net-next,01/37] can: sja1000: Fix comment
    https://git.kernel.org/netdev/net-next/c/e36c56bf77d5
  - [net-next,02/37] can: etas_es58x: rework the version check logic to silence -Wformat-truncation
    https://git.kernel.org/netdev/net-next/c/107e6f6fe6f3
  - [net-next,03/37] can: etas_es58x: add missing a blank line after declaration
    https://git.kernel.org/netdev/net-next/c/4f8005092caf
  - [net-next,04/37] can: raw: Remove NULL check before dev_{put, hold}
    https://git.kernel.org/netdev/net-next/c/dd8bb80308c4
  - [net-next,05/37] can: peak_pci: replace deprecated strncpy with strscpy
    https://git.kernel.org/netdev/net-next/c/3b9333493b5f
  - [net-next,06/37] can: dev: can_restart(): don't crash kernel if carrier is OK
    https://git.kernel.org/netdev/net-next/c/fe5c9940dfd8
  - [net-next,07/37] can: dev: can_restart(): fix race condition between controller restart and netif_carrier_on()
    https://git.kernel.org/netdev/net-next/c/6841cab8c450
  - [net-next,08/37] can: dev: can_restart(): reverse logic to remove need for goto
    https://git.kernel.org/netdev/net-next/c/8f3ec204d340
  - [net-next,09/37] can: dev: can_restart(): move debug message and stats after successful restart
    https://git.kernel.org/netdev/net-next/c/f0e0c809c0be
  - [net-next,10/37] can: dev: can_put_echo_skb(): don't crash kernel if can_priv::echo_skb is accessed out of bounds
    https://git.kernel.org/netdev/net-next/c/6411959c10fe
  - [net-next,11/37] can: dev: add can_state_get_by_berr_counter() to return the CAN state based on the current error counters
    https://git.kernel.org/netdev/net-next/c/9beebc2b5d00
  - [net-next,12/37] can: at91_can: use a consistent indention
    https://git.kernel.org/netdev/net-next/c/e26ccc4658c1
  - [net-next,13/37] can: at91_can: at91_irq_tx(): remove one level of indention
    https://git.kernel.org/netdev/net-next/c/18c987147483
  - [net-next,14/37] can: at91_can: BR register: convert to FIELD_PREP()
    https://git.kernel.org/netdev/net-next/c/bd7854e83900
  - [net-next,15/37] can: at91_can: ECR register: convert to FIELD_GET()
    https://git.kernel.org/netdev/net-next/c/abe1348753b3
  - [net-next,16/37] can: at91_can: MMR registers: convert to FIELD_PREP()
    https://git.kernel.org/netdev/net-next/c/53558ac133c0
  - [net-next,17/37] can: at91_can: MID registers: convert access to FIELD_PREP(), FIELD_GET()
    https://git.kernel.org/netdev/net-next/c/90aa9a250cf2
  - [net-next,18/37] can: at91_can: MSR Register: convert to FIELD_PREP()
    https://git.kernel.org/netdev/net-next/c/bdfff1433cd6
  - [net-next,19/37] can: at91_can: MCR Register: convert to FIELD_PREP()
    https://git.kernel.org/netdev/net-next/c/5e9c5bcc017d
  - [net-next,20/37] can: at91_can: add more register definitions
    https://git.kernel.org/netdev/net-next/c/63446dc70316
  - [net-next,21/37] can: at91_can: at91_setup_mailboxes(): update comments
    https://git.kernel.org/netdev/net-next/c/2b08e5217a1d
  - [net-next,22/37] can: at91_can: rename struct at91_priv::{tx_next,tx_echo} to {tx_head,tx_tail}
    https://git.kernel.org/netdev/net-next/c/2f1a01a82fca
  - [net-next,23/37] can: at91_can: at91_set_bittiming(): demote register output to debug level
    https://git.kernel.org/netdev/net-next/c/ccd7cd07051f
  - [net-next,24/37] can: at91_can: at91_chip_start(): don't disable IRQs twice
    https://git.kernel.org/netdev/net-next/c/8227088cb3c2
  - [net-next,25/37] can: at91_can: at91_open(): forward request_irq()'s return value in case or an error
    https://git.kernel.org/netdev/net-next/c/99f4ff41bbb0
  - [net-next,26/37] can: at91_can: add CAN transceiver support
    https://git.kernel.org/netdev/net-next/c/3ecc09856afb
  - [net-next,27/37] can: at91_can: at91_poll_err(): fold in at91_poll_err_frame()
    https://git.kernel.org/netdev/net-next/c/864c6f07d3c4
  - [net-next,28/37] can: at91_can: at91_poll_err(): increase stats even if no quota left or OOM
    https://git.kernel.org/netdev/net-next/c/aa3f5d935cbb
  - [net-next,29/37] can: at91_can: at91_irq_err_frame(): call directly from IRQ handler
    https://git.kernel.org/netdev/net-next/c/d3f4cf05402b
  - [net-next,30/37] can: at91_can: at91_irq_err_frame(): move next to at91_irq_err()
    https://git.kernel.org/netdev/net-next/c/e0c9db91d60b
  - [net-next,31/37] can: at91_can: at91_irq_err(): rename to at91_irq_err_line()
    https://git.kernel.org/netdev/net-next/c/efad777c3e97
  - [net-next,32/37] can: at91_can: at91_irq_err_line(): make use of can_state_get_by_berr_counter()
    https://git.kernel.org/netdev/net-next/c/910f179aa0de
  - [net-next,33/37] can: at91_can: at91_irq_err_line(): take reg_sr into account for bus off
    https://git.kernel.org/netdev/net-next/c/f13e86993d85
  - [net-next,34/37] can: at91_can: at91_irq_err_line(): make use of can_change_state() and can_bus_off()
    https://git.kernel.org/netdev/net-next/c/9df2faf947bc
  - [net-next,35/37] can: at91_can: at91_irq_err_line(): send error counters with state change
    https://git.kernel.org/netdev/net-next/c/3db6154e44db
  - [net-next,36/37] can: at91_can: at91_alloc_can_err_skb() introduce new function
    https://git.kernel.org/netdev/net-next/c/dd94a2f1f2f8
  - [net-next,37/37] can: at91_can: switch to rx-offload implementation
    https://git.kernel.org/netdev/net-next/c/137f59d5dab4

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2023-10-06 22:50 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-05 19:57 [PATCH net-next 0/37] pull-request: can-next 2023-10-05 Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 01/37] can: sja1000: Fix comment Marc Kleine-Budde
2023-10-06 22:50   ` patchwork-bot+netdevbpf
2023-10-05 19:57 ` [PATCH net-next 02/37] can: etas_es58x: rework the version check logic to silence -Wformat-truncation Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 03/37] can: etas_es58x: add missing a blank line after declaration Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 04/37] can: raw: Remove NULL check before dev_{put, hold} Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 05/37] can: peak_pci: replace deprecated strncpy with strscpy Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 06/37] can: dev: can_restart(): don't crash kernel if carrier is OK Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 07/37] can: dev: can_restart(): fix race condition between controller restart and netif_carrier_on() Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 08/37] can: dev: can_restart(): reverse logic to remove need for goto Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 09/37] can: dev: can_restart(): move debug message and stats after successful restart Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 10/37] can: dev: can_put_echo_skb(): don't crash kernel if can_priv::echo_skb is accessed out of bounds Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 11/37] can: dev: add can_state_get_by_berr_counter() to return the CAN state based on the current error counters Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 12/37] can: at91_can: use a consistent indention Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 13/37] can: at91_can: at91_irq_tx(): remove one level of indention Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 14/37] can: at91_can: BR register: convert to FIELD_PREP() Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 15/37] can: at91_can: ECR register: convert to FIELD_GET() Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 16/37] can: at91_can: MMR registers: convert to FIELD_PREP() Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 17/37] can: at91_can: MID registers: convert access to FIELD_PREP(), FIELD_GET() Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 18/37] can: at91_can: MSR Register: convert to FIELD_PREP() Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 19/37] can: at91_can: MCR " Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 20/37] can: at91_can: add more register definitions Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 21/37] can: at91_can: at91_setup_mailboxes(): update comments Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 22/37] can: at91_can: rename struct at91_priv::{tx_next,tx_echo} to {tx_head,tx_tail} Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 23/37] can: at91_can: at91_set_bittiming(): demote register output to debug level Marc Kleine-Budde
2023-10-05 19:57 ` [PATCH net-next 24/37] can: at91_can: at91_chip_start(): don't disable IRQs twice Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 25/37] can: at91_can: at91_open(): forward request_irq()'s return value in case or an error Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 26/37] can: at91_can: add CAN transceiver support Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 27/37] can: at91_can: at91_poll_err(): fold in at91_poll_err_frame() Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 28/37] can: at91_can: at91_poll_err(): increase stats even if no quota left or OOM Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 29/37] can: at91_can: at91_irq_err_frame(): call directly from IRQ handler Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 30/37] can: at91_can: at91_irq_err_frame(): move next to at91_irq_err() Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 31/37] can: at91_can: at91_irq_err(): rename to at91_irq_err_line() Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 32/37] can: at91_can: at91_irq_err_line(): make use of can_state_get_by_berr_counter() Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 33/37] can: at91_can: at91_irq_err_line(): take reg_sr into account for bus off Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 34/37] can: at91_can: at91_irq_err_line(): make use of can_change_state() and can_bus_off() Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 35/37] can: at91_can: at91_irq_err_line(): send error counters with state change Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 36/37] can: at91_can: at91_alloc_can_err_skb() introduce new function Marc Kleine-Budde
2023-10-05 19:58 ` [PATCH net-next 37/37] can: at91_can: switch to rx-offload implementation Marc Kleine-Budde

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.