1*e0ab3dd5SMarc Kleine-Budde // SPDX-License-Identifier: GPL-2.0 2*e0ab3dd5SMarc Kleine-Budde // 3*e0ab3dd5SMarc Kleine-Budde // mcp251xfd - Microchip MCP251xFD Family CAN controller driver 4*e0ab3dd5SMarc Kleine-Budde // 5*e0ab3dd5SMarc Kleine-Budde // Copyright (c) 2020, 2021 Pengutronix, 6*e0ab3dd5SMarc Kleine-Budde // Marc Kleine-Budde <kernel@pengutronix.de> 7*e0ab3dd5SMarc Kleine-Budde // Copyright (C) 2015-2018 Etnaviv Project 8*e0ab3dd5SMarc Kleine-Budde // 9*e0ab3dd5SMarc Kleine-Budde 10*e0ab3dd5SMarc Kleine-Budde #include <linux/devcoredump.h> 11*e0ab3dd5SMarc Kleine-Budde 12*e0ab3dd5SMarc Kleine-Budde #include "mcp251xfd.h" 13*e0ab3dd5SMarc Kleine-Budde #include "mcp251xfd-dump.h" 14*e0ab3dd5SMarc Kleine-Budde 15*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_iter { 16*e0ab3dd5SMarc Kleine-Budde void *start; 17*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_object_header *hdr; 18*e0ab3dd5SMarc Kleine-Budde void *data; 19*e0ab3dd5SMarc Kleine-Budde }; 20*e0ab3dd5SMarc Kleine-Budde 21*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_reg_space { 22*e0ab3dd5SMarc Kleine-Budde u16 base; 23*e0ab3dd5SMarc Kleine-Budde u16 size; 24*e0ab3dd5SMarc Kleine-Budde }; 25*e0ab3dd5SMarc Kleine-Budde 26*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_ring { 27*e0ab3dd5SMarc Kleine-Budde enum mcp251xfd_dump_object_ring_key key; 28*e0ab3dd5SMarc Kleine-Budde u32 val; 29*e0ab3dd5SMarc Kleine-Budde }; 30*e0ab3dd5SMarc Kleine-Budde 31*e0ab3dd5SMarc Kleine-Budde static const struct mcp251xfd_dump_reg_space mcp251xfd_dump_reg_space[] = { 32*e0ab3dd5SMarc Kleine-Budde { 33*e0ab3dd5SMarc Kleine-Budde .base = MCP251XFD_REG_CON, 34*e0ab3dd5SMarc Kleine-Budde .size = MCP251XFD_REG_FLTOBJ(32) - MCP251XFD_REG_CON, 35*e0ab3dd5SMarc Kleine-Budde }, { 36*e0ab3dd5SMarc Kleine-Budde .base = MCP251XFD_RAM_START, 37*e0ab3dd5SMarc Kleine-Budde .size = MCP251XFD_RAM_SIZE, 38*e0ab3dd5SMarc Kleine-Budde }, { 39*e0ab3dd5SMarc Kleine-Budde .base = MCP251XFD_REG_OSC, 40*e0ab3dd5SMarc Kleine-Budde .size = MCP251XFD_REG_DEVID - MCP251XFD_REG_OSC, 41*e0ab3dd5SMarc Kleine-Budde }, 42*e0ab3dd5SMarc Kleine-Budde }; 43*e0ab3dd5SMarc Kleine-Budde 44*e0ab3dd5SMarc Kleine-Budde static void mcp251xfd_dump_header(struct mcp251xfd_dump_iter *iter, 45*e0ab3dd5SMarc Kleine-Budde enum mcp251xfd_dump_object_type object_type, 46*e0ab3dd5SMarc Kleine-Budde const void *data_end) 47*e0ab3dd5SMarc Kleine-Budde { 48*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_object_header *hdr = iter->hdr; 49*e0ab3dd5SMarc Kleine-Budde unsigned int len; 50*e0ab3dd5SMarc Kleine-Budde 51*e0ab3dd5SMarc Kleine-Budde len = data_end - iter->data; 52*e0ab3dd5SMarc Kleine-Budde if (!len) 53*e0ab3dd5SMarc Kleine-Budde return; 54*e0ab3dd5SMarc Kleine-Budde 55*e0ab3dd5SMarc Kleine-Budde hdr->magic = cpu_to_le32(MCP251XFD_DUMP_MAGIC); 56*e0ab3dd5SMarc Kleine-Budde hdr->type = cpu_to_le32(object_type); 57*e0ab3dd5SMarc Kleine-Budde hdr->offset = cpu_to_le32(iter->data - iter->start); 58*e0ab3dd5SMarc Kleine-Budde hdr->len = cpu_to_le32(len); 59*e0ab3dd5SMarc Kleine-Budde 60*e0ab3dd5SMarc Kleine-Budde iter->hdr++; 61*e0ab3dd5SMarc Kleine-Budde iter->data += len; 62*e0ab3dd5SMarc Kleine-Budde } 63*e0ab3dd5SMarc Kleine-Budde 64*e0ab3dd5SMarc Kleine-Budde static void mcp251xfd_dump_registers(const struct mcp251xfd_priv *priv, 65*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_iter *iter) 66*e0ab3dd5SMarc Kleine-Budde { 67*e0ab3dd5SMarc Kleine-Budde const int val_bytes = regmap_get_val_bytes(priv->map_rx); 68*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_object_reg *reg = iter->data; 69*e0ab3dd5SMarc Kleine-Budde unsigned int i, j; 70*e0ab3dd5SMarc Kleine-Budde int err; 71*e0ab3dd5SMarc Kleine-Budde 72*e0ab3dd5SMarc Kleine-Budde for (i = 0; i < ARRAY_SIZE(mcp251xfd_dump_reg_space); i++) { 73*e0ab3dd5SMarc Kleine-Budde const struct mcp251xfd_dump_reg_space *reg_space; 74*e0ab3dd5SMarc Kleine-Budde void *buf; 75*e0ab3dd5SMarc Kleine-Budde 76*e0ab3dd5SMarc Kleine-Budde reg_space = &mcp251xfd_dump_reg_space[i]; 77*e0ab3dd5SMarc Kleine-Budde 78*e0ab3dd5SMarc Kleine-Budde buf = kmalloc(reg_space->size, GFP_KERNEL); 79*e0ab3dd5SMarc Kleine-Budde if (!buf) 80*e0ab3dd5SMarc Kleine-Budde goto out; 81*e0ab3dd5SMarc Kleine-Budde 82*e0ab3dd5SMarc Kleine-Budde err = regmap_bulk_read(priv->map_reg, reg_space->base, 83*e0ab3dd5SMarc Kleine-Budde buf, reg_space->size / val_bytes); 84*e0ab3dd5SMarc Kleine-Budde if (err) { 85*e0ab3dd5SMarc Kleine-Budde kfree(buf); 86*e0ab3dd5SMarc Kleine-Budde continue; 87*e0ab3dd5SMarc Kleine-Budde } 88*e0ab3dd5SMarc Kleine-Budde 89*e0ab3dd5SMarc Kleine-Budde for (j = 0; j < reg_space->size; j += sizeof(u32), reg++) { 90*e0ab3dd5SMarc Kleine-Budde reg->reg = cpu_to_le32(reg_space->base + j); 91*e0ab3dd5SMarc Kleine-Budde reg->val = cpu_to_le32p(buf + j); 92*e0ab3dd5SMarc Kleine-Budde } 93*e0ab3dd5SMarc Kleine-Budde 94*e0ab3dd5SMarc Kleine-Budde kfree(buf); 95*e0ab3dd5SMarc Kleine-Budde } 96*e0ab3dd5SMarc Kleine-Budde 97*e0ab3dd5SMarc Kleine-Budde out: 98*e0ab3dd5SMarc Kleine-Budde mcp251xfd_dump_header(iter, MCP251XFD_DUMP_OBJECT_TYPE_REG, reg); 99*e0ab3dd5SMarc Kleine-Budde } 100*e0ab3dd5SMarc Kleine-Budde 101*e0ab3dd5SMarc Kleine-Budde static void mcp251xfd_dump_ring(struct mcp251xfd_dump_iter *iter, 102*e0ab3dd5SMarc Kleine-Budde enum mcp251xfd_dump_object_type object_type, 103*e0ab3dd5SMarc Kleine-Budde const struct mcp251xfd_dump_ring *dump_ring, 104*e0ab3dd5SMarc Kleine-Budde unsigned int len) 105*e0ab3dd5SMarc Kleine-Budde { 106*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_object_reg *reg = iter->data; 107*e0ab3dd5SMarc Kleine-Budde unsigned int i; 108*e0ab3dd5SMarc Kleine-Budde 109*e0ab3dd5SMarc Kleine-Budde for (i = 0; i < len; i++, reg++) { 110*e0ab3dd5SMarc Kleine-Budde reg->reg = cpu_to_le32(dump_ring[i].key); 111*e0ab3dd5SMarc Kleine-Budde reg->val = cpu_to_le32(dump_ring[i].val); 112*e0ab3dd5SMarc Kleine-Budde } 113*e0ab3dd5SMarc Kleine-Budde 114*e0ab3dd5SMarc Kleine-Budde mcp251xfd_dump_header(iter, object_type, reg); 115*e0ab3dd5SMarc Kleine-Budde } 116*e0ab3dd5SMarc Kleine-Budde 117*e0ab3dd5SMarc Kleine-Budde static void mcp251xfd_dump_tef_ring(const struct mcp251xfd_priv *priv, 118*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_iter *iter) 119*e0ab3dd5SMarc Kleine-Budde { 120*e0ab3dd5SMarc Kleine-Budde const struct mcp251xfd_tef_ring *tef = priv->tef; 121*e0ab3dd5SMarc Kleine-Budde const struct mcp251xfd_tx_ring *tx = priv->tx; 122*e0ab3dd5SMarc Kleine-Budde const struct mcp251xfd_dump_ring dump_ring[] = { 123*e0ab3dd5SMarc Kleine-Budde { 124*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_HEAD, 125*e0ab3dd5SMarc Kleine-Budde .val = tef->head, 126*e0ab3dd5SMarc Kleine-Budde }, { 127*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_TAIL, 128*e0ab3dd5SMarc Kleine-Budde .val = tef->tail, 129*e0ab3dd5SMarc Kleine-Budde }, { 130*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_BASE, 131*e0ab3dd5SMarc Kleine-Budde .val = 0, 132*e0ab3dd5SMarc Kleine-Budde }, { 133*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_NR, 134*e0ab3dd5SMarc Kleine-Budde .val = 0, 135*e0ab3dd5SMarc Kleine-Budde }, { 136*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_FIFO_NR, 137*e0ab3dd5SMarc Kleine-Budde .val = 0, 138*e0ab3dd5SMarc Kleine-Budde }, { 139*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_NUM, 140*e0ab3dd5SMarc Kleine-Budde .val = tx->obj_num, 141*e0ab3dd5SMarc Kleine-Budde }, { 142*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_SIZE, 143*e0ab3dd5SMarc Kleine-Budde .val = sizeof(struct mcp251xfd_hw_tef_obj), 144*e0ab3dd5SMarc Kleine-Budde }, 145*e0ab3dd5SMarc Kleine-Budde }; 146*e0ab3dd5SMarc Kleine-Budde 147*e0ab3dd5SMarc Kleine-Budde mcp251xfd_dump_ring(iter, MCP251XFD_DUMP_OBJECT_TYPE_TEF, 148*e0ab3dd5SMarc Kleine-Budde dump_ring, ARRAY_SIZE(dump_ring)); 149*e0ab3dd5SMarc Kleine-Budde } 150*e0ab3dd5SMarc Kleine-Budde 151*e0ab3dd5SMarc Kleine-Budde static void mcp251xfd_dump_rx_ring_one(const struct mcp251xfd_priv *priv, 152*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_iter *iter, 153*e0ab3dd5SMarc Kleine-Budde const struct mcp251xfd_rx_ring *rx) 154*e0ab3dd5SMarc Kleine-Budde { 155*e0ab3dd5SMarc Kleine-Budde const struct mcp251xfd_dump_ring dump_ring[] = { 156*e0ab3dd5SMarc Kleine-Budde { 157*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_HEAD, 158*e0ab3dd5SMarc Kleine-Budde .val = rx->head, 159*e0ab3dd5SMarc Kleine-Budde }, { 160*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_TAIL, 161*e0ab3dd5SMarc Kleine-Budde .val = rx->tail, 162*e0ab3dd5SMarc Kleine-Budde }, { 163*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_BASE, 164*e0ab3dd5SMarc Kleine-Budde .val = rx->base, 165*e0ab3dd5SMarc Kleine-Budde }, { 166*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_NR, 167*e0ab3dd5SMarc Kleine-Budde .val = rx->nr, 168*e0ab3dd5SMarc Kleine-Budde }, { 169*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_FIFO_NR, 170*e0ab3dd5SMarc Kleine-Budde .val = rx->fifo_nr, 171*e0ab3dd5SMarc Kleine-Budde }, { 172*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_NUM, 173*e0ab3dd5SMarc Kleine-Budde .val = rx->obj_num, 174*e0ab3dd5SMarc Kleine-Budde }, { 175*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_SIZE, 176*e0ab3dd5SMarc Kleine-Budde .val = rx->obj_size, 177*e0ab3dd5SMarc Kleine-Budde }, 178*e0ab3dd5SMarc Kleine-Budde }; 179*e0ab3dd5SMarc Kleine-Budde 180*e0ab3dd5SMarc Kleine-Budde mcp251xfd_dump_ring(iter, MCP251XFD_DUMP_OBJECT_TYPE_RX, 181*e0ab3dd5SMarc Kleine-Budde dump_ring, ARRAY_SIZE(dump_ring)); 182*e0ab3dd5SMarc Kleine-Budde } 183*e0ab3dd5SMarc Kleine-Budde 184*e0ab3dd5SMarc Kleine-Budde static void mcp251xfd_dump_rx_ring(const struct mcp251xfd_priv *priv, 185*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_iter *iter) 186*e0ab3dd5SMarc Kleine-Budde { 187*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_rx_ring *rx_ring; 188*e0ab3dd5SMarc Kleine-Budde unsigned int i; 189*e0ab3dd5SMarc Kleine-Budde 190*e0ab3dd5SMarc Kleine-Budde mcp251xfd_for_each_rx_ring(priv, rx_ring, i) 191*e0ab3dd5SMarc Kleine-Budde mcp251xfd_dump_rx_ring_one(priv, iter, rx_ring); 192*e0ab3dd5SMarc Kleine-Budde } 193*e0ab3dd5SMarc Kleine-Budde 194*e0ab3dd5SMarc Kleine-Budde static void mcp251xfd_dump_tx_ring(const struct mcp251xfd_priv *priv, 195*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_iter *iter) 196*e0ab3dd5SMarc Kleine-Budde { 197*e0ab3dd5SMarc Kleine-Budde const struct mcp251xfd_tx_ring *tx = priv->tx; 198*e0ab3dd5SMarc Kleine-Budde const struct mcp251xfd_dump_ring dump_ring[] = { 199*e0ab3dd5SMarc Kleine-Budde { 200*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_HEAD, 201*e0ab3dd5SMarc Kleine-Budde .val = tx->head, 202*e0ab3dd5SMarc Kleine-Budde }, { 203*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_TAIL, 204*e0ab3dd5SMarc Kleine-Budde .val = tx->tail, 205*e0ab3dd5SMarc Kleine-Budde }, { 206*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_BASE, 207*e0ab3dd5SMarc Kleine-Budde .val = tx->base, 208*e0ab3dd5SMarc Kleine-Budde }, { 209*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_NR, 210*e0ab3dd5SMarc Kleine-Budde .val = 0, 211*e0ab3dd5SMarc Kleine-Budde }, { 212*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_FIFO_NR, 213*e0ab3dd5SMarc Kleine-Budde .val = MCP251XFD_TX_FIFO, 214*e0ab3dd5SMarc Kleine-Budde }, { 215*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_NUM, 216*e0ab3dd5SMarc Kleine-Budde .val = tx->obj_num, 217*e0ab3dd5SMarc Kleine-Budde }, { 218*e0ab3dd5SMarc Kleine-Budde .key = MCP251XFD_DUMP_OBJECT_RING_KEY_OBJ_SIZE, 219*e0ab3dd5SMarc Kleine-Budde .val = tx->obj_size, 220*e0ab3dd5SMarc Kleine-Budde }, 221*e0ab3dd5SMarc Kleine-Budde }; 222*e0ab3dd5SMarc Kleine-Budde 223*e0ab3dd5SMarc Kleine-Budde mcp251xfd_dump_ring(iter, MCP251XFD_DUMP_OBJECT_TYPE_TX, 224*e0ab3dd5SMarc Kleine-Budde dump_ring, ARRAY_SIZE(dump_ring)); 225*e0ab3dd5SMarc Kleine-Budde } 226*e0ab3dd5SMarc Kleine-Budde 227*e0ab3dd5SMarc Kleine-Budde static void mcp251xfd_dump_end(const struct mcp251xfd_priv *priv, 228*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_iter *iter) 229*e0ab3dd5SMarc Kleine-Budde { 230*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_object_header *hdr = iter->hdr; 231*e0ab3dd5SMarc Kleine-Budde 232*e0ab3dd5SMarc Kleine-Budde hdr->magic = cpu_to_le32(MCP251XFD_DUMP_MAGIC); 233*e0ab3dd5SMarc Kleine-Budde hdr->type = cpu_to_le32(MCP251XFD_DUMP_OBJECT_TYPE_END); 234*e0ab3dd5SMarc Kleine-Budde hdr->offset = cpu_to_le32(0); 235*e0ab3dd5SMarc Kleine-Budde hdr->len = cpu_to_le32(0); 236*e0ab3dd5SMarc Kleine-Budde 237*e0ab3dd5SMarc Kleine-Budde /* provoke NULL pointer access, if used after END object */ 238*e0ab3dd5SMarc Kleine-Budde iter->hdr = NULL; 239*e0ab3dd5SMarc Kleine-Budde } 240*e0ab3dd5SMarc Kleine-Budde 241*e0ab3dd5SMarc Kleine-Budde void mcp251xfd_dump(const struct mcp251xfd_priv *priv) 242*e0ab3dd5SMarc Kleine-Budde { 243*e0ab3dd5SMarc Kleine-Budde struct mcp251xfd_dump_iter iter; 244*e0ab3dd5SMarc Kleine-Budde unsigned int rings_num, obj_num; 245*e0ab3dd5SMarc Kleine-Budde unsigned int file_size = 0; 246*e0ab3dd5SMarc Kleine-Budde unsigned int i; 247*e0ab3dd5SMarc Kleine-Budde 248*e0ab3dd5SMarc Kleine-Budde /* register space + end marker */ 249*e0ab3dd5SMarc Kleine-Budde obj_num = 2; 250*e0ab3dd5SMarc Kleine-Budde 251*e0ab3dd5SMarc Kleine-Budde /* register space */ 252*e0ab3dd5SMarc Kleine-Budde for (i = 0; i < ARRAY_SIZE(mcp251xfd_dump_reg_space); i++) 253*e0ab3dd5SMarc Kleine-Budde file_size += mcp251xfd_dump_reg_space[i].size / sizeof(u32) * 254*e0ab3dd5SMarc Kleine-Budde sizeof(struct mcp251xfd_dump_object_reg); 255*e0ab3dd5SMarc Kleine-Budde 256*e0ab3dd5SMarc Kleine-Budde /* TEF ring, RX ring, TX rings */ 257*e0ab3dd5SMarc Kleine-Budde rings_num = 1 + priv->rx_ring_num + 1; 258*e0ab3dd5SMarc Kleine-Budde obj_num += rings_num; 259*e0ab3dd5SMarc Kleine-Budde file_size += rings_num * __MCP251XFD_DUMP_OBJECT_RING_KEY_MAX * 260*e0ab3dd5SMarc Kleine-Budde sizeof(struct mcp251xfd_dump_object_reg); 261*e0ab3dd5SMarc Kleine-Budde 262*e0ab3dd5SMarc Kleine-Budde /* size of the headers */ 263*e0ab3dd5SMarc Kleine-Budde file_size += sizeof(*iter.hdr) * obj_num; 264*e0ab3dd5SMarc Kleine-Budde 265*e0ab3dd5SMarc Kleine-Budde /* allocate the file in vmalloc memory, it's likely to be big */ 266*e0ab3dd5SMarc Kleine-Budde iter.start = __vmalloc(file_size, GFP_KERNEL | __GFP_NOWARN | 267*e0ab3dd5SMarc Kleine-Budde __GFP_ZERO | __GFP_NORETRY); 268*e0ab3dd5SMarc Kleine-Budde if (!iter.start) { 269*e0ab3dd5SMarc Kleine-Budde netdev_warn(priv->ndev, "Failed to allocate devcoredump file.\n"); 270*e0ab3dd5SMarc Kleine-Budde return; 271*e0ab3dd5SMarc Kleine-Budde } 272*e0ab3dd5SMarc Kleine-Budde 273*e0ab3dd5SMarc Kleine-Budde /* point the data member after the headers */ 274*e0ab3dd5SMarc Kleine-Budde iter.hdr = iter.start; 275*e0ab3dd5SMarc Kleine-Budde iter.data = &iter.hdr[obj_num]; 276*e0ab3dd5SMarc Kleine-Budde 277*e0ab3dd5SMarc Kleine-Budde mcp251xfd_dump_registers(priv, &iter); 278*e0ab3dd5SMarc Kleine-Budde mcp251xfd_dump_tef_ring(priv, &iter); 279*e0ab3dd5SMarc Kleine-Budde mcp251xfd_dump_rx_ring(priv, &iter); 280*e0ab3dd5SMarc Kleine-Budde mcp251xfd_dump_tx_ring(priv, &iter); 281*e0ab3dd5SMarc Kleine-Budde mcp251xfd_dump_end(priv, &iter); 282*e0ab3dd5SMarc Kleine-Budde 283*e0ab3dd5SMarc Kleine-Budde dev_coredumpv(&priv->spi->dev, iter.start, 284*e0ab3dd5SMarc Kleine-Budde iter.data - iter.start, GFP_KERNEL); 285*e0ab3dd5SMarc Kleine-Budde } 286