]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/net/ethernet/chelsio/cxgb4/cxgb4_cudbg.c
4ec322eec68ca277107b60f3eb970dbf33a122e6
[linux.git] / drivers / net / ethernet / chelsio / cxgb4 / cxgb4_cudbg.c
1 /*
2  *  Copyright (C) 2017 Chelsio Communications.  All rights reserved.
3  *
4  *  This program is free software; you can redistribute it and/or modify it
5  *  under the terms and conditions of the GNU General Public License,
6  *  version 2, as published by the Free Software Foundation.
7  *
8  *  This program is distributed in the hope it will be useful, but WITHOUT
9  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  *  more details.
12  *
13  *  The full GNU General Public License is included in this distribution in
14  *  the file called "COPYING".
15  *
16  */
17
18 #include "cxgb4.h"
19 #include "cxgb4_cudbg.h"
20
21 static const struct cxgb4_collect_entity cxgb4_collect_hw_dump[] = {
22         { CUDBG_REG_DUMP, cudbg_collect_reg_dump },
23 };
24
25 static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity)
26 {
27         u32 len = 0;
28
29         switch (entity) {
30         case CUDBG_REG_DUMP:
31                 switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
32                 case CHELSIO_T4:
33                         len = T4_REGMAP_SIZE;
34                         break;
35                 case CHELSIO_T5:
36                 case CHELSIO_T6:
37                         len = T5_REGMAP_SIZE;
38                         break;
39                 default:
40                         break;
41                 }
42                 break;
43         default:
44                 break;
45         }
46
47         return len;
48 }
49
50 u32 cxgb4_get_dump_length(struct adapter *adap, u32 flag)
51 {
52         u32 i, entity;
53         u32 len = 0;
54
55         if (flag & CXGB4_ETH_DUMP_HW) {
56                 for (i = 0; i < ARRAY_SIZE(cxgb4_collect_hw_dump); i++) {
57                         entity = cxgb4_collect_hw_dump[i].entity;
58                         len += cxgb4_get_entity_length(adap, entity);
59                 }
60         }
61
62         return len;
63 }
64
65 static void cxgb4_cudbg_collect_entity(struct cudbg_init *pdbg_init,
66                                        struct cudbg_buffer *dbg_buff,
67                                        const struct cxgb4_collect_entity *e_arr,
68                                        u32 arr_size, void *buf, u32 *tot_size)
69 {
70         struct adapter *adap = pdbg_init->adap;
71         struct cudbg_error cudbg_err = { 0 };
72         struct cudbg_entity_hdr *entity_hdr;
73         u32 entity_size, i;
74         u32 total_size = 0;
75         int ret;
76
77         for (i = 0; i < arr_size; i++) {
78                 const struct cxgb4_collect_entity *e = &e_arr[i];
79
80                 /* Skip entities that won't fit in output buffer */
81                 entity_size = cxgb4_get_entity_length(adap, e->entity);
82                 if (entity_size >
83                     pdbg_init->outbuf_size - *tot_size - total_size)
84                         continue;
85
86                 entity_hdr = cudbg_get_entity_hdr(buf, e->entity);
87                 entity_hdr->entity_type = e->entity;
88                 entity_hdr->start_offset = dbg_buff->offset;
89                 memset(&cudbg_err, 0, sizeof(struct cudbg_error));
90                 ret = e->collect_cb(pdbg_init, dbg_buff, &cudbg_err);
91                 if (ret) {
92                         entity_hdr->size = 0;
93                         dbg_buff->offset = entity_hdr->start_offset;
94                 } else {
95                         cudbg_align_debug_buffer(dbg_buff, entity_hdr);
96                 }
97
98                 /* Log error and continue with next entity */
99                 if (cudbg_err.sys_err)
100                         ret = CUDBG_SYSTEM_ERROR;
101
102                 entity_hdr->hdr_flags = ret;
103                 entity_hdr->sys_err = cudbg_err.sys_err;
104                 entity_hdr->sys_warn = cudbg_err.sys_warn;
105                 total_size += entity_hdr->size;
106         }
107
108         *tot_size += total_size;
109 }
110
111 int cxgb4_cudbg_collect(struct adapter *adap, void *buf, u32 *buf_size,
112                         u32 flag)
113 {
114         struct cudbg_init cudbg_init = { 0 };
115         struct cudbg_buffer dbg_buff = { 0 };
116         u32 size, min_size, total_size = 0;
117         struct cudbg_hdr *cudbg_hdr;
118
119         size = *buf_size;
120
121         cudbg_init.adap = adap;
122         cudbg_init.outbuf = buf;
123         cudbg_init.outbuf_size = size;
124
125         dbg_buff.data = buf;
126         dbg_buff.size = size;
127         dbg_buff.offset = 0;
128
129         cudbg_hdr = (struct cudbg_hdr *)buf;
130         cudbg_hdr->signature = CUDBG_SIGNATURE;
131         cudbg_hdr->hdr_len = sizeof(struct cudbg_hdr);
132         cudbg_hdr->major_ver = CUDBG_MAJOR_VERSION;
133         cudbg_hdr->minor_ver = CUDBG_MINOR_VERSION;
134         cudbg_hdr->max_entities = CUDBG_MAX_ENTITY;
135         cudbg_hdr->chip_ver = adap->params.chip;
136         cudbg_hdr->dump_type = CUDBG_DUMP_TYPE_MINI;
137         cudbg_hdr->compress_type = CUDBG_COMPRESSION_NONE;
138
139         min_size = sizeof(struct cudbg_hdr) +
140                    sizeof(struct cudbg_entity_hdr) *
141                    cudbg_hdr->max_entities;
142         if (size < min_size)
143                 return -ENOMEM;
144
145         dbg_buff.offset += min_size;
146         total_size = dbg_buff.offset;
147
148         if (flag & CXGB4_ETH_DUMP_HW)
149                 cxgb4_cudbg_collect_entity(&cudbg_init, &dbg_buff,
150                                            cxgb4_collect_hw_dump,
151                                            ARRAY_SIZE(cxgb4_collect_hw_dump),
152                                            buf,
153                                            &total_size);
154
155         cudbg_hdr->data_len = total_size;
156         *buf_size = total_size;
157         return 0;
158 }
159
160 void cxgb4_init_ethtool_dump(struct adapter *adapter)
161 {
162         adapter->eth_dump.flag = CXGB4_ETH_DUMP_NONE;
163         adapter->eth_dump.version = adapter->params.fw_vers;
164         adapter->eth_dump.len = 0;
165 }