Lines Matching +full:spi +full:- +full:crc

1 // SPDX-License-Identifier: GPL-2.0
3 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
6 // Marc Kleine-Budde <kernel@pengutronix.de>
10 // CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface
27 return &tx_ring->obj[tx_head]; in mcp251xfd_get_tx_obj_next()
36 const struct canfd_frame *cfd = (struct canfd_frame *)skb->data; in mcp251xfd_tx_obj_from_skb()
43 if (cfd->can_id & CAN_EFF_FLAG) { in mcp251xfd_tx_obj_from_skb()
46 sid = FIELD_GET(MCP251XFD_REG_FRAME_EFF_SID_MASK, cfd->can_id); in mcp251xfd_tx_obj_from_skb()
47 eid = FIELD_GET(MCP251XFD_REG_FRAME_EFF_EID_MASK, cfd->can_id); in mcp251xfd_tx_obj_from_skb()
54 id = FIELD_PREP(MCP251XFD_OBJ_ID_SID_MASK, cfd->can_id); in mcp251xfd_tx_obj_from_skb()
64 if (cfd->can_id & CAN_RTR_FLAG) in mcp251xfd_tx_obj_from_skb()
67 len_sanitized = canfd_sanitize_len(cfd->len); in mcp251xfd_tx_obj_from_skb()
71 if (cfd->flags & CANFD_ESI) in mcp251xfd_tx_obj_from_skb()
76 if (cfd->flags & CANFD_BRS) in mcp251xfd_tx_obj_from_skb()
79 dlc = can_fd_len2dlc(cfd->len); in mcp251xfd_tx_obj_from_skb()
82 priv->can.ctrlmode); in mcp251xfd_tx_obj_from_skb()
87 load_buf = &tx_obj->buf; in mcp251xfd_tx_obj_from_skb()
88 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_TX) in mcp251xfd_tx_obj_from_skb()
89 hw_tx_obj = &load_buf->crc.hw_tx_obj; in mcp251xfd_tx_obj_from_skb()
91 hw_tx_obj = &load_buf->nocrc.hw_tx_obj; in mcp251xfd_tx_obj_from_skb()
93 put_unaligned_le32(id, &hw_tx_obj->id); in mcp251xfd_tx_obj_from_skb()
94 put_unaligned_le32(flags, &hw_tx_obj->flags); in mcp251xfd_tx_obj_from_skb()
97 memcpy(hw_tx_obj->data, cfd->data, cfd->len); in mcp251xfd_tx_obj_from_skb()
103 pad_len = len_sanitized - cfd->len; in mcp251xfd_tx_obj_from_skb()
105 memset(hw_tx_obj->data + cfd->len, 0x0, pad_len); in mcp251xfd_tx_obj_from_skb()
109 len = sizeof(hw_tx_obj->id) + sizeof(hw_tx_obj->flags); in mcp251xfd_tx_obj_from_skb()
113 len += round_up(cfd->len, sizeof(u32)); in mcp251xfd_tx_obj_from_skb()
115 if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_TX) { in mcp251xfd_tx_obj_from_skb()
116 u16 crc; in mcp251xfd_tx_obj_from_skb() local
118 mcp251xfd_spi_cmd_crc_set_len_in_ram(&load_buf->crc.cmd, in mcp251xfd_tx_obj_from_skb()
120 /* CRC */ in mcp251xfd_tx_obj_from_skb()
121 len += sizeof(load_buf->crc.cmd); in mcp251xfd_tx_obj_from_skb()
122 crc = mcp251xfd_crc16_compute(&load_buf->crc, len); in mcp251xfd_tx_obj_from_skb()
123 put_unaligned_be16(crc, (void *)load_buf + len); in mcp251xfd_tx_obj_from_skb()
126 len += sizeof(load_buf->crc.crc); in mcp251xfd_tx_obj_from_skb()
128 len += sizeof(load_buf->nocrc.cmd); in mcp251xfd_tx_obj_from_skb()
131 tx_obj->xfer[0].len = len; in mcp251xfd_tx_obj_from_skb()
137 return spi_async(priv->spi, &tx_obj->msg); in mcp251xfd_tx_obj_write()
146 netif_stop_queue(priv->ndev); in mcp251xfd_tx_busy()
152 netdev_dbg(priv->ndev, in mcp251xfd_tx_busy()
153 "Stopping tx-queue (tx_head=0x%08x, tx_tail=0x%08x, len=%d).\n", in mcp251xfd_tx_busy()
154 tx_ring->head, tx_ring->tail, in mcp251xfd_tx_busy()
155 tx_ring->head - tx_ring->tail); in mcp251xfd_tx_busy()
160 netif_start_queue(priv->ndev); in mcp251xfd_tx_busy()
169 struct mcp251xfd_tx_ring *tx_ring = priv->tx; in mcp251xfd_start_xmit()
182 mcp251xfd_tx_obj_from_skb(priv, tx_obj, skb, tx_ring->head); in mcp251xfd_start_xmit()
186 tx_ring->head++; in mcp251xfd_start_xmit()
193 netdev_sent_queue(priv->ndev, frame_len); in mcp251xfd_start_xmit()
202 netdev_err(priv->ndev, "ERROR in %s: %d\n", __func__, err); in mcp251xfd_start_xmit()