cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mcp251xfd-ring.c (15574B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// mcp251xfd - Microchip MCP251xFD Family CAN controller driver
      4//
      5// Copyright (c) 2019, 2020, 2021 Pengutronix,
      6//               Marc Kleine-Budde <kernel@pengutronix.de>
      7//
      8// Based on:
      9//
     10// CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
     11//
     12// Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
     13//
     14
     15#include <asm/unaligned.h>
     16
     17#include "mcp251xfd.h"
     18#include "mcp251xfd-ram.h"
     19
     20static inline u8
     21mcp251xfd_cmd_prepare_write_reg(const struct mcp251xfd_priv *priv,
     22				union mcp251xfd_write_reg_buf *write_reg_buf,
     23				const u16 reg, const u32 mask, const u32 val)
     24{
     25	u8 first_byte, last_byte, len;
     26	u8 *data;
     27	__le32 val_le32;
     28
     29	first_byte = mcp251xfd_first_byte_set(mask);
     30	last_byte = mcp251xfd_last_byte_set(mask);
     31	len = last_byte - first_byte + 1;
     32
     33	data = mcp251xfd_spi_cmd_write(priv, write_reg_buf, reg + first_byte);
     34	val_le32 = cpu_to_le32(val >> BITS_PER_BYTE * first_byte);
     35	memcpy(data, &val_le32, len);
     36
     37	if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) {
     38		u16 crc;
     39
     40		mcp251xfd_spi_cmd_crc_set_len_in_reg(&write_reg_buf->crc.cmd,
     41						     len);
     42		/* CRC */
     43		len += sizeof(write_reg_buf->crc.cmd);
     44		crc = mcp251xfd_crc16_compute(&write_reg_buf->crc, len);
     45		put_unaligned_be16(crc, (void *)write_reg_buf + len);
     46
     47		/* Total length */
     48		len += sizeof(write_reg_buf->crc.crc);
     49	} else {
     50		len += sizeof(write_reg_buf->nocrc.cmd);
     51	}
     52
     53	return len;
     54}
     55
     56static void
     57mcp251xfd_ring_init_tef(struct mcp251xfd_priv *priv, u16 *base)
     58{
     59	struct mcp251xfd_tef_ring *tef_ring;
     60	struct spi_transfer *xfer;
     61	u32 val;
     62	u16 addr;
     63	u8 len;
     64	int i;
     65
     66	/* TEF */
     67	tef_ring = priv->tef;
     68	tef_ring->head = 0;
     69	tef_ring->tail = 0;
     70
     71	/* TEF- and TX-FIFO have same number of objects */
     72	*base = mcp251xfd_get_tef_obj_addr(priv->tx->obj_num);
     73
     74	/* FIFO IRQ enable */
     75	addr = MCP251XFD_REG_TEFCON;
     76	val = MCP251XFD_REG_TEFCON_TEFOVIE | MCP251XFD_REG_TEFCON_TEFNEIE;
     77
     78	len = mcp251xfd_cmd_prepare_write_reg(priv, &tef_ring->irq_enable_buf,
     79					      addr, val, val);
     80	tef_ring->irq_enable_xfer.tx_buf = &tef_ring->irq_enable_buf;
     81	tef_ring->irq_enable_xfer.len = len;
     82	spi_message_init_with_transfers(&tef_ring->irq_enable_msg,
     83					&tef_ring->irq_enable_xfer, 1);
     84
     85	/* FIFO increment TEF tail pointer */
     86	addr = MCP251XFD_REG_TEFCON;
     87	val = MCP251XFD_REG_TEFCON_UINC;
     88	len = mcp251xfd_cmd_prepare_write_reg(priv, &tef_ring->uinc_buf,
     89					      addr, val, val);
     90
     91	for (i = 0; i < ARRAY_SIZE(tef_ring->uinc_xfer); i++) {
     92		xfer = &tef_ring->uinc_xfer[i];
     93		xfer->tx_buf = &tef_ring->uinc_buf;
     94		xfer->len = len;
     95		xfer->cs_change = 1;
     96		xfer->cs_change_delay.value = 0;
     97		xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
     98	}
     99
    100	/* "cs_change == 1" on the last transfer results in an active
    101	 * chip select after the complete SPI message. This causes the
    102	 * controller to interpret the next register access as
    103	 * data. Set "cs_change" of the last transfer to "0" to
    104	 * properly deactivate the chip select at the end of the
    105	 * message.
    106	 */
    107	xfer->cs_change = 0;
    108
    109	if (priv->tx_coalesce_usecs_irq || priv->tx_obj_num_coalesce_irq) {
    110		val = MCP251XFD_REG_TEFCON_UINC |
    111			MCP251XFD_REG_TEFCON_TEFOVIE |
    112			MCP251XFD_REG_TEFCON_TEFHIE;
    113
    114		len = mcp251xfd_cmd_prepare_write_reg(priv,
    115						      &tef_ring->uinc_irq_disable_buf,
    116						      addr, val, val);
    117		xfer->tx_buf = &tef_ring->uinc_irq_disable_buf;
    118		xfer->len = len;
    119	}
    120}
    121
    122static void
    123mcp251xfd_tx_ring_init_tx_obj(const struct mcp251xfd_priv *priv,
    124			      const struct mcp251xfd_tx_ring *ring,
    125			      struct mcp251xfd_tx_obj *tx_obj,
    126			      const u8 rts_buf_len,
    127			      const u8 n)
    128{
    129	struct spi_transfer *xfer;
    130	u16 addr;
    131
    132	/* FIFO load */
    133	addr = mcp251xfd_get_tx_obj_addr(ring, n);
    134	if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_TX)
    135		mcp251xfd_spi_cmd_write_crc_set_addr(&tx_obj->buf.crc.cmd,
    136						     addr);
    137	else
    138		mcp251xfd_spi_cmd_write_nocrc(&tx_obj->buf.nocrc.cmd,
    139					      addr);
    140
    141	xfer = &tx_obj->xfer[0];
    142	xfer->tx_buf = &tx_obj->buf;
    143	xfer->len = 0;	/* actual len is assigned on the fly */
    144	xfer->cs_change = 1;
    145	xfer->cs_change_delay.value = 0;
    146	xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
    147
    148	/* FIFO request to send */
    149	xfer = &tx_obj->xfer[1];
    150	xfer->tx_buf = &ring->rts_buf;
    151	xfer->len = rts_buf_len;
    152
    153	/* SPI message */
    154	spi_message_init_with_transfers(&tx_obj->msg, tx_obj->xfer,
    155					ARRAY_SIZE(tx_obj->xfer));
    156}
    157
    158static void
    159mcp251xfd_ring_init_tx(struct mcp251xfd_priv *priv, u16 *base, u8 *fifo_nr)
    160{
    161	struct mcp251xfd_tx_ring *tx_ring;
    162	struct mcp251xfd_tx_obj *tx_obj;
    163	u32 val;
    164	u16 addr;
    165	u8 len;
    166	int i;
    167
    168	tx_ring = priv->tx;
    169	tx_ring->head = 0;
    170	tx_ring->tail = 0;
    171	tx_ring->base = *base;
    172	tx_ring->nr = 0;
    173	tx_ring->fifo_nr = *fifo_nr;
    174
    175	*base = mcp251xfd_get_tx_obj_addr(tx_ring, tx_ring->obj_num);
    176	*fifo_nr += 1;
    177
    178	/* FIFO request to send */
    179	addr = MCP251XFD_REG_FIFOCON(tx_ring->fifo_nr);
    180	val = MCP251XFD_REG_FIFOCON_TXREQ | MCP251XFD_REG_FIFOCON_UINC;
    181	len = mcp251xfd_cmd_prepare_write_reg(priv, &tx_ring->rts_buf,
    182					      addr, val, val);
    183
    184	mcp251xfd_for_each_tx_obj(tx_ring, tx_obj, i)
    185		mcp251xfd_tx_ring_init_tx_obj(priv, tx_ring, tx_obj, len, i);
    186}
    187
    188static void
    189mcp251xfd_ring_init_rx(struct mcp251xfd_priv *priv, u16 *base, u8 *fifo_nr)
    190{
    191	struct mcp251xfd_rx_ring *rx_ring;
    192	struct spi_transfer *xfer;
    193	u32 val;
    194	u16 addr;
    195	u8 len;
    196	int i, j;
    197
    198	mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
    199		rx_ring->head = 0;
    200		rx_ring->tail = 0;
    201		rx_ring->base = *base;
    202		rx_ring->nr = i;
    203		rx_ring->fifo_nr = *fifo_nr;
    204
    205		*base = mcp251xfd_get_rx_obj_addr(rx_ring, rx_ring->obj_num);
    206		*fifo_nr += 1;
    207
    208		/* FIFO IRQ enable */
    209		addr = MCP251XFD_REG_FIFOCON(rx_ring->fifo_nr);
    210		val = MCP251XFD_REG_FIFOCON_RXOVIE |
    211			MCP251XFD_REG_FIFOCON_TFNRFNIE;
    212		len = mcp251xfd_cmd_prepare_write_reg(priv, &rx_ring->irq_enable_buf,
    213						      addr, val, val);
    214		rx_ring->irq_enable_xfer.tx_buf = &rx_ring->irq_enable_buf;
    215		rx_ring->irq_enable_xfer.len = len;
    216		spi_message_init_with_transfers(&rx_ring->irq_enable_msg,
    217						&rx_ring->irq_enable_xfer, 1);
    218
    219		/* FIFO increment RX tail pointer */
    220		val = MCP251XFD_REG_FIFOCON_UINC;
    221		len = mcp251xfd_cmd_prepare_write_reg(priv, &rx_ring->uinc_buf,
    222						      addr, val, val);
    223
    224		for (j = 0; j < ARRAY_SIZE(rx_ring->uinc_xfer); j++) {
    225			xfer = &rx_ring->uinc_xfer[j];
    226			xfer->tx_buf = &rx_ring->uinc_buf;
    227			xfer->len = len;
    228			xfer->cs_change = 1;
    229			xfer->cs_change_delay.value = 0;
    230			xfer->cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
    231		}
    232
    233		/* "cs_change == 1" on the last transfer results in an
    234		 * active chip select after the complete SPI
    235		 * message. This causes the controller to interpret
    236		 * the next register access as data. Set "cs_change"
    237		 * of the last transfer to "0" to properly deactivate
    238		 * the chip select at the end of the message.
    239		 */
    240		xfer->cs_change = 0;
    241
    242		/* Use 1st RX-FIFO for IRQ coalescing. If enabled
    243		 * (rx_coalesce_usecs_irq or rx_max_coalesce_frames_irq
    244		 * is activated), use the last transfer to disable:
    245		 *
    246		 * - TFNRFNIE (Receive FIFO Not Empty Interrupt)
    247		 *
    248		 * and enable:
    249		 *
    250		 * - TFHRFHIE (Receive FIFO Half Full Interrupt)
    251		 *   - or -
    252		 * - TFERFFIE (Receive FIFO Full Interrupt)
    253		 *
    254		 * depending on rx_max_coalesce_frames_irq.
    255		 *
    256		 * The RXOVIE (Overflow Interrupt) is always enabled.
    257		 */
    258		if (rx_ring->nr == 0 && (priv->rx_coalesce_usecs_irq ||
    259					 priv->rx_obj_num_coalesce_irq)) {
    260			val = MCP251XFD_REG_FIFOCON_UINC |
    261				MCP251XFD_REG_FIFOCON_RXOVIE;
    262
    263			if (priv->rx_obj_num_coalesce_irq == rx_ring->obj_num)
    264				val |= MCP251XFD_REG_FIFOCON_TFERFFIE;
    265			else if (priv->rx_obj_num_coalesce_irq)
    266				val |= MCP251XFD_REG_FIFOCON_TFHRFHIE;
    267
    268			len = mcp251xfd_cmd_prepare_write_reg(priv,
    269							      &rx_ring->uinc_irq_disable_buf,
    270							      addr, val, val);
    271			xfer->tx_buf = &rx_ring->uinc_irq_disable_buf;
    272			xfer->len = len;
    273		}
    274	}
    275}
    276
    277int mcp251xfd_ring_init(struct mcp251xfd_priv *priv)
    278{
    279	const struct mcp251xfd_rx_ring *rx_ring;
    280	u16 base = 0, ram_used;
    281	u8 fifo_nr = 1;
    282	int i;
    283
    284	netdev_reset_queue(priv->ndev);
    285
    286	mcp251xfd_ring_init_tef(priv, &base);
    287	mcp251xfd_ring_init_rx(priv, &base, &fifo_nr);
    288	mcp251xfd_ring_init_tx(priv, &base, &fifo_nr);
    289
    290	/* mcp251xfd_handle_rxif() will iterate over all RX rings.
    291	 * Rings with their corresponding bit set in
    292	 * priv->regs_status.rxif are read out.
    293	 *
    294	 * If the chip is configured for only 1 RX-FIFO, and if there
    295	 * is an RX interrupt pending (RXIF in INT register is set),
    296	 * it must be the 1st RX-FIFO.
    297	 *
    298	 * We mark the RXIF of the 1st FIFO as pending here, so that
    299	 * we can skip the read of the RXIF register in
    300	 * mcp251xfd_read_regs_status() for the 1 RX-FIFO only case.
    301	 *
    302	 * If we use more than 1 RX-FIFO, this value gets overwritten
    303	 * in mcp251xfd_read_regs_status(), so set it unconditionally
    304	 * here.
    305	 */
    306	priv->regs_status.rxif = BIT(priv->rx[0]->fifo_nr);
    307
    308	if (priv->tx_obj_num_coalesce_irq) {
    309		netdev_dbg(priv->ndev,
    310			   "FIFO setup: TEF:         0x%03x: %2d*%zu bytes = %4zu bytes (coalesce)\n",
    311			   mcp251xfd_get_tef_obj_addr(0),
    312			   priv->tx_obj_num_coalesce_irq,
    313			   sizeof(struct mcp251xfd_hw_tef_obj),
    314			   priv->tx_obj_num_coalesce_irq *
    315			   sizeof(struct mcp251xfd_hw_tef_obj));
    316
    317		netdev_dbg(priv->ndev,
    318			   "                         0x%03x: %2d*%zu bytes = %4zu bytes\n",
    319			   mcp251xfd_get_tef_obj_addr(priv->tx_obj_num_coalesce_irq),
    320			   priv->tx->obj_num - priv->tx_obj_num_coalesce_irq,
    321			   sizeof(struct mcp251xfd_hw_tef_obj),
    322			   (priv->tx->obj_num - priv->tx_obj_num_coalesce_irq) *
    323			   sizeof(struct mcp251xfd_hw_tef_obj));
    324	} else {
    325		netdev_dbg(priv->ndev,
    326			   "FIFO setup: TEF:         0x%03x: %2d*%zu bytes = %4zu bytes\n",
    327			   mcp251xfd_get_tef_obj_addr(0),
    328			   priv->tx->obj_num, sizeof(struct mcp251xfd_hw_tef_obj),
    329			   priv->tx->obj_num * sizeof(struct mcp251xfd_hw_tef_obj));
    330	}
    331
    332	mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
    333		if (rx_ring->nr == 0 && priv->rx_obj_num_coalesce_irq) {
    334			netdev_dbg(priv->ndev,
    335				   "FIFO setup: RX-%u: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes (coalesce)\n",
    336				   rx_ring->nr, rx_ring->fifo_nr,
    337				   mcp251xfd_get_rx_obj_addr(rx_ring, 0),
    338				   priv->rx_obj_num_coalesce_irq, rx_ring->obj_size,
    339				   priv->rx_obj_num_coalesce_irq * rx_ring->obj_size);
    340
    341			if (priv->rx_obj_num_coalesce_irq == MCP251XFD_FIFO_DEPTH)
    342				continue;
    343
    344			netdev_dbg(priv->ndev,
    345				   "                         0x%03x: %2u*%u bytes = %4u bytes\n",
    346				   mcp251xfd_get_rx_obj_addr(rx_ring,
    347							     priv->rx_obj_num_coalesce_irq),
    348				   rx_ring->obj_num - priv->rx_obj_num_coalesce_irq,
    349				   rx_ring->obj_size,
    350				   (rx_ring->obj_num - priv->rx_obj_num_coalesce_irq) *
    351				   rx_ring->obj_size);
    352		} else {
    353			netdev_dbg(priv->ndev,
    354				   "FIFO setup: RX-%u: FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n",
    355				   rx_ring->nr, rx_ring->fifo_nr,
    356				   mcp251xfd_get_rx_obj_addr(rx_ring, 0),
    357				   rx_ring->obj_num, rx_ring->obj_size,
    358				   rx_ring->obj_num * rx_ring->obj_size);
    359		}
    360	}
    361
    362	netdev_dbg(priv->ndev,
    363		   "FIFO setup: TX:   FIFO %u/0x%03x: %2u*%u bytes = %4u bytes\n",
    364		   priv->tx->fifo_nr,
    365		   mcp251xfd_get_tx_obj_addr(priv->tx, 0),
    366		   priv->tx->obj_num, priv->tx->obj_size,
    367		   priv->tx->obj_num * priv->tx->obj_size);
    368
    369	netdev_dbg(priv->ndev,
    370		   "FIFO setup: free:                             %4d bytes\n",
    371		   MCP251XFD_RAM_SIZE - (base - MCP251XFD_RAM_START));
    372
    373	ram_used = base - MCP251XFD_RAM_START;
    374	if (ram_used > MCP251XFD_RAM_SIZE) {
    375		netdev_err(priv->ndev,
    376			   "Error during ring configuration, using more RAM (%u bytes) than available (%u bytes).\n",
    377			   ram_used, MCP251XFD_RAM_SIZE);
    378		return -ENOMEM;
    379	}
    380
    381	return 0;
    382}
    383
    384void mcp251xfd_ring_free(struct mcp251xfd_priv *priv)
    385{
    386	int i;
    387
    388	for (i = ARRAY_SIZE(priv->rx) - 1; i >= 0; i--) {
    389		kfree(priv->rx[i]);
    390		priv->rx[i] = NULL;
    391	}
    392}
    393
    394static enum hrtimer_restart mcp251xfd_rx_irq_timer(struct hrtimer *t)
    395{
    396	struct mcp251xfd_priv *priv = container_of(t, struct mcp251xfd_priv,
    397						   rx_irq_timer);
    398	struct mcp251xfd_rx_ring *ring = priv->rx[0];
    399
    400	if (test_bit(MCP251XFD_FLAGS_DOWN, priv->flags))
    401		return HRTIMER_NORESTART;
    402
    403	spi_async(priv->spi, &ring->irq_enable_msg);
    404
    405	return HRTIMER_NORESTART;
    406}
    407
    408static enum hrtimer_restart mcp251xfd_tx_irq_timer(struct hrtimer *t)
    409{
    410	struct mcp251xfd_priv *priv = container_of(t, struct mcp251xfd_priv,
    411						   tx_irq_timer);
    412	struct mcp251xfd_tef_ring *ring = priv->tef;
    413
    414	if (test_bit(MCP251XFD_FLAGS_DOWN, priv->flags))
    415		return HRTIMER_NORESTART;
    416
    417	spi_async(priv->spi, &ring->irq_enable_msg);
    418
    419	return HRTIMER_NORESTART;
    420}
    421
    422const struct can_ram_config mcp251xfd_ram_config = {
    423	.rx = {
    424		.size[CAN_RAM_MODE_CAN] = sizeof(struct mcp251xfd_hw_rx_obj_can),
    425		.size[CAN_RAM_MODE_CANFD] = sizeof(struct mcp251xfd_hw_rx_obj_canfd),
    426		.min = MCP251XFD_RX_OBJ_NUM_MIN,
    427		.max = MCP251XFD_RX_OBJ_NUM_MAX,
    428		.def[CAN_RAM_MODE_CAN] = CAN_RAM_NUM_MAX,
    429		.def[CAN_RAM_MODE_CANFD] = CAN_RAM_NUM_MAX,
    430		.fifo_num = MCP251XFD_FIFO_RX_NUM,
    431		.fifo_depth_min = MCP251XFD_RX_FIFO_DEPTH_MIN,
    432		.fifo_depth_coalesce_min = MCP251XFD_RX_FIFO_DEPTH_COALESCE_MIN,
    433	},
    434	.tx = {
    435		.size[CAN_RAM_MODE_CAN] = sizeof(struct mcp251xfd_hw_tef_obj) +
    436			sizeof(struct mcp251xfd_hw_tx_obj_can),
    437		.size[CAN_RAM_MODE_CANFD] = sizeof(struct mcp251xfd_hw_tef_obj) +
    438			sizeof(struct mcp251xfd_hw_tx_obj_canfd),
    439		.min = MCP251XFD_TX_OBJ_NUM_MIN,
    440		.max = MCP251XFD_TX_OBJ_NUM_MAX,
    441		.def[CAN_RAM_MODE_CAN] = MCP251XFD_TX_OBJ_NUM_CAN_DEFAULT,
    442		.def[CAN_RAM_MODE_CANFD] = MCP251XFD_TX_OBJ_NUM_CANFD_DEFAULT,
    443		.fifo_num = MCP251XFD_FIFO_TX_NUM,
    444		.fifo_depth_min = MCP251XFD_TX_FIFO_DEPTH_MIN,
    445		.fifo_depth_coalesce_min = MCP251XFD_TX_FIFO_DEPTH_COALESCE_MIN,
    446	},
    447	.size = MCP251XFD_RAM_SIZE,
    448	.fifo_depth = MCP251XFD_FIFO_DEPTH,
    449};
    450
    451int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)
    452{
    453	const bool fd_mode = mcp251xfd_is_fd_mode(priv);
    454	struct mcp251xfd_tx_ring *tx_ring = priv->tx;
    455	struct mcp251xfd_rx_ring *rx_ring;
    456	u8 tx_obj_size, rx_obj_size;
    457	u8 rem, i;
    458
    459	/* switching from CAN-2.0 to CAN-FD mode or vice versa */
    460	if (fd_mode != test_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags)) {
    461		struct can_ram_layout layout;
    462
    463		can_ram_get_layout(&layout, &mcp251xfd_ram_config, NULL, NULL, fd_mode);
    464		priv->rx_obj_num = layout.default_rx;
    465		tx_ring->obj_num = layout.default_tx;
    466	}
    467
    468	if (fd_mode) {
    469		tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_canfd);
    470		rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_canfd);
    471		set_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags);
    472	} else {
    473		tx_obj_size = sizeof(struct mcp251xfd_hw_tx_obj_can);
    474		rx_obj_size = sizeof(struct mcp251xfd_hw_rx_obj_can);
    475		clear_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags);
    476	}
    477
    478	tx_ring->obj_size = tx_obj_size;
    479
    480	rem = priv->rx_obj_num;
    481	for (i = 0; i < ARRAY_SIZE(priv->rx) && rem; i++) {
    482		u8 rx_obj_num;
    483
    484		if (i == 0 && priv->rx_obj_num_coalesce_irq)
    485			rx_obj_num = min_t(u8, priv->rx_obj_num_coalesce_irq * 2,
    486					   MCP251XFD_FIFO_DEPTH);
    487		else
    488			rx_obj_num = min_t(u8, rounddown_pow_of_two(rem),
    489					   MCP251XFD_FIFO_DEPTH);
    490		rem -= rx_obj_num;
    491
    492		rx_ring = kzalloc(sizeof(*rx_ring) + rx_obj_size * rx_obj_num,
    493				  GFP_KERNEL);
    494		if (!rx_ring) {
    495			mcp251xfd_ring_free(priv);
    496			return -ENOMEM;
    497		}
    498
    499		rx_ring->obj_num = rx_obj_num;
    500		rx_ring->obj_size = rx_obj_size;
    501		priv->rx[i] = rx_ring;
    502	}
    503	priv->rx_ring_num = i;
    504
    505	hrtimer_init(&priv->rx_irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    506	priv->rx_irq_timer.function = mcp251xfd_rx_irq_timer;
    507
    508	hrtimer_init(&priv->tx_irq_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    509	priv->tx_irq_timer.function = mcp251xfd_tx_irq_timer;
    510
    511	return 0;
    512}