1*1e846c7aSMarc Kleine-Budde // SPDX-License-Identifier: GPL-2.0 2*1e846c7aSMarc Kleine-Budde // 3*1e846c7aSMarc Kleine-Budde // mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4*1e846c7aSMarc Kleine-Budde // 5*1e846c7aSMarc Kleine-Budde // Copyright (c) 2019, 2020, 2021 Pengutronix, 6*1e846c7aSMarc Kleine-Budde // Marc Kleine-Budde <kernel@pengutronix.de> 7*1e846c7aSMarc Kleine-Budde // 8*1e846c7aSMarc Kleine-Budde // Based on: 9*1e846c7aSMarc Kleine-Budde // 10*1e846c7aSMarc Kleine-Budde // CAN bus driver for Microchip 25XXFD CAN Controller with SPI Interface 11*1e846c7aSMarc Kleine-Budde // 12*1e846c7aSMarc Kleine-Budde // Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org> 13*1e846c7aSMarc Kleine-Budde // 14*1e846c7aSMarc Kleine-Budde 15*1e846c7aSMarc Kleine-Budde #include <linux/bitfield.h> 16*1e846c7aSMarc Kleine-Budde 17*1e846c7aSMarc Kleine-Budde #include "mcp251xfd.h" 18*1e846c7aSMarc Kleine-Budde 19*1e846c7aSMarc Kleine-Budde static inline int 20*1e846c7aSMarc Kleine-Budde mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv, 21*1e846c7aSMarc Kleine-Budde u8 *tef_tail) 22*1e846c7aSMarc Kleine-Budde { 23*1e846c7aSMarc Kleine-Budde u32 tef_ua; 24*1e846c7aSMarc Kleine-Budde int err; 25*1e846c7aSMarc Kleine-Budde 26*1e846c7aSMarc Kleine-Budde err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFUA, &tef_ua); 27*1e846c7aSMarc Kleine-Budde if (err) 28*1e846c7aSMarc Kleine-Budde return err; 29*1e846c7aSMarc Kleine-Budde 30*1e846c7aSMarc Kleine-Budde *tef_tail = tef_ua / sizeof(struct mcp251xfd_hw_tef_obj); 31*1e846c7aSMarc Kleine-Budde 32*1e846c7aSMarc Kleine-Budde return 0; 33*1e846c7aSMarc Kleine-Budde } 34*1e846c7aSMarc Kleine-Budde 35*1e846c7aSMarc Kleine-Budde static int mcp251xfd_check_tef_tail(const struct mcp251xfd_priv *priv) 36*1e846c7aSMarc Kleine-Budde { 37*1e846c7aSMarc Kleine-Budde u8 tef_tail_chip, tef_tail; 38*1e846c7aSMarc Kleine-Budde int err; 39*1e846c7aSMarc Kleine-Budde 40*1e846c7aSMarc Kleine-Budde if (!IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY)) 41*1e846c7aSMarc Kleine-Budde return 0; 42*1e846c7aSMarc Kleine-Budde 43*1e846c7aSMarc Kleine-Budde err = mcp251xfd_tef_tail_get_from_chip(priv, &tef_tail_chip); 44*1e846c7aSMarc Kleine-Budde if (err) 45*1e846c7aSMarc Kleine-Budde return err; 46*1e846c7aSMarc Kleine-Budde 47*1e846c7aSMarc Kleine-Budde tef_tail = mcp251xfd_get_tef_tail(priv); 48*1e846c7aSMarc Kleine-Budde if (tef_tail_chip != tef_tail) { 49*1e846c7aSMarc Kleine-Budde netdev_err(priv->ndev, 50*1e846c7aSMarc Kleine-Budde "TEF tail of chip (0x%02x) and ours (0x%08x) inconsistent.\n", 51*1e846c7aSMarc Kleine-Budde tef_tail_chip, tef_tail); 52*1e846c7aSMarc Kleine-Budde return -EILSEQ; 53*1e846c7aSMarc Kleine-Budde } 54*1e846c7aSMarc Kleine-Budde 55*1e846c7aSMarc Kleine-Budde return 0; 56*1e846c7aSMarc Kleine-Budde } 57*1e846c7aSMarc Kleine-Budde 58*1e846c7aSMarc Kleine-Budde static int 59*1e846c7aSMarc Kleine-Budde mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq) 60*1e846c7aSMarc Kleine-Budde { 61*1e846c7aSMarc Kleine-Budde const struct mcp251xfd_tx_ring *tx_ring = priv->tx; 62*1e846c7aSMarc Kleine-Budde u32 tef_sta; 63*1e846c7aSMarc Kleine-Budde int err; 64*1e846c7aSMarc Kleine-Budde 65*1e846c7aSMarc Kleine-Budde err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFSTA, &tef_sta); 66*1e846c7aSMarc Kleine-Budde if (err) 67*1e846c7aSMarc Kleine-Budde return err; 68*1e846c7aSMarc Kleine-Budde 69*1e846c7aSMarc Kleine-Budde if (tef_sta & MCP251XFD_REG_TEFSTA_TEFOVIF) { 70*1e846c7aSMarc Kleine-Budde netdev_err(priv->ndev, 71*1e846c7aSMarc Kleine-Budde "Transmit Event FIFO buffer overflow.\n"); 72*1e846c7aSMarc Kleine-Budde return -ENOBUFS; 73*1e846c7aSMarc Kleine-Budde } 74*1e846c7aSMarc Kleine-Budde 75*1e846c7aSMarc Kleine-Budde netdev_info(priv->ndev, 76*1e846c7aSMarc Kleine-Budde "Transmit Event FIFO buffer %s. (seq=0x%08x, tef_tail=0x%08x, tef_head=0x%08x, tx_head=0x%08x).\n", 77*1e846c7aSMarc Kleine-Budde tef_sta & MCP251XFD_REG_TEFSTA_TEFFIF ? 78*1e846c7aSMarc Kleine-Budde "full" : tef_sta & MCP251XFD_REG_TEFSTA_TEFNEIF ? 79*1e846c7aSMarc Kleine-Budde "not empty" : "empty", 80*1e846c7aSMarc Kleine-Budde seq, priv->tef->tail, priv->tef->head, tx_ring->head); 81*1e846c7aSMarc Kleine-Budde 82*1e846c7aSMarc Kleine-Budde /* The Sequence Number in the TEF doesn't match our tef_tail. */ 83*1e846c7aSMarc Kleine-Budde return -EAGAIN; 84*1e846c7aSMarc Kleine-Budde } 85*1e846c7aSMarc Kleine-Budde 86*1e846c7aSMarc Kleine-Budde static int 87*1e846c7aSMarc Kleine-Budde mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, 88*1e846c7aSMarc Kleine-Budde const struct mcp251xfd_hw_tef_obj *hw_tef_obj, 89*1e846c7aSMarc Kleine-Budde unsigned int *frame_len_ptr) 90*1e846c7aSMarc Kleine-Budde { 91*1e846c7aSMarc Kleine-Budde struct net_device_stats *stats = &priv->ndev->stats; 92*1e846c7aSMarc Kleine-Budde struct sk_buff *skb; 93*1e846c7aSMarc Kleine-Budde u32 seq, seq_masked, tef_tail_masked, tef_tail; 94*1e846c7aSMarc Kleine-Budde 95*1e846c7aSMarc Kleine-Budde seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK, 96*1e846c7aSMarc Kleine-Budde hw_tef_obj->flags); 97*1e846c7aSMarc Kleine-Budde 98*1e846c7aSMarc Kleine-Budde /* Use the MCP2517FD mask on the MCP2518FD, too. We only 99*1e846c7aSMarc Kleine-Budde * compare 7 bits, this should be enough to detect 100*1e846c7aSMarc Kleine-Budde * net-yet-completed, i.e. old TEF objects. 101*1e846c7aSMarc Kleine-Budde */ 102*1e846c7aSMarc Kleine-Budde seq_masked = seq & 103*1e846c7aSMarc Kleine-Budde field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); 104*1e846c7aSMarc Kleine-Budde tef_tail_masked = priv->tef->tail & 105*1e846c7aSMarc Kleine-Budde field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); 106*1e846c7aSMarc Kleine-Budde if (seq_masked != tef_tail_masked) 107*1e846c7aSMarc Kleine-Budde return mcp251xfd_handle_tefif_recover(priv, seq); 108*1e846c7aSMarc Kleine-Budde 109*1e846c7aSMarc Kleine-Budde tef_tail = mcp251xfd_get_tef_tail(priv); 110*1e846c7aSMarc Kleine-Budde skb = priv->can.echo_skb[tef_tail]; 111*1e846c7aSMarc Kleine-Budde if (skb) 112*1e846c7aSMarc Kleine-Budde mcp251xfd_skb_set_timestamp(priv, skb, hw_tef_obj->ts); 113*1e846c7aSMarc Kleine-Budde stats->tx_bytes += 114*1e846c7aSMarc Kleine-Budde can_rx_offload_get_echo_skb(&priv->offload, 115*1e846c7aSMarc Kleine-Budde tef_tail, hw_tef_obj->ts, 116*1e846c7aSMarc Kleine-Budde frame_len_ptr); 117*1e846c7aSMarc Kleine-Budde stats->tx_packets++; 118*1e846c7aSMarc Kleine-Budde priv->tef->tail++; 119*1e846c7aSMarc Kleine-Budde 120*1e846c7aSMarc Kleine-Budde return 0; 121*1e846c7aSMarc Kleine-Budde } 122*1e846c7aSMarc Kleine-Budde 123*1e846c7aSMarc Kleine-Budde static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv) 124*1e846c7aSMarc Kleine-Budde { 125*1e846c7aSMarc Kleine-Budde const struct mcp251xfd_tx_ring *tx_ring = priv->tx; 126*1e846c7aSMarc Kleine-Budde unsigned int new_head; 127*1e846c7aSMarc Kleine-Budde u8 chip_tx_tail; 128*1e846c7aSMarc Kleine-Budde int err; 129*1e846c7aSMarc Kleine-Budde 130*1e846c7aSMarc Kleine-Budde err = mcp251xfd_tx_tail_get_from_chip(priv, &chip_tx_tail); 131*1e846c7aSMarc Kleine-Budde if (err) 132*1e846c7aSMarc Kleine-Budde return err; 133*1e846c7aSMarc Kleine-Budde 134*1e846c7aSMarc Kleine-Budde /* chip_tx_tail, is the next TX-Object send by the HW. 135*1e846c7aSMarc Kleine-Budde * The new TEF head must be >= the old head, ... 136*1e846c7aSMarc Kleine-Budde */ 137*1e846c7aSMarc Kleine-Budde new_head = round_down(priv->tef->head, tx_ring->obj_num) + chip_tx_tail; 138*1e846c7aSMarc Kleine-Budde if (new_head <= priv->tef->head) 139*1e846c7aSMarc Kleine-Budde new_head += tx_ring->obj_num; 140*1e846c7aSMarc Kleine-Budde 141*1e846c7aSMarc Kleine-Budde /* ... but it cannot exceed the TX head. */ 142*1e846c7aSMarc Kleine-Budde priv->tef->head = min(new_head, tx_ring->head); 143*1e846c7aSMarc Kleine-Budde 144*1e846c7aSMarc Kleine-Budde return mcp251xfd_check_tef_tail(priv); 145*1e846c7aSMarc Kleine-Budde } 146*1e846c7aSMarc Kleine-Budde 147*1e846c7aSMarc Kleine-Budde static inline int 148*1e846c7aSMarc Kleine-Budde mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv, 149*1e846c7aSMarc Kleine-Budde struct mcp251xfd_hw_tef_obj *hw_tef_obj, 150*1e846c7aSMarc Kleine-Budde const u8 offset, const u8 len) 151*1e846c7aSMarc Kleine-Budde { 152*1e846c7aSMarc Kleine-Budde const struct mcp251xfd_tx_ring *tx_ring = priv->tx; 153*1e846c7aSMarc Kleine-Budde const int val_bytes = regmap_get_val_bytes(priv->map_rx); 154*1e846c7aSMarc Kleine-Budde 155*1e846c7aSMarc Kleine-Budde if (IS_ENABLED(CONFIG_CAN_MCP251XFD_SANITY) && 156*1e846c7aSMarc Kleine-Budde (offset > tx_ring->obj_num || 157*1e846c7aSMarc Kleine-Budde len > tx_ring->obj_num || 158*1e846c7aSMarc Kleine-Budde offset + len > tx_ring->obj_num)) { 159*1e846c7aSMarc Kleine-Budde netdev_err(priv->ndev, 160*1e846c7aSMarc Kleine-Budde "Trying to read too many TEF objects (max=%d, offset=%d, len=%d).\n", 161*1e846c7aSMarc Kleine-Budde tx_ring->obj_num, offset, len); 162*1e846c7aSMarc Kleine-Budde return -ERANGE; 163*1e846c7aSMarc Kleine-Budde } 164*1e846c7aSMarc Kleine-Budde 165*1e846c7aSMarc Kleine-Budde return regmap_bulk_read(priv->map_rx, 166*1e846c7aSMarc Kleine-Budde mcp251xfd_get_tef_obj_addr(offset), 167*1e846c7aSMarc Kleine-Budde hw_tef_obj, 168*1e846c7aSMarc Kleine-Budde sizeof(*hw_tef_obj) / val_bytes * len); 169*1e846c7aSMarc Kleine-Budde } 170*1e846c7aSMarc Kleine-Budde 171*1e846c7aSMarc Kleine-Budde static inline void mcp251xfd_ecc_tefif_successful(struct mcp251xfd_priv *priv) 172*1e846c7aSMarc Kleine-Budde { 173*1e846c7aSMarc Kleine-Budde struct mcp251xfd_ecc *ecc = &priv->ecc; 174*1e846c7aSMarc Kleine-Budde 175*1e846c7aSMarc Kleine-Budde ecc->ecc_stat = 0; 176*1e846c7aSMarc Kleine-Budde } 177*1e846c7aSMarc Kleine-Budde 178*1e846c7aSMarc Kleine-Budde int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) 179*1e846c7aSMarc Kleine-Budde { 180*1e846c7aSMarc Kleine-Budde struct mcp251xfd_hw_tef_obj hw_tef_obj[MCP251XFD_TX_OBJ_NUM_MAX]; 181*1e846c7aSMarc Kleine-Budde unsigned int total_frame_len = 0; 182*1e846c7aSMarc Kleine-Budde u8 tef_tail, len, l; 183*1e846c7aSMarc Kleine-Budde int err, i; 184*1e846c7aSMarc Kleine-Budde 185*1e846c7aSMarc Kleine-Budde err = mcp251xfd_tef_ring_update(priv); 186*1e846c7aSMarc Kleine-Budde if (err) 187*1e846c7aSMarc Kleine-Budde return err; 188*1e846c7aSMarc Kleine-Budde 189*1e846c7aSMarc Kleine-Budde tef_tail = mcp251xfd_get_tef_tail(priv); 190*1e846c7aSMarc Kleine-Budde len = mcp251xfd_get_tef_len(priv); 191*1e846c7aSMarc Kleine-Budde l = mcp251xfd_get_tef_linear_len(priv); 192*1e846c7aSMarc Kleine-Budde err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l); 193*1e846c7aSMarc Kleine-Budde if (err) 194*1e846c7aSMarc Kleine-Budde return err; 195*1e846c7aSMarc Kleine-Budde 196*1e846c7aSMarc Kleine-Budde if (l < len) { 197*1e846c7aSMarc Kleine-Budde err = mcp251xfd_tef_obj_read(priv, &hw_tef_obj[l], 0, len - l); 198*1e846c7aSMarc Kleine-Budde if (err) 199*1e846c7aSMarc Kleine-Budde return err; 200*1e846c7aSMarc Kleine-Budde } 201*1e846c7aSMarc Kleine-Budde 202*1e846c7aSMarc Kleine-Budde for (i = 0; i < len; i++) { 203*1e846c7aSMarc Kleine-Budde unsigned int frame_len = 0; 204*1e846c7aSMarc Kleine-Budde 205*1e846c7aSMarc Kleine-Budde err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len); 206*1e846c7aSMarc Kleine-Budde /* -EAGAIN means the Sequence Number in the TEF 207*1e846c7aSMarc Kleine-Budde * doesn't match our tef_tail. This can happen if we 208*1e846c7aSMarc Kleine-Budde * read the TEF objects too early. Leave loop let the 209*1e846c7aSMarc Kleine-Budde * interrupt handler call us again. 210*1e846c7aSMarc Kleine-Budde */ 211*1e846c7aSMarc Kleine-Budde if (err == -EAGAIN) 212*1e846c7aSMarc Kleine-Budde goto out_netif_wake_queue; 213*1e846c7aSMarc Kleine-Budde if (err) 214*1e846c7aSMarc Kleine-Budde return err; 215*1e846c7aSMarc Kleine-Budde 216*1e846c7aSMarc Kleine-Budde total_frame_len += frame_len; 217*1e846c7aSMarc Kleine-Budde } 218*1e846c7aSMarc Kleine-Budde 219*1e846c7aSMarc Kleine-Budde out_netif_wake_queue: 220*1e846c7aSMarc Kleine-Budde len = i; /* number of handled goods TEFs */ 221*1e846c7aSMarc Kleine-Budde if (len) { 222*1e846c7aSMarc Kleine-Budde struct mcp251xfd_tef_ring *ring = priv->tef; 223*1e846c7aSMarc Kleine-Budde struct mcp251xfd_tx_ring *tx_ring = priv->tx; 224*1e846c7aSMarc Kleine-Budde int offset; 225*1e846c7aSMarc Kleine-Budde 226*1e846c7aSMarc Kleine-Budde /* Increment the TEF FIFO tail pointer 'len' times in 227*1e846c7aSMarc Kleine-Budde * a single SPI message. 228*1e846c7aSMarc Kleine-Budde * 229*1e846c7aSMarc Kleine-Budde * Note: 230*1e846c7aSMarc Kleine-Budde * Calculate offset, so that the SPI transfer ends on 231*1e846c7aSMarc Kleine-Budde * the last message of the uinc_xfer array, which has 232*1e846c7aSMarc Kleine-Budde * "cs_change == 0", to properly deactivate the chip 233*1e846c7aSMarc Kleine-Budde * select. 234*1e846c7aSMarc Kleine-Budde */ 235*1e846c7aSMarc Kleine-Budde offset = ARRAY_SIZE(ring->uinc_xfer) - len; 236*1e846c7aSMarc Kleine-Budde err = spi_sync_transfer(priv->spi, 237*1e846c7aSMarc Kleine-Budde ring->uinc_xfer + offset, len); 238*1e846c7aSMarc Kleine-Budde if (err) 239*1e846c7aSMarc Kleine-Budde return err; 240*1e846c7aSMarc Kleine-Budde 241*1e846c7aSMarc Kleine-Budde tx_ring->tail += len; 242*1e846c7aSMarc Kleine-Budde netdev_completed_queue(priv->ndev, len, total_frame_len); 243*1e846c7aSMarc Kleine-Budde 244*1e846c7aSMarc Kleine-Budde err = mcp251xfd_check_tef_tail(priv); 245*1e846c7aSMarc Kleine-Budde if (err) 246*1e846c7aSMarc Kleine-Budde return err; 247*1e846c7aSMarc Kleine-Budde } 248*1e846c7aSMarc Kleine-Budde 249*1e846c7aSMarc Kleine-Budde mcp251xfd_ecc_tefif_successful(priv); 250*1e846c7aSMarc Kleine-Budde 251*1e846c7aSMarc Kleine-Budde if (mcp251xfd_get_tx_free(priv->tx)) { 252*1e846c7aSMarc Kleine-Budde /* Make sure that anybody stopping the queue after 253*1e846c7aSMarc Kleine-Budde * this sees the new tx_ring->tail. 254*1e846c7aSMarc Kleine-Budde */ 255*1e846c7aSMarc Kleine-Budde smp_mb(); 256*1e846c7aSMarc Kleine-Budde netif_wake_queue(priv->ndev); 257*1e846c7aSMarc Kleine-Budde } 258*1e846c7aSMarc Kleine-Budde 259*1e846c7aSMarc Kleine-Budde return 0; 260*1e846c7aSMarc Kleine-Budde } 261