net/sfc/base: import MCDI logging
authorAndrew Rybchenko <arybchenko@solarflare.com>
Tue, 29 Nov 2016 16:18:39 +0000 (16:18 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 17 Jan 2017 18:39:25 +0000 (19:39 +0100)
Driver can provide a function to be called to log MCDI
requests and responses to help with debugging.

Solarflare netlogdecode cross-platform tool may be used
to decode these logs.

EFSYS_OPT_MCDI_LOGGING should be enabled to use it.

From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
drivers/net/sfc/base/efx.h
drivers/net/sfc/base/efx_check.h
drivers/net/sfc/base/efx_mcdi.c

index 8d0e691..9fdfb96 100644 (file)
@@ -191,12 +191,24 @@ typedef enum efx_mcdi_exception_e {
        EFX_MCDI_EXCEPTION_MC_BADASSERT,
 } efx_mcdi_exception_t;
 
+#if EFSYS_OPT_MCDI_LOGGING
+typedef enum efx_log_msg_e {
+       EFX_LOG_INVALID,
+       EFX_LOG_MCDI_REQUEST,
+       EFX_LOG_MCDI_RESPONSE,
+} efx_log_msg_t;
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+
 typedef struct efx_mcdi_transport_s {
        void            *emt_context;
        efsys_mem_t     *emt_dma_mem;
        void            (*emt_execute)(void *, efx_mcdi_req_t *);
        void            (*emt_ev_cpl)(void *);
        void            (*emt_exception)(void *, efx_mcdi_exception_t);
+#if EFSYS_OPT_MCDI_LOGGING
+       void            (*emt_logger)(void *, efx_log_msg_t,
+                                       void *, size_t, void *, size_t);
+#endif /* EFSYS_OPT_MCDI_LOGGING */
 } efx_mcdi_transport_t;
 
 extern __checkReturn   efx_rc_t
index 9d0e988..228b42c 100644 (file)
 #  error "MCDI requires SIENA or HUNTINGTON or MEDFORD"
 #endif /* EFSYS_OPT_MCDI */
 
+#if EFSYS_OPT_MCDI_LOGGING
+/* Support MCDI logging */
+# if !EFSYS_OPT_MCDI
+#  error "MCDI_LOGGING requires MCDI"
+# endif
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+
 #ifdef EFSYS_OPT_MON_LM87
 # error "MON_LM87 is obsolete and is not supported."
 #endif
index c11ece9..a87a223 100644 (file)
@@ -192,6 +192,9 @@ efx_mcdi_request_start(
        __in            efx_mcdi_req_t *emrp,
        __in            boolean_t ev_cpl)
 {
+#if EFSYS_OPT_MCDI_LOGGING
+       const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+#endif
        efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
        efx_dword_t hdr[2];
        size_t hdr_len;
@@ -268,6 +271,14 @@ efx_mcdi_request_start(
                    MCDI_HEADER_XFLAGS, xflags);
        }
 
+#if EFSYS_OPT_MCDI_LOGGING
+       if (emtp->emt_logger != NULL) {
+               emtp->emt_logger(emtp->emt_context, EFX_LOG_MCDI_REQUEST,
+                   &hdr[0], hdr_len,
+                   emrp->emr_in_buf, emrp->emr_in_length);
+       }
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+
        efx_mcdi_send_request(enp, &hdr[0], hdr_len,
            emrp->emr_in_buf, emrp->emr_in_length);
 }
@@ -278,6 +289,9 @@ efx_mcdi_read_response_header(
        __in            efx_nic_t *enp,
        __inout         efx_mcdi_req_t *emrp)
 {
+#if EFSYS_OPT_MCDI_LOGGING
+       const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+#endif /* EFSYS_OPT_MCDI_LOGGING */
        efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
        efx_dword_t hdr[2];
        unsigned int hdr_len;
@@ -338,6 +352,15 @@ efx_mcdi_read_response_header(
                emrp->emr_err_code = err_code;
                emrp->emr_err_arg = err_arg;
 
+#if EFSYS_OPT_MCDI_LOGGING
+               if (emtp->emt_logger != NULL) {
+                       emtp->emt_logger(emtp->emt_context,
+                           EFX_LOG_MCDI_RESPONSE,
+                           &hdr[0], hdr_len,
+                           &err[0], err_len);
+               }
+#endif /* EFSYS_OPT_MCDI_LOGGING */
+
                if (!emrp->emr_quiet) {
                        EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd,
                            int, err_code, int, err_arg);
@@ -363,6 +386,9 @@ efx_mcdi_finish_response(
        __in            efx_nic_t *enp,
        __in            efx_mcdi_req_t *emrp)
 {
+#if EFSYS_OPT_MCDI_LOGGING
+       const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+#endif /* EFSYS_OPT_MCDI_LOGGING */
        efx_dword_t hdr[2];
        unsigned int hdr_len;
        size_t bytes;
@@ -389,6 +415,14 @@ efx_mcdi_finish_response(
        bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length);
        efx_mcdi_read_response(enp, emrp->emr_out_buf, hdr_len, bytes);
 
+#if EFSYS_OPT_MCDI_LOGGING
+       if (emtp->emt_logger != NULL) {
+               emtp->emt_logger(emtp->emt_context,
+                   EFX_LOG_MCDI_RESPONSE,
+                   &hdr[0], hdr_len,
+                   emrp->emr_out_buf, bytes);
+       }
+#endif /* EFSYS_OPT_MCDI_LOGGING */
 }