Commit 1dba0a37 authored by Biju Das's avatar Biju Das Committed by Marc Kleine-Budde
Browse files

can: rcar_canfd: Fix page entries in the AFL list



There are a total of 96 AFL pages and each page has 16 entries with
registers CFDGAFLIDr, CFDGAFLMr, CFDGAFLP0r, CFDGAFLP1r holding
the rule entries (r = 0..15).

Currently, RCANFD_GAFL* macros use a start variable to find AFL entries,
which is incorrect as the testing on RZ/G3E shows ch1 and ch4
gets a start value of 0 and the register contents are overwritten.

Fix this issue by using rule_entry corresponding to the channel
to find the page entries in the AFL list.

Fixes: dd3bd23e ("can: rcar_canfd: Add Renesas R-Car CAN FD driver")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarBiju Das <biju.das.jz@bp.renesas.com>
Tested-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20250307170330.173425-3-biju.das.jz@bp.renesas.com


Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent 51f6fc9e
Loading
Loading
Loading
Loading
+11 −17
Original line number Diff line number Diff line
@@ -787,22 +787,14 @@ static void rcar_canfd_configure_controller(struct rcar_canfd_global *gpriv)
}

static void rcar_canfd_configure_afl_rules(struct rcar_canfd_global *gpriv,
					   u32 ch)
					   u32 ch, u32 rule_entry)
{
	u32 cfg;
	int offset, start, page, num_rules = RCANFD_CHANNEL_NUMRULES;
	int offset, page, num_rules = RCANFD_CHANNEL_NUMRULES;
	u32 rule_entry_index = rule_entry % 16;
	u32 ridx = ch + RCANFD_RFFIFO_IDX;

	if (ch == 0) {
		start = 0; /* Channel 0 always starts from 0th rule */
	} else {
		/* Get number of Channel 0 rules and adjust */
		cfg = rcar_canfd_read(gpriv->base, RCANFD_GAFLCFG(ch));
		start = RCANFD_GAFLCFG_GETRNC(gpriv, 0, cfg);
	}

	/* Enable write access to entry */
	page = RCANFD_GAFL_PAGENUM(start);
	page = RCANFD_GAFL_PAGENUM(rule_entry);
	rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLECTR,
			   (RCANFD_GAFLECTR_AFLPN(gpriv, page) |
			    RCANFD_GAFLECTR_AFLDAE));
@@ -818,13 +810,13 @@ static void rcar_canfd_configure_afl_rules(struct rcar_canfd_global *gpriv,
		offset = RCANFD_C_GAFL_OFFSET;

	/* Accept all IDs */
	rcar_canfd_write(gpriv->base, RCANFD_GAFLID(offset, start), 0);
	rcar_canfd_write(gpriv->base, RCANFD_GAFLID(offset, rule_entry_index), 0);
	/* IDE or RTR is not considered for matching */
	rcar_canfd_write(gpriv->base, RCANFD_GAFLM(offset, start), 0);
	rcar_canfd_write(gpriv->base, RCANFD_GAFLM(offset, rule_entry_index), 0);
	/* Any data length accepted */
	rcar_canfd_write(gpriv->base, RCANFD_GAFLP0(offset, start), 0);
	rcar_canfd_write(gpriv->base, RCANFD_GAFLP0(offset, rule_entry_index), 0);
	/* Place the msg in corresponding Rx FIFO entry */
	rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLP1(offset, start),
	rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLP1(offset, rule_entry_index),
			   RCANFD_GAFLP1_GAFLFDP(ridx));

	/* Disable write access to page */
@@ -1851,6 +1843,7 @@ static int rcar_canfd_probe(struct platform_device *pdev)
	unsigned long channels_mask = 0;
	int err, ch_irq, g_irq;
	int g_err_irq, g_recc_irq;
	u32 rule_entry = 0;
	bool fdmode = true;			/* CAN FD only mode - default */
	char name[9] = "channelX";
	int i;
@@ -2023,7 +2016,8 @@ static int rcar_canfd_probe(struct platform_device *pdev)
		rcar_canfd_configure_tx(gpriv, ch);

		/* Configure receive rules */
		rcar_canfd_configure_afl_rules(gpriv, ch);
		rcar_canfd_configure_afl_rules(gpriv, ch, rule_entry);
		rule_entry += RCANFD_CHANNEL_NUMRULES;
	}

	/* Configure common interrupts */