Skip to content

Commit 1cee72e

Browse files
Thor Thayergregkh
authored andcommitted
can: c_can: Update D_CAN TX and RX functions to 32 bit - fix Altera Cyclone access
commit 427460c83cdf55069eee49799a0caef7dde8df69 upstream. When testing CAN write floods on Altera's CycloneV, the first 2 bytes are sometimes 0x00, 0x00 or corrupted instead of the values sent. Also observed bytes 4 & 5 were corrupted in some cases. The D_CAN Data registers are 32 bits and changing from 16 bit writes to 32 bit writes fixes the problem. Testing performed on Altera CycloneV (D_CAN). Requesting tests on other C_CAN & D_CAN platforms. Reported-by: Richard Andrysek <richard.andrysek@gomtec.de> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 63b9e0f commit 1cee72e

1 file changed

Lines changed: 31 additions & 7 deletions

File tree

drivers/net/can/c_can/c_can.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -332,9 +332,23 @@ static void c_can_setup_tx_object(struct net_device *dev, int iface,
332332

333333
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
334334

335-
for (i = 0; i < frame->can_dlc; i += 2) {
336-
priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2,
337-
frame->data[i] | (frame->data[i + 1] << 8));
335+
if (priv->type == BOSCH_D_CAN) {
336+
u32 data = 0, dreg = C_CAN_IFACE(DATA1_REG, iface);
337+
338+
for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
339+
data = (u32)frame->data[i];
340+
data |= (u32)frame->data[i + 1] << 8;
341+
data |= (u32)frame->data[i + 2] << 16;
342+
data |= (u32)frame->data[i + 3] << 24;
343+
priv->write_reg32(priv, dreg, data);
344+
}
345+
} else {
346+
for (i = 0; i < frame->can_dlc; i += 2) {
347+
priv->write_reg(priv,
348+
C_CAN_IFACE(DATA1_REG, iface) + i / 2,
349+
frame->data[i] |
350+
(frame->data[i + 1] << 8));
351+
}
338352
}
339353
}
340354

@@ -402,10 +416,20 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl)
402416
} else {
403417
int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
404418

405-
for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
406-
data = priv->read_reg(priv, dreg);
407-
frame->data[i] = data;
408-
frame->data[i + 1] = data >> 8;
419+
if (priv->type == BOSCH_D_CAN) {
420+
for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
421+
data = priv->read_reg32(priv, dreg);
422+
frame->data[i] = data;
423+
frame->data[i + 1] = data >> 8;
424+
frame->data[i + 2] = data >> 16;
425+
frame->data[i + 3] = data >> 24;
426+
}
427+
} else {
428+
for (i = 0; i < frame->can_dlc; i += 2, dreg++) {
429+
data = priv->read_reg(priv, dreg);
430+
frame->data[i] = data;
431+
frame->data[i + 1] = data >> 8;
432+
}
409433
}
410434
}
411435

0 commit comments

Comments
 (0)