cxgb4: use backdoor access to collect dumps when firmware crashed
authorRahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Fri, 26 Jan 2018 11:35:56 +0000 (17:05 +0530)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 Jan 2018 16:00:22 +0000 (11:00 -0500)
Fallback to backdoor register access to collect dumps if firmware
is crashed.  Fixes TID, SGE Queue Context, and MPS TCAM dump collection.

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c

index 8b95117c2923e683f0c6b36fbd27d263f435fb5e..557fd8bfd54e575646f083e5c426ba6c28ecf338 100644 (file)
@@ -1567,6 +1567,12 @@ int cudbg_collect_tid(struct cudbg_init *pdbg_init,
        tid1->ver_hdr.size = sizeof(struct cudbg_tid_info_region_rev1) -
                             sizeof(struct cudbg_ver_hdr);
 
+       /* If firmware is not attached/alive, use backdoor register
+        * access to collect dump.
+        */
+       if (!is_fw_attached(pdbg_init))
+               goto fill_tid;
+
 #define FW_PARAM_PFVF_A(param) \
        (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) | \
         FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_##param) | \
@@ -1604,6 +1610,9 @@ int cudbg_collect_tid(struct cudbg_init *pdbg_init,
                tid->nhpftids = val[1] - val[0] + 1;
        }
 
+#undef FW_PARAM_PFVF_A
+
+fill_tid:
        tid->ntids = padap->tids.ntids;
        tid->nstids = padap->tids.nstids;
        tid->stid_base = padap->tids.stid_base;
@@ -1623,8 +1632,6 @@ int cudbg_collect_tid(struct cudbg_init *pdbg_init,
        tid->ip_users = t4_read_reg(padap, LE_DB_ACT_CNT_IPV4_A);
        tid->ipv6_users = t4_read_reg(padap, LE_DB_ACT_CNT_IPV6_A);
 
-#undef FW_PARAM_PFVF_A
-
        return cudbg_write_and_release_buff(pdbg_init, &temp_buff, dbg_buff);
 }
 
@@ -1866,11 +1873,18 @@ int cudbg_collect_dump_context(struct cudbg_init *pdbg_init,
                max_ctx_size = region_info[i].end - region_info[i].start + 1;
                max_ctx_qid = max_ctx_size / SGE_CTXT_SIZE;
 
-               t4_sge_ctxt_flush(padap, padap->mbox, i);
-               rc = t4_memory_rw(padap, MEMWIN_NIC, mem_type[i],
-                                 region_info[i].start, max_ctx_size,
-                                 (__be32 *)ctx_buf, 1);
-               if (rc) {
+               /* If firmware is not attached/alive, use backdoor register
+                * access to collect dump.
+                */
+               if (is_fw_attached(pdbg_init)) {
+                       t4_sge_ctxt_flush(padap, padap->mbox, i);
+
+                       rc = t4_memory_rw(padap, MEMWIN_NIC, mem_type[i],
+                                         region_info[i].start, max_ctx_size,
+                                         (__be32 *)ctx_buf, 1);
+               }
+
+               if (rc || !is_fw_attached(pdbg_init)) {
                        max_ctx_qid = CUDBG_LOWMEM_MAX_CTXT_QIDS;
                        cudbg_get_sge_ctxt_fw(pdbg_init, max_ctx_qid, i,
                                              &buff);
@@ -1946,9 +1960,10 @@ static void cudbg_mps_rpl_backdoor(struct adapter *padap,
        mps_rplc->rplc31_0 = htonl(t4_read_reg(padap, MPS_VF_RPLCT_MAP0_A));
 }
 
-static int cudbg_collect_tcam_index(struct adapter *padap,
+static int cudbg_collect_tcam_index(struct cudbg_init *pdbg_init,
                                    struct cudbg_mps_tcam *tcam, u32 idx)
 {
+       struct adapter *padap = pdbg_init->adap;
        u64 tcamy, tcamx, val;
        u32 ctl, data2;
        int rc = 0;
@@ -2033,12 +2048,22 @@ static int cudbg_collect_tcam_index(struct adapter *padap,
                        htons(FW_LDST_CMD_FID_V(FW_LDST_MPS_RPLC) |
                              FW_LDST_CMD_IDX_V(idx));
 
-               rc = t4_wr_mbox(padap, padap->mbox, &ldst_cmd, sizeof(ldst_cmd),
-                               &ldst_cmd);
-               if (rc)
+               /* If firmware is not attached/alive, use backdoor register
+                * access to collect dump.
+                */
+               if (is_fw_attached(pdbg_init))
+                       rc = t4_wr_mbox(padap, padap->mbox, &ldst_cmd,
+                                       sizeof(ldst_cmd), &ldst_cmd);
+
+               if (rc || !is_fw_attached(pdbg_init)) {
                        cudbg_mps_rpl_backdoor(padap, &mps_rplc);
-               else
+                       /* Ignore error since we collected directly from
+                        * reading registers.
+                        */
+                       rc = 0;
+               } else {
                        mps_rplc = ldst_cmd.u.mps.rplc;
+               }
 
                tcam->rplc[0] = ntohl(mps_rplc.rplc31_0);
                tcam->rplc[1] = ntohl(mps_rplc.rplc63_32);
@@ -2075,7 +2100,7 @@ int cudbg_collect_mps_tcam(struct cudbg_init *pdbg_init,
 
        tcam = (struct cudbg_mps_tcam *)temp_buff.data;
        for (i = 0; i < n; i++) {
-               rc = cudbg_collect_tcam_index(padap, tcam, i);
+               rc = cudbg_collect_tcam_index(pdbg_init, tcam, i);
                if (rc) {
                        cudbg_err->sys_err = rc;
                        cudbg_put_buff(pdbg_init, &temp_buff);