LCOV - code coverage report
Current view: top level - drivers/net/qede - qede_regs.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 133 0.0 %
Date: 2025-01-02 22:41:34 Functions: 0 5 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 30 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright (c) 2020 Marvell Semiconductor Inc.
       3                 :            :  * All rights reserved.
       4                 :            :  * www.marvell.com
       5                 :            :  */
       6                 :            : 
       7                 :            : #include <stdio.h>
       8                 :            : #include <stdlib.h>
       9                 :            : #include <fcntl.h>
      10                 :            : #include <time.h>
      11                 :            : #include <rte_ethdev.h>
      12                 :            : #include "base/bcm_osal.h"
      13                 :            : #include "qede_ethdev.h"
      14                 :            : 
      15                 :            : int
      16                 :          0 : qede_get_regs_len(struct qede_dev *qdev)
      17                 :            : {
      18                 :          0 :         struct ecore_dev *edev = &qdev->edev;
      19                 :            :         int cur_engine, num_of_hwfns, regs_len = 0;
      20                 :            :         uint8_t org_engine;
      21                 :            : 
      22         [ #  # ]:          0 :         if (IS_VF(edev))
      23                 :            :                 return 0;
      24                 :            : 
      25   [ #  #  #  # ]:          0 :         if (qdev->ops && qdev->ops->common) {
      26                 :          0 :                 num_of_hwfns = qdev->dev_info.common.num_hwfns;
      27                 :          0 :                 org_engine = qdev->ops->common->dbg_get_debug_engine(edev);
      28         [ #  # ]:          0 :                 for (cur_engine = 0; cur_engine < num_of_hwfns; cur_engine++) {
      29                 :            :                         /* compute required buffer size for idle_chks and
      30                 :            :                          * grcDump for each hw function
      31                 :            :                          */
      32                 :          0 :                         DP_NOTICE(edev, false,
      33                 :            :                                 "Calculating idle_chk and grcdump register length for current engine\n");
      34                 :          0 :                         qdev->ops->common->dbg_set_debug_engine(edev,
      35                 :            :                                                                 cur_engine);
      36                 :          0 :                         regs_len += REGDUMP_HEADER_SIZE +
      37                 :          0 :                                 qdev->ops->common->dbg_idle_chk_size(edev) +
      38                 :          0 :                                 REGDUMP_HEADER_SIZE +
      39                 :          0 :                                 qdev->ops->common->dbg_idle_chk_size(edev) +
      40                 :          0 :                                 REGDUMP_HEADER_SIZE +
      41                 :          0 :                                 qdev->ops->common->dbg_grc_size(edev) +
      42                 :          0 :                                 REGDUMP_HEADER_SIZE +
      43                 :          0 :                                 qdev->ops->common->dbg_reg_fifo_size(edev) +
      44                 :          0 :                                 REGDUMP_HEADER_SIZE +
      45                 :          0 :                                 qdev->ops->common->dbg_protection_override_size(edev) +
      46                 :          0 :                                 REGDUMP_HEADER_SIZE +
      47                 :          0 :                                 qdev->ops->common->dbg_igu_fifo_size(edev) +
      48                 :          0 :                                 REGDUMP_HEADER_SIZE +
      49                 :          0 :                                 qdev->ops->common->dbg_fw_asserts_size(edev);
      50                 :            :                 }
      51                 :            :                 /* compute required buffer size for mcp trace and add it to the
      52                 :            :                  * total required buffer size
      53                 :            :                  */
      54                 :          0 :                 regs_len += REGDUMP_HEADER_SIZE +
      55                 :          0 :                             qdev->ops->common->dbg_mcp_trace_size(edev);
      56                 :            : 
      57                 :          0 :                 qdev->ops->common->dbg_set_debug_engine(edev, org_engine);
      58                 :            :         }
      59                 :          0 :         DP_NOTICE(edev, false, "Total length = %u\n", regs_len);
      60                 :            : 
      61                 :          0 :         return regs_len;
      62                 :            : }
      63                 :            : 
      64                 :            : static uint32_t
      65                 :            : qede_calc_regdump_header(enum debug_print_features feature, int engine,
      66                 :            :                          uint32_t feature_size, uint8_t omit_engine)
      67                 :            : {
      68                 :            :         /* insert the engine, feature and mode inside the header and
      69                 :            :          * combine it with feature size
      70                 :            :          */
      71                 :          0 :         return (feature_size | (feature << REGDUMP_HEADER_FEATURE_SHIFT) |
      72                 :          0 :                 (omit_engine << REGDUMP_HEADER_OMIT_ENGINE_SHIFT) |
      73                 :          0 :                 (engine << REGDUMP_HEADER_ENGINE_SHIFT));
      74                 :            : }
      75                 :            : 
      76                 :          0 : int qede_get_regs(struct rte_eth_dev *eth_dev, struct rte_dev_reg_info *regs)
      77                 :            : {
      78                 :          0 :         struct qede_dev *qdev = eth_dev->data->dev_private;
      79                 :          0 :         struct ecore_dev *edev = &qdev->edev;
      80                 :          0 :         uint32_t *buffer = regs->data;
      81                 :            :         int cur_engine, num_of_hwfns;
      82                 :            :         /* '1' tells the parser to omit the engine number in the output files */
      83                 :            :         uint8_t omit_engine = 0;
      84                 :            :         uint8_t org_engine;
      85                 :            :         uint32_t feature_size;
      86                 :            :         uint32_t offset = 0;
      87                 :            : 
      88         [ #  # ]:          0 :         if (IS_VF(edev))
      89                 :            :                 return -ENOTSUP;
      90                 :            : 
      91         [ #  # ]:          0 :         if (buffer == NULL) {
      92                 :          0 :                 regs->length = qede_get_regs_len(qdev);
      93                 :          0 :                 regs->width =  sizeof(uint32_t);
      94                 :          0 :                 DP_INFO(edev, "Length %u\n", regs->length);
      95                 :          0 :                 return 0;
      96                 :            :         }
      97                 :            : 
      98         [ #  # ]:          0 :         memset(buffer, 0, regs->length);
      99                 :          0 :         num_of_hwfns = qdev->dev_info.common.num_hwfns;
     100         [ #  # ]:          0 :         if (num_of_hwfns == 1)
     101                 :            :                 omit_engine = 1;
     102                 :            : 
     103                 :          0 :         OSAL_MUTEX_ACQUIRE(&edev->dbg_lock);
     104                 :            : 
     105                 :          0 :         org_engine = qdev->ops->common->dbg_get_debug_engine(edev);
     106         [ #  # ]:          0 :         for (cur_engine = 0; cur_engine < num_of_hwfns; cur_engine++) {
     107                 :            :                 /* collect idle_chks and grcDump for each hw function */
     108                 :          0 :                 DP_NOTICE(edev, false, "obtaining idle_chk and grcdump for current engine\n");
     109                 :          0 :                 qdev->ops->common->dbg_set_debug_engine(edev, cur_engine);
     110                 :            : 
     111                 :            :                 /* first idle_chk */
     112                 :          0 :                 qdev->ops->common->dbg_idle_chk(edev, (uint8_t *)buffer +
     113                 :          0 :                         offset + REGDUMP_HEADER_SIZE, &feature_size);
     114                 :          0 :                 *(uint32_t *)((uint8_t *)buffer + offset) =
     115                 :          0 :                         qede_calc_regdump_header(IDLE_CHK, cur_engine,
     116                 :            :                                                  feature_size, omit_engine);
     117                 :          0 :                 offset += (feature_size + REGDUMP_HEADER_SIZE);
     118                 :          0 :                 DP_NOTICE(edev, false, "Idle Check1 feature_size %u\n",
     119                 :            :                           feature_size);
     120                 :            : 
     121                 :            :                 /* second idle_chk */
     122                 :          0 :                 qdev->ops->common->dbg_idle_chk(edev, (uint8_t *)buffer +
     123                 :          0 :                         offset + REGDUMP_HEADER_SIZE, &feature_size);
     124                 :          0 :                 *(uint32_t *)((uint8_t *)buffer + offset) =
     125                 :          0 :                         qede_calc_regdump_header(IDLE_CHK, cur_engine,
     126                 :            :                                                  feature_size, omit_engine);
     127                 :          0 :                 offset += (feature_size + REGDUMP_HEADER_SIZE);
     128                 :          0 :                 DP_NOTICE(edev, false, "Idle Check2 feature_size %u\n",
     129                 :            :                           feature_size);
     130                 :            : 
     131                 :            :                 /* reg_fifo dump */
     132                 :          0 :                 qdev->ops->common->dbg_reg_fifo(edev, (uint8_t *)buffer +
     133                 :          0 :                         offset + REGDUMP_HEADER_SIZE, &feature_size);
     134                 :          0 :                 *(uint32_t *)((uint8_t *)buffer + offset) =
     135                 :          0 :                         qede_calc_regdump_header(REG_FIFO, cur_engine,
     136                 :            :                                                  feature_size, omit_engine);
     137                 :          0 :                 offset += (feature_size + REGDUMP_HEADER_SIZE);
     138                 :          0 :                 DP_NOTICE(edev, false, "Reg fifo feature_size %u\n",
     139                 :            :                           feature_size);
     140                 :            : 
     141                 :            :                 /* igu_fifo dump */
     142                 :          0 :                 qdev->ops->common->dbg_igu_fifo(edev, (uint8_t *)buffer +
     143                 :          0 :                         offset + REGDUMP_HEADER_SIZE, &feature_size);
     144                 :          0 :                 *(uint32_t *)((uint8_t *)buffer + offset) =
     145                 :          0 :                         qede_calc_regdump_header(IGU_FIFO, cur_engine,
     146                 :            :                                                  feature_size, omit_engine);
     147                 :          0 :                 offset += (feature_size + REGDUMP_HEADER_SIZE);
     148                 :          0 :                 DP_NOTICE(edev, false, "IGU fifo feature_size %u\n",
     149                 :            :                           feature_size);
     150                 :            : 
     151                 :            :                 /* protection_override dump */
     152                 :          0 :                 qdev->ops->common->dbg_protection_override(edev,
     153                 :            :                                                            (uint8_t *)buffer +
     154                 :          0 :                         offset + REGDUMP_HEADER_SIZE, &feature_size);
     155                 :          0 :                 *(uint32_t *)((uint8_t *)buffer + offset) =
     156                 :          0 :                        qede_calc_regdump_header(PROTECTION_OVERRIDE, cur_engine,
     157                 :            :                                                 feature_size, omit_engine);
     158                 :          0 :                 offset += (feature_size + REGDUMP_HEADER_SIZE);
     159                 :          0 :                 DP_NOTICE(edev, false, "Protection override feature_size %u\n",
     160                 :            :                           feature_size);
     161                 :            : 
     162                 :            :                 /* fw_asserts dump */
     163                 :          0 :                 qdev->ops->common->dbg_fw_asserts(edev, (uint8_t *)buffer +
     164                 :          0 :                         offset + REGDUMP_HEADER_SIZE, &feature_size);
     165                 :          0 :                 *(uint32_t *)((uint8_t *)buffer + offset) =
     166                 :          0 :                         qede_calc_regdump_header(FW_ASSERTS, cur_engine,
     167                 :            :                                                  feature_size, omit_engine);
     168                 :          0 :                 offset += (feature_size + REGDUMP_HEADER_SIZE);
     169                 :          0 :                 DP_NOTICE(edev, false, "FW assert feature_size %u\n",
     170                 :            :                           feature_size);
     171                 :            : 
     172                 :            :                 /* grc dump */
     173                 :          0 :                 qdev->ops->common->dbg_grc(edev, (uint8_t *)buffer +
     174                 :          0 :                         offset + REGDUMP_HEADER_SIZE, &feature_size);
     175                 :          0 :                 *(uint32_t *)((uint8_t *)buffer + offset) =
     176                 :          0 :                         qede_calc_regdump_header(GRC_DUMP, cur_engine,
     177                 :            :                                                  feature_size, omit_engine);
     178                 :          0 :                 offset += (feature_size + REGDUMP_HEADER_SIZE);
     179                 :          0 :                 DP_NOTICE(edev, false, "GRC dump feature_size %u\n",
     180                 :            :                           feature_size);
     181                 :            :         }
     182                 :            : 
     183                 :            :         /* mcp_trace */
     184                 :          0 :         qdev->ops->common->dbg_mcp_trace(edev, (uint8_t *)buffer +
     185                 :          0 :                 offset + REGDUMP_HEADER_SIZE, &feature_size);
     186                 :          0 :         *(uint32_t *)((uint8_t *)buffer + offset) =
     187                 :          0 :                 qede_calc_regdump_header(MCP_TRACE, cur_engine, feature_size,
     188                 :            :                                          omit_engine);
     189                 :          0 :         offset += (feature_size + REGDUMP_HEADER_SIZE);
     190                 :          0 :         DP_NOTICE(edev, false, "MCP trace feature_size %u\n", feature_size);
     191                 :            : 
     192                 :          0 :         qdev->ops->common->dbg_set_debug_engine(edev, org_engine);
     193                 :            : 
     194                 :          0 :         OSAL_MUTEX_RELEASE(&edev->dbg_lock);
     195                 :            : 
     196                 :          0 :         return 0;
     197                 :            : }
     198                 :            : 
     199                 :            : static void
     200                 :          0 : qede_set_fw_dump_file_name(struct qede_dev *qdev)
     201                 :            : {
     202                 :            :         time_t ltime;
     203                 :            :         struct tm *tm;
     204                 :            : 
     205                 :          0 :         ltime = time(NULL);
     206                 :          0 :         tm = localtime(&ltime);
     207                 :          0 :         snprintf(qdev->dump_file, QEDE_FW_DUMP_FILE_SIZE,
     208                 :            :                  "qede_pmd_dump_%02d-%02d-%02d_%02d-%02d-%02d.bin",
     209                 :          0 :                  tm->tm_mon + 1, (int)tm->tm_mday, 1900 + tm->tm_year,
     210                 :            :                  tm->tm_hour, tm->tm_min, tm->tm_sec);
     211                 :          0 : }
     212                 :            : 
     213                 :            : static int
     214                 :          0 : qede_write_fwdump(const char *dump_file, void *dump, size_t len)
     215                 :            : {
     216                 :            :         int err = 0;
     217                 :            :         FILE *f;
     218                 :            :         size_t bytes;
     219                 :            : 
     220                 :          0 :         f = fopen(dump_file, "wb+");
     221                 :            : 
     222         [ #  # ]:          0 :         if (!f) {
     223                 :          0 :                 fprintf(stderr, "Can't open file %s: %s\n",
     224                 :          0 :                         dump_file, strerror(errno));
     225                 :          0 :                 return 1;
     226                 :            :         }
     227                 :          0 :         bytes = fwrite(dump, 1, len, f);
     228         [ #  # ]:          0 :         if (bytes != len) {
     229                 :          0 :                 fprintf(stderr,
     230                 :            :                         "Can not write all of dump data bytes=%zd len=%zd\n",
     231                 :            :                         bytes, len);
     232                 :            :                 err = 1;
     233                 :            :         }
     234                 :            : 
     235         [ #  # ]:          0 :         if (fclose(f)) {
     236                 :          0 :                 fprintf(stderr, "Can't close file %s: %s\n",
     237                 :          0 :                         dump_file, strerror(errno));
     238                 :            :                 err = 1;
     239                 :            :         }
     240                 :            : 
     241                 :            :         return err;
     242                 :            : }
     243                 :            : 
     244                 :            : int
     245                 :          0 : qede_save_fw_dump(uint16_t port_id)
     246                 :            : {
     247                 :          0 :         struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id];
     248                 :            :         struct rte_dev_reg_info regs;
     249                 :          0 :         struct qede_dev *qdev = eth_dev->data->dev_private;
     250                 :            :         struct ecore_dev *edev = &qdev->edev;
     251                 :            :         int rc = 0;
     252                 :            : 
     253         [ #  # ]:          0 :         if (!rte_eth_dev_is_valid_port(port_id)) {
     254                 :          0 :                 DP_ERR(edev, "port %u invalid port ID", port_id);
     255                 :          0 :                 return -ENODEV;
     256                 :            :         }
     257                 :            : 
     258                 :            :         memset(&regs, 0, sizeof(regs));
     259                 :          0 :         regs.length = qede_get_regs_len(qdev);
     260                 :          0 :         regs.data = OSAL_ZALLOC(eth_dev, GFP_KERNEL, regs.length);
     261         [ #  # ]:          0 :         if (regs.data) {
     262                 :          0 :                 qede_get_regs(eth_dev, &regs);
     263                 :          0 :                 qede_set_fw_dump_file_name(qdev);
     264                 :          0 :                 rc = qede_write_fwdump(qdev->dump_file, regs.data, regs.length);
     265         [ #  # ]:          0 :                 if (!rc)
     266                 :          0 :                         DP_NOTICE(edev, false, "FW dump written to %s file\n",
     267                 :            :                                   qdev->dump_file);
     268                 :          0 :                 OSAL_FREE(edev, regs.data);
     269                 :            :         }
     270                 :            : 
     271                 :            :         return rc;
     272                 :            : }

Generated by: LCOV version 1.14