Lines Matching +full:canfd +full:- +full:1
1 // SPDX-License-Identifier: GPL-2.0
3 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
6 // Marc Kleine-Budde <kernel@pengutronix.de>
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()
69 /* CANFD */ 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()
118 mcp251xfd_spi_cmd_crc_set_len_in_ram(&load_buf->crc.cmd, 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()
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()
138 struct net_device *ndev = priv->ndev; in mcp251xfd_tx_failure_drop()
139 struct net_device_stats *stats = &ndev->stats; in mcp251xfd_tx_failure_drop()
143 tx_ring->head--; in mcp251xfd_tx_failure_drop()
144 stats->tx_dropped++; in mcp251xfd_tx_failure_drop()
147 netdev_completed_queue(ndev, 1, frame_len); in mcp251xfd_tx_failure_drop()
151 netdev_err(priv->ndev, "ERROR in %s: %d\n", __func__, err); in mcp251xfd_tx_failure_drop()
158 struct mcp251xfd_tx_obj *tx_obj = priv->tx_work_obj; in mcp251xfd_tx_obj_write_sync()
159 struct mcp251xfd_tx_ring *tx_ring = priv->tx; in mcp251xfd_tx_obj_write_sync()
162 err = spi_sync(priv->spi, &tx_obj->msg); in mcp251xfd_tx_obj_write_sync()
170 return spi_async(priv->spi, &tx_obj->msg); in mcp251xfd_tx_obj_write()
179 netif_stop_queue(priv->ndev); in mcp251xfd_tx_busy()
185 netdev_dbg(priv->ndev, in mcp251xfd_tx_busy()
186 "Stopping tx-queue (tx_head=0x%08x, tx_tail=0x%08x, len=%d).\n", in mcp251xfd_tx_busy()
187 tx_ring->head, tx_ring->tail, in mcp251xfd_tx_busy()
188 tx_ring->head - tx_ring->tail); in mcp251xfd_tx_busy()
193 netif_start_queue(priv->ndev); in mcp251xfd_tx_busy()
207 struct mcp251xfd_tx_ring *tx_ring = priv->tx; in mcp251xfd_start_xmit()
217 mcp251xfd_work_busy(&priv->tx_work)) in mcp251xfd_start_xmit()
221 mcp251xfd_tx_obj_from_skb(priv, tx_obj, skb, tx_ring->head); in mcp251xfd_start_xmit()
225 tx_ring->head++; in mcp251xfd_start_xmit()
232 netdev_sent_queue(priv->ndev, frame_len); in mcp251xfd_start_xmit()
235 if (err == -EBUSY) { in mcp251xfd_start_xmit()
237 priv->tx_work_obj = tx_obj; in mcp251xfd_start_xmit()
238 queue_work(priv->wq, &priv->tx_work); in mcp251xfd_start_xmit()