mirror of
https://github.com/torvalds/linux.git
synced 2025-12-01 07:26:02 +07:00
Merge tag 'linux-can-next-for-6.17-20250618' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next
Marc Kleine-Budde says:
====================
pull-request: can-next 2025-06-18
All 10 patches are by Geert Uytterhoeven, target the rcar_canfd
driver, first cleanup/refactor the driver and then add support for
Transceiver Delay Compensation.
* tag 'linux-can-next-for-6.17-20250618' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next:
can: rcar_canfd: Add support for Transceiver Delay Compensation
can: rcar_canfd: Return early in rcar_canfd_set_bittiming() when not FD
can: rcar_canfd: Share config code in rcar_canfd_set_bittiming()
can: rcar_canfd: Rename rcar_canfd_setrnc() to rcar_canfd_set_rnc()
can: rcar_canfd: Repurpose f_dcfg base for other registers
can: rcar_canfd: Simplify data access in rcar_canfd_{ge,pu}t_data()
can: rcar_canfd: Add helper variable dev to rcar_canfd_reset_controller()
can: rcar_canfd: Add helper variable ndev to rcar_canfd_rx_pkt()
can: rcar_canfd: Remove bittiming debug prints
can: rcar_canfd: Consistently use ndev for net_device pointers
====================
Link: https://patch.msgid.link/20250618092336.2175168-1-mkl@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -191,9 +191,19 @@
|
||||
/* RSCFDnCFDCmFDCFG */
|
||||
#define RCANFD_GEN4_FDCFG_CLOE BIT(30)
|
||||
#define RCANFD_GEN4_FDCFG_FDOE BIT(28)
|
||||
#define RCANFD_FDCFG_TDCO GENMASK(23, 16)
|
||||
#define RCANFD_FDCFG_TDCE BIT(9)
|
||||
#define RCANFD_FDCFG_TDCOC BIT(8)
|
||||
#define RCANFD_FDCFG_TDCO(x) (((x) & 0x7f) >> 16)
|
||||
|
||||
/* RSCFDnCFDCmFDSTS */
|
||||
#define RCANFD_FDSTS_SOC GENMASK(31, 24)
|
||||
#define RCANFD_FDSTS_EOC GENMASK(23, 16)
|
||||
#define RCANFD_GEN4_FDSTS_TDCVF BIT(15)
|
||||
#define RCANFD_GEN4_FDSTS_PNSTS GENMASK(13, 12)
|
||||
#define RCANFD_FDSTS_SOCO BIT(9)
|
||||
#define RCANFD_FDSTS_EOCO BIT(8)
|
||||
#define RCANFD_FDSTS_TDCVF BIT(7)
|
||||
#define RCANFD_FDSTS_TDCR GENMASK(7, 0)
|
||||
|
||||
/* RSCFDnCFDRFCCx */
|
||||
#define RCANFD_RFCC_RFIM BIT(12)
|
||||
@@ -425,19 +435,10 @@
|
||||
#define RCANFD_C_RPGACC(r) (0x1900 + (0x04 * (r)))
|
||||
|
||||
/* R-Car Gen4 Classical and CAN FD mode specific register map */
|
||||
#define RCANFD_GEN4_FDCFG(m) (0x1404 + (0x20 * (m)))
|
||||
|
||||
#define RCANFD_GEN4_GAFL_OFFSET (0x1800)
|
||||
|
||||
/* CAN FD mode specific register map */
|
||||
|
||||
/* RSCFDnCFDCmXXX -> RCANFD_F_XXX(m) */
|
||||
#define RCANFD_F_DCFG(gpriv, m) ((gpriv)->info->regs->f_dcfg + (0x20 * (m)))
|
||||
#define RCANFD_F_CFDCFG(m) (0x0504 + (0x20 * (m)))
|
||||
#define RCANFD_F_CFDCTR(m) (0x0508 + (0x20 * (m)))
|
||||
#define RCANFD_F_CFDSTS(m) (0x050c + (0x20 * (m)))
|
||||
#define RCANFD_F_CFDCRC(m) (0x0510 + (0x20 * (m)))
|
||||
|
||||
/* RSCFDnCFDGAFLXXXj offset */
|
||||
#define RCANFD_F_GAFL_OFFSET (0x1000)
|
||||
|
||||
@@ -510,7 +511,7 @@ struct rcar_canfd_regs {
|
||||
u16 cfcc; /* Common FIFO Configuration/Control Register */
|
||||
u16 cfsts; /* Common FIFO Status Register */
|
||||
u16 cfpctr; /* Common FIFO Pointer Control Register */
|
||||
u16 f_dcfg; /* Global FD Configuration Register */
|
||||
u16 coffset; /* Channel Data Bitrate Configuration Register */
|
||||
u16 rfoffset; /* Receive FIFO buffer access ID register */
|
||||
u16 cfoffset; /* Transmit/receive FIFO buffer access ID register */
|
||||
};
|
||||
@@ -529,6 +530,7 @@ struct rcar_canfd_shift_data {
|
||||
struct rcar_canfd_hw_info {
|
||||
const struct can_bittiming_const *nom_bittiming;
|
||||
const struct can_bittiming_const *data_bittiming;
|
||||
const struct can_tdc_const *tdc_const;
|
||||
const struct rcar_canfd_regs *regs;
|
||||
const struct rcar_canfd_shift_data *sh;
|
||||
u8 rnc_field_width;
|
||||
@@ -636,12 +638,31 @@ static const struct can_bittiming_const rcar_canfd_bittiming_const = {
|
||||
.brp_inc = 1,
|
||||
};
|
||||
|
||||
/* CAN FD Transmission Delay Compensation constants */
|
||||
static const struct can_tdc_const rcar_canfd_gen3_tdc_const = {
|
||||
.tdcv_min = 1,
|
||||
.tdcv_max = 128,
|
||||
.tdco_min = 1,
|
||||
.tdco_max = 128,
|
||||
.tdcf_min = 0, /* Filter window not supported */
|
||||
.tdcf_max = 0,
|
||||
};
|
||||
|
||||
static const struct can_tdc_const rcar_canfd_gen4_tdc_const = {
|
||||
.tdcv_min = 1,
|
||||
.tdcv_max = 256,
|
||||
.tdco_min = 1,
|
||||
.tdco_max = 256,
|
||||
.tdcf_min = 0, /* Filter window not supported */
|
||||
.tdcf_max = 0,
|
||||
};
|
||||
|
||||
static const struct rcar_canfd_regs rcar_gen3_regs = {
|
||||
.rfcc = 0x00b8,
|
||||
.cfcc = 0x0118,
|
||||
.cfsts = 0x0178,
|
||||
.cfpctr = 0x01d8,
|
||||
.f_dcfg = 0x0500,
|
||||
.coffset = 0x0500,
|
||||
.rfoffset = 0x3000,
|
||||
.cfoffset = 0x3400,
|
||||
};
|
||||
@@ -651,7 +672,7 @@ static const struct rcar_canfd_regs rcar_gen4_regs = {
|
||||
.cfcc = 0x0120,
|
||||
.cfsts = 0x01e0,
|
||||
.cfpctr = 0x0240,
|
||||
.f_dcfg = 0x1400,
|
||||
.coffset = 0x1400,
|
||||
.rfoffset = 0x6000,
|
||||
.cfoffset = 0x6400,
|
||||
};
|
||||
@@ -681,6 +702,7 @@ static const struct rcar_canfd_shift_data rcar_gen4_shift_data = {
|
||||
static const struct rcar_canfd_hw_info rcar_gen3_hw_info = {
|
||||
.nom_bittiming = &rcar_canfd_gen3_nom_bittiming_const,
|
||||
.data_bittiming = &rcar_canfd_gen3_data_bittiming_const,
|
||||
.tdc_const = &rcar_canfd_gen3_tdc_const,
|
||||
.regs = &rcar_gen3_regs,
|
||||
.sh = &rcar_gen3_shift_data,
|
||||
.rnc_field_width = 8,
|
||||
@@ -697,6 +719,7 @@ static const struct rcar_canfd_hw_info rcar_gen3_hw_info = {
|
||||
static const struct rcar_canfd_hw_info rcar_gen4_hw_info = {
|
||||
.nom_bittiming = &rcar_canfd_gen4_nom_bittiming_const,
|
||||
.data_bittiming = &rcar_canfd_gen4_data_bittiming_const,
|
||||
.tdc_const = &rcar_canfd_gen4_tdc_const,
|
||||
.regs = &rcar_gen4_regs,
|
||||
.sh = &rcar_gen4_shift_data,
|
||||
.rnc_field_width = 16,
|
||||
@@ -713,6 +736,7 @@ static const struct rcar_canfd_hw_info rcar_gen4_hw_info = {
|
||||
static const struct rcar_canfd_hw_info rzg2l_hw_info = {
|
||||
.nom_bittiming = &rcar_canfd_gen3_nom_bittiming_const,
|
||||
.data_bittiming = &rcar_canfd_gen3_data_bittiming_const,
|
||||
.tdc_const = &rcar_canfd_gen3_tdc_const,
|
||||
.regs = &rcar_gen3_regs,
|
||||
.sh = &rcar_gen3_shift_data,
|
||||
.rnc_field_width = 8,
|
||||
@@ -729,6 +753,7 @@ static const struct rcar_canfd_hw_info rzg2l_hw_info = {
|
||||
static const struct rcar_canfd_hw_info r9a09g047_hw_info = {
|
||||
.nom_bittiming = &rcar_canfd_gen4_nom_bittiming_const,
|
||||
.data_bittiming = &rcar_canfd_gen4_data_bittiming_const,
|
||||
.tdc_const = &rcar_canfd_gen4_tdc_const,
|
||||
.regs = &rcar_gen4_regs,
|
||||
.sh = &rcar_gen4_shift_data,
|
||||
.rnc_field_width = 16,
|
||||
@@ -781,23 +806,54 @@ static void rcar_canfd_update_bit(void __iomem *base, u32 reg,
|
||||
static void rcar_canfd_get_data(struct rcar_canfd_channel *priv,
|
||||
struct canfd_frame *cf, u32 off)
|
||||
{
|
||||
u32 *data = (u32 *)cf->data;
|
||||
u32 i, lwords;
|
||||
|
||||
lwords = DIV_ROUND_UP(cf->len, sizeof(u32));
|
||||
for (i = 0; i < lwords; i++)
|
||||
*((u32 *)cf->data + i) =
|
||||
rcar_canfd_read(priv->base, off + i * sizeof(u32));
|
||||
data[i] = rcar_canfd_read(priv->base, off + i * sizeof(u32));
|
||||
}
|
||||
|
||||
static void rcar_canfd_put_data(struct rcar_canfd_channel *priv,
|
||||
struct canfd_frame *cf, u32 off)
|
||||
{
|
||||
const u32 *data = (u32 *)cf->data;
|
||||
u32 i, lwords;
|
||||
|
||||
lwords = DIV_ROUND_UP(cf->len, sizeof(u32));
|
||||
for (i = 0; i < lwords; i++)
|
||||
rcar_canfd_write(priv->base, off + i * sizeof(u32),
|
||||
*((u32 *)cf->data + i));
|
||||
rcar_canfd_write(priv->base, off + i * sizeof(u32), data[i]);
|
||||
}
|
||||
|
||||
/* RSCFDnCFDCmXXX -> rcar_canfd_f_xxx(gpriv, ch) */
|
||||
static inline unsigned int rcar_canfd_f_dcfg(struct rcar_canfd_global *gpriv,
|
||||
unsigned int ch)
|
||||
{
|
||||
return gpriv->info->regs->coffset + 0x00 + 0x20 * ch;
|
||||
}
|
||||
|
||||
static inline unsigned int rcar_canfd_f_cfdcfg(struct rcar_canfd_global *gpriv,
|
||||
unsigned int ch)
|
||||
{
|
||||
return gpriv->info->regs->coffset + 0x04 + 0x20 * ch;
|
||||
}
|
||||
|
||||
static inline unsigned int rcar_canfd_f_cfdctr(struct rcar_canfd_global *gpriv,
|
||||
unsigned int ch)
|
||||
{
|
||||
return gpriv->info->regs->coffset + 0x08 + 0x20 * ch;
|
||||
}
|
||||
|
||||
static inline unsigned int rcar_canfd_f_cfdsts(struct rcar_canfd_global *gpriv,
|
||||
unsigned int ch)
|
||||
{
|
||||
return gpriv->info->regs->coffset + 0x0c + 0x20 * ch;
|
||||
}
|
||||
|
||||
static inline unsigned int rcar_canfd_f_cfdcrc(struct rcar_canfd_global *gpriv,
|
||||
unsigned int ch)
|
||||
{
|
||||
return gpriv->info->regs->coffset + 0x10 + 0x20 * ch;
|
||||
}
|
||||
|
||||
static void rcar_canfd_tx_failure_cleanup(struct net_device *ndev)
|
||||
@@ -808,8 +864,8 @@ static void rcar_canfd_tx_failure_cleanup(struct net_device *ndev)
|
||||
can_free_echo_skb(ndev, i, NULL);
|
||||
}
|
||||
|
||||
static void rcar_canfd_setrnc(struct rcar_canfd_global *gpriv, unsigned int ch,
|
||||
unsigned int num_rules)
|
||||
static void rcar_canfd_set_rnc(struct rcar_canfd_global *gpriv, unsigned int ch,
|
||||
unsigned int num_rules)
|
||||
{
|
||||
unsigned int rnc_stride = 32 / gpriv->info->rnc_field_width;
|
||||
unsigned int shift = 32 - (ch % rnc_stride + 1) * gpriv->info->rnc_field_width;
|
||||
@@ -827,8 +883,8 @@ static void rcar_canfd_set_mode(struct rcar_canfd_global *gpriv)
|
||||
|
||||
for_each_set_bit(ch, &gpriv->channels_mask,
|
||||
gpriv->info->max_channels)
|
||||
rcar_canfd_set_bit(gpriv->base, RCANFD_GEN4_FDCFG(ch),
|
||||
val);
|
||||
rcar_canfd_set_bit(gpriv->base,
|
||||
rcar_canfd_f_cfdcfg(gpriv, ch), val);
|
||||
} else {
|
||||
if (gpriv->fdmode)
|
||||
rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG,
|
||||
@@ -841,6 +897,7 @@ static void rcar_canfd_set_mode(struct rcar_canfd_global *gpriv)
|
||||
|
||||
static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv)
|
||||
{
|
||||
struct device *dev = &gpriv->pdev->dev;
|
||||
u32 sts, ch;
|
||||
int err;
|
||||
|
||||
@@ -850,7 +907,7 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv)
|
||||
err = readl_poll_timeout((gpriv->base + RCANFD_GSTS), sts,
|
||||
!(sts & RCANFD_GSTS_GRAMINIT), 2, 500000);
|
||||
if (err) {
|
||||
dev_dbg(&gpriv->pdev->dev, "global raminit failed\n");
|
||||
dev_dbg(dev, "global raminit failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -863,7 +920,7 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv)
|
||||
err = readl_poll_timeout((gpriv->base + RCANFD_GSTS), sts,
|
||||
(sts & RCANFD_GSTS_GRSTSTS), 2, 500000);
|
||||
if (err) {
|
||||
dev_dbg(&gpriv->pdev->dev, "global reset failed\n");
|
||||
dev_dbg(dev, "global reset failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -887,8 +944,7 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv)
|
||||
(sts & RCANFD_CSTS_CRSTSTS),
|
||||
2, 500000);
|
||||
if (err) {
|
||||
dev_dbg(&gpriv->pdev->dev,
|
||||
"channel %u reset failed\n", ch);
|
||||
dev_dbg(dev, "channel %u reset failed\n", ch);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@@ -938,7 +994,7 @@ static void rcar_canfd_configure_afl_rules(struct rcar_canfd_global *gpriv,
|
||||
RCANFD_GAFLECTR_AFLDAE));
|
||||
|
||||
/* Write number of rules for channel */
|
||||
rcar_canfd_setrnc(gpriv, ch, num_rules);
|
||||
rcar_canfd_set_rnc(gpriv, ch, num_rules);
|
||||
if (gpriv->info->shared_can_regs)
|
||||
offset = RCANFD_GEN4_GAFL_OFFSET;
|
||||
else if (gpriv->fdmode)
|
||||
@@ -1436,14 +1492,17 @@ static irqreturn_t rcar_canfd_channel_interrupt(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void rcar_canfd_set_bittiming(struct net_device *dev)
|
||||
static void rcar_canfd_set_bittiming(struct net_device *ndev)
|
||||
{
|
||||
struct rcar_canfd_channel *priv = netdev_priv(dev);
|
||||
u32 mask = RCANFD_FDCFG_TDCO | RCANFD_FDCFG_TDCE | RCANFD_FDCFG_TDCOC;
|
||||
struct rcar_canfd_channel *priv = netdev_priv(ndev);
|
||||
struct rcar_canfd_global *gpriv = priv->gpriv;
|
||||
const struct can_bittiming *bt = &priv->can.bittiming;
|
||||
const struct can_bittiming *dbt = &priv->can.fd.data_bittiming;
|
||||
const struct can_tdc_const *tdc_const = priv->can.fd.tdc_const;
|
||||
const struct can_tdc *tdc = &priv->can.fd.tdc;
|
||||
u32 cfg, tdcmode = 0, tdco = 0;
|
||||
u16 brp, sjw, tseg1, tseg2;
|
||||
u32 cfg;
|
||||
u32 ch = priv->channel;
|
||||
|
||||
/* Nominal bit timing settings */
|
||||
@@ -1452,46 +1511,43 @@ static void rcar_canfd_set_bittiming(struct net_device *dev)
|
||||
tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
|
||||
tseg2 = bt->phase_seg2 - 1;
|
||||
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
|
||||
/* CAN FD only mode */
|
||||
if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) || gpriv->info->shared_can_regs) {
|
||||
cfg = (RCANFD_NCFG_NTSEG1(gpriv, tseg1) | RCANFD_NCFG_NBRP(brp) |
|
||||
RCANFD_NCFG_NSJW(gpriv, sjw) | RCANFD_NCFG_NTSEG2(gpriv, tseg2));
|
||||
|
||||
rcar_canfd_write(priv->base, RCANFD_CCFG(ch), cfg);
|
||||
netdev_dbg(priv->ndev, "nrate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n",
|
||||
brp, sjw, tseg1, tseg2);
|
||||
|
||||
/* Data bit timing settings */
|
||||
brp = dbt->brp - 1;
|
||||
sjw = dbt->sjw - 1;
|
||||
tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;
|
||||
tseg2 = dbt->phase_seg2 - 1;
|
||||
|
||||
cfg = (RCANFD_DCFG_DTSEG1(gpriv, tseg1) | RCANFD_DCFG_DBRP(brp) |
|
||||
RCANFD_DCFG_DSJW(gpriv, sjw) | RCANFD_DCFG_DTSEG2(gpriv, tseg2));
|
||||
|
||||
rcar_canfd_write(priv->base, RCANFD_F_DCFG(gpriv, ch), cfg);
|
||||
netdev_dbg(priv->ndev, "drate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n",
|
||||
brp, sjw, tseg1, tseg2);
|
||||
} else {
|
||||
/* Classical CAN only mode */
|
||||
if (gpriv->info->shared_can_regs) {
|
||||
cfg = (RCANFD_NCFG_NTSEG1(gpriv, tseg1) |
|
||||
RCANFD_NCFG_NBRP(brp) |
|
||||
RCANFD_NCFG_NSJW(gpriv, sjw) |
|
||||
RCANFD_NCFG_NTSEG2(gpriv, tseg2));
|
||||
} else {
|
||||
cfg = (RCANFD_CFG_TSEG1(tseg1) |
|
||||
RCANFD_CFG_BRP(brp) |
|
||||
RCANFD_CFG_SJW(sjw) |
|
||||
RCANFD_CFG_TSEG2(tseg2));
|
||||
}
|
||||
|
||||
rcar_canfd_write(priv->base, RCANFD_CCFG(ch), cfg);
|
||||
netdev_dbg(priv->ndev,
|
||||
"rate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n",
|
||||
brp, sjw, tseg1, tseg2);
|
||||
cfg = (RCANFD_CFG_TSEG1(tseg1) | RCANFD_CFG_BRP(brp) |
|
||||
RCANFD_CFG_SJW(sjw) | RCANFD_CFG_TSEG2(tseg2));
|
||||
}
|
||||
|
||||
rcar_canfd_write(priv->base, RCANFD_CCFG(ch), cfg);
|
||||
|
||||
if (!(priv->can.ctrlmode & CAN_CTRLMODE_FD))
|
||||
return;
|
||||
|
||||
/* Data bit timing settings */
|
||||
brp = dbt->brp - 1;
|
||||
sjw = dbt->sjw - 1;
|
||||
tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;
|
||||
tseg2 = dbt->phase_seg2 - 1;
|
||||
|
||||
cfg = (RCANFD_DCFG_DTSEG1(gpriv, tseg1) | RCANFD_DCFG_DBRP(brp) |
|
||||
RCANFD_DCFG_DSJW(gpriv, sjw) | RCANFD_DCFG_DTSEG2(gpriv, tseg2));
|
||||
|
||||
rcar_canfd_write(priv->base, rcar_canfd_f_dcfg(gpriv, ch), cfg);
|
||||
|
||||
/* Transceiver Delay Compensation */
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_TDC_AUTO) {
|
||||
/* TDC enabled, measured + offset */
|
||||
tdcmode = RCANFD_FDCFG_TDCE;
|
||||
tdco = tdc->tdco - 1;
|
||||
} else if (priv->can.ctrlmode & CAN_CTRLMODE_TDC_MANUAL) {
|
||||
/* TDC enabled, offset only */
|
||||
tdcmode = RCANFD_FDCFG_TDCE | RCANFD_FDCFG_TDCOC;
|
||||
tdco = min(tdc->tdcv + tdc->tdco, tdc_const->tdco_max) - 1;
|
||||
}
|
||||
|
||||
rcar_canfd_update_bit(gpriv->base, rcar_canfd_f_cfdcfg(gpriv, ch), mask,
|
||||
tdcmode | FIELD_PREP(RCANFD_FDCFG_TDCO, tdco));
|
||||
}
|
||||
|
||||
static int rcar_canfd_start(struct net_device *ndev)
|
||||
@@ -1691,7 +1747,8 @@ static netdev_tx_t rcar_canfd_start_xmit(struct sk_buff *skb,
|
||||
|
||||
static void rcar_canfd_rx_pkt(struct rcar_canfd_channel *priv)
|
||||
{
|
||||
struct net_device_stats *stats = &priv->ndev->stats;
|
||||
struct net_device *ndev = priv->ndev;
|
||||
struct net_device_stats *stats = &ndev->stats;
|
||||
struct rcar_canfd_global *gpriv = priv->gpriv;
|
||||
struct canfd_frame *cf;
|
||||
struct sk_buff *skb;
|
||||
@@ -1707,14 +1764,13 @@ static void rcar_canfd_rx_pkt(struct rcar_canfd_channel *priv)
|
||||
|
||||
if ((priv->can.ctrlmode & CAN_CTRLMODE_FD) &&
|
||||
sts & RCANFD_RFFDSTS_RFFDF)
|
||||
skb = alloc_canfd_skb(priv->ndev, &cf);
|
||||
skb = alloc_canfd_skb(ndev, &cf);
|
||||
else
|
||||
skb = alloc_can_skb(priv->ndev,
|
||||
(struct can_frame **)&cf);
|
||||
skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
|
||||
} else {
|
||||
id = rcar_canfd_read(priv->base, RCANFD_C_RFID(ridx));
|
||||
dlc = rcar_canfd_read(priv->base, RCANFD_C_RFPTR(ridx));
|
||||
skb = alloc_can_skb(priv->ndev, (struct can_frame **)&cf);
|
||||
skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
|
||||
}
|
||||
|
||||
if (!skb) {
|
||||
@@ -1735,7 +1791,7 @@ static void rcar_canfd_rx_pkt(struct rcar_canfd_channel *priv)
|
||||
|
||||
if (sts & RCANFD_RFFDSTS_RFESI) {
|
||||
cf->flags |= CANFD_ESI;
|
||||
netdev_dbg(priv->ndev, "ESI Error\n");
|
||||
netdev_dbg(ndev, "ESI Error\n");
|
||||
}
|
||||
|
||||
if (!(sts & RCANFD_RFFDSTS_RFFDF) && (id & RCANFD_RFID_RFRTR)) {
|
||||
@@ -1802,6 +1858,29 @@ static int rcar_canfd_rx_poll(struct napi_struct *napi, int quota)
|
||||
return num_pkts;
|
||||
}
|
||||
|
||||
static unsigned int rcar_canfd_get_tdcr(struct rcar_canfd_global *gpriv,
|
||||
unsigned int ch)
|
||||
{
|
||||
u32 sts = rcar_canfd_read(gpriv->base, rcar_canfd_f_cfdsts(gpriv, ch));
|
||||
u32 tdcr = FIELD_GET(RCANFD_FDSTS_TDCR, sts);
|
||||
|
||||
return tdcr & (gpriv->info->tdc_const->tdcv_max - 1);
|
||||
}
|
||||
|
||||
static int rcar_canfd_get_auto_tdcv(const struct net_device *ndev, u32 *tdcv)
|
||||
{
|
||||
struct rcar_canfd_channel *priv = netdev_priv(ndev);
|
||||
u32 tdco = priv->can.fd.tdc.tdco;
|
||||
u32 tdcr;
|
||||
|
||||
/* Transceiver Delay Compensation Result */
|
||||
tdcr = rcar_canfd_get_tdcr(priv->gpriv, priv->channel) + 1;
|
||||
|
||||
*tdcv = tdcr < tdco ? 0 : tdcr - tdco;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rcar_canfd_do_set_mode(struct net_device *ndev, enum can_mode mode)
|
||||
{
|
||||
int err;
|
||||
@@ -1818,10 +1897,10 @@ static int rcar_canfd_do_set_mode(struct net_device *ndev, enum can_mode mode)
|
||||
}
|
||||
}
|
||||
|
||||
static int rcar_canfd_get_berr_counter(const struct net_device *dev,
|
||||
static int rcar_canfd_get_berr_counter(const struct net_device *ndev,
|
||||
struct can_berr_counter *bec)
|
||||
{
|
||||
struct rcar_canfd_channel *priv = netdev_priv(dev);
|
||||
struct rcar_canfd_channel *priv = netdev_priv(ndev);
|
||||
u32 val, ch = priv->channel;
|
||||
|
||||
/* Peripheral clock is already enabled in probe */
|
||||
@@ -1924,12 +2003,17 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
|
||||
if (gpriv->fdmode) {
|
||||
priv->can.bittiming_const = gpriv->info->nom_bittiming;
|
||||
priv->can.fd.data_bittiming_const = gpriv->info->data_bittiming;
|
||||
priv->can.fd.tdc_const = gpriv->info->tdc_const;
|
||||
|
||||
/* Controller starts in CAN FD only mode */
|
||||
err = can_set_static_ctrlmode(ndev, CAN_CTRLMODE_FD);
|
||||
if (err)
|
||||
goto fail;
|
||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING;
|
||||
|
||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING |
|
||||
CAN_CTRLMODE_TDC_AUTO |
|
||||
CAN_CTRLMODE_TDC_MANUAL;
|
||||
priv->can.fd.do_get_auto_tdcv = rcar_canfd_get_auto_tdcv;
|
||||
} else {
|
||||
/* Controller starts in Classical CAN only mode */
|
||||
priv->can.bittiming_const = &rcar_canfd_bittiming_const;
|
||||
|
||||
Reference in New Issue
Block a user