]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
scsi: lpfc: Add support for reporting encryption events
authorSarah Catania <sarah.catania@broadcom.com>
Thu, 11 Dec 2025 00:16:58 +0000 (16:16 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 17 Dec 2025 02:56:48 +0000 (21:56 -0500)
Support logging encryption events in both point-to-point and fabric
topologies.  A new LOG_ENCRYPTION flag is defined for reporting
encryption related events for HBAs that support the FEDIF feature.
Encryption information is stored in each NDLP object, which is
determined during the discovery stage after PLOGI completes.

For reporting encryption information to upper layers, the
.get_fc_rport_enc_info routine is implemented in lpfc_get_enc_info().
This allows encryption status to be reported through fc_remote_ports
sysfs.  Debugfs is also updated to report encryption information for all
NDLP objects.

Signed-off-by: Sarah Catania <sarah.catania@broadcom.com>
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Link: https://patch.msgid.link/20251211001659.138635-3-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_debugfs.c
drivers/scsi/lpfc/lpfc_disc.h
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_hw4.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_logmsg.h
drivers/scsi/lpfc/lpfc_sli4.h

index 33582d48ec09b53ff08374f228eb16cf0ce307a5..4af5c069635a2a13e3b7635787ddef455025098f 100644 (file)
@@ -6979,6 +6979,42 @@ lpfc_reset_stats(struct Scsi_Host *shost)
        return;
 }
 
+/**
+ * lpfc_get_enc_info - Return encryption information about the session for
+ *                     a given remote port.
+ * @rport: ptr to fc_rport from scsi transport fc
+ *
+ * Given an rport object, iterate through the fc_nodes list to find node
+ * corresponding with rport. Pass the encryption information from the node to
+ * rport's encryption attribute for reporting to upper layers. Information is
+ * passed through nlp_enc_info struct which contains encryption status.
+ *
+ * Returns:
+ * - Address of rport's fc_encryption_info struct
+ * - NULL when not found
+ **/
+static struct fc_encryption_info *
+lpfc_get_enc_info(struct fc_rport *rport)
+{
+       struct Scsi_Host *shost = rport_to_shost(rport);
+       struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+       struct fc_encryption_info *ef = NULL;
+       struct lpfc_nodelist *ndlp, *next_ndlp;
+       unsigned long iflags;
+
+       spin_lock_irqsave(&vport->fc_nodes_list_lock, iflags);
+       list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
+               if (ndlp->rport && ndlp->rport == rport) {
+                       ef = &rport->enc_info;
+                       ef->status = ndlp->nlp_enc_info.status;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&vport->fc_nodes_list_lock, iflags);
+       return ef;
+}
+
+
 /*
  * The LPFC driver treats linkdown handling as target loss events so there
  * are no sysfs handlers for link_down_tmo.
@@ -7196,6 +7232,8 @@ struct fc_function_template lpfc_transport_functions = {
        .get_fc_host_stats = lpfc_get_stats,
        .reset_fc_host_stats = lpfc_reset_stats,
 
+       .get_fc_rport_enc_info = lpfc_get_enc_info,
+
        .dd_fcrport_size = sizeof(struct lpfc_rport_data),
        .show_rport_maxframe_size = 1,
        .show_rport_supported_classes = 1,
@@ -7265,6 +7303,8 @@ struct fc_function_template lpfc_vport_transport_functions = {
        .get_fc_host_stats = lpfc_get_stats,
        .reset_fc_host_stats = lpfc_reset_stats,
 
+       .get_fc_rport_enc_info = lpfc_get_enc_info,
+
        .dd_fcrport_size = sizeof(struct lpfc_rport_data),
        .show_rport_maxframe_size = 1,
        .show_rport_supported_classes = 1,
index 92b5b2dbe8474d91e0acbf72bd122d452655d613..646f88c776f522e4552beb20804f85cfcc8f6bf1 100644 (file)
@@ -872,6 +872,13 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
                                 ndlp->nlp_rpi);
                len += scnprintf(buf+len, size-len, "flag:x%08lx ",
                                 ndlp->nlp_flag);
+               if (ndlp->nlp_enc_info.status) {
+                       len += scnprintf(buf + len,
+                                        size - len, "ENCRYPTED");
+                       len += scnprintf(buf + len, size - len,
+                                        ndlp->nlp_enc_info.level
+                                        ? "(CNSA2.0) " : "(CNSA1.0) ");
+               }
                if (!ndlp->nlp_type)
                        len += scnprintf(buf+len, size-len, "UNKNOWN_TYPE ");
                if (ndlp->nlp_type & NLP_FC_NODE)
index 51cb8571c04928057eac9483eb28a7ccd86a2236..de0adeecf668a02354a1b20fddf708ffc92322cc 100644 (file)
@@ -77,6 +77,11 @@ struct lpfc_node_rrqs {
        unsigned long xri_bitmap[XRI_BITMAP_ULONGS];
 };
 
+struct lpfc_enc_info {
+       u8 status; /* encryption status for session */
+       u8 level; /* CNSA encryption level */
+};
+
 enum lpfc_fc4_xpt_flags {
        NLP_XPT_REGD            = 0x1,
        SCSI_XPT_REGD           = 0x2,
@@ -138,6 +143,8 @@ struct lpfc_nodelist {
        uint8_t         vmid_support;           /* destination VMID support */
 #define NLP_NVME_NSLER     0x1                 /* NVME NSLER device */
 
+       struct lpfc_enc_info nlp_enc_info; /* Encryption information struct */
+
        struct timer_list   nlp_delayfunc;      /* Used for delayed ELS cmds */
        struct lpfc_hba *phba;
        struct fc_rport *rport;         /* scsi_transport_fc port structure */
index 02b6d31b9ad9d5bcb9ffcae15e9d04d487a5ce11..32da3c23c7f450db9d16ebb1d6c17cfd1bdadb7c 100644 (file)
@@ -2014,6 +2014,58 @@ lpfc_cmpl_els_rrq(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
        lpfc_nlp_put(ndlp);
        return;
 }
+
+/**
+ * lpfc_check_encryption - Reports an ndlp's encryption information
+ * @phba: pointer to lpfc hba data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @cmdiocb: pointer to lpfc command iocbq data structure.
+ * @rspiocb: pointer to lpfc response iocbq data structure.
+ *
+ * This routine is called in the completion callback function for issuing
+ * or receiving a Port Login (PLOGI) command. In a PLOGI completion, if FEDIF
+ * is supported, encryption information will be provided in completion status
+ * data. If @phba supports FEDIF, a log message containing encryption
+ * information will be logged. Encryption status is also saved for encryption
+ * reporting with upper layer through the rport encryption attribute.
+ **/
+static void
+lpfc_check_encryption(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
+                     struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb)
+{
+       struct lpfc_vport *vport = cmdiocb->vport;
+       u32 did = ndlp->nlp_DID;
+       struct lpfc_enc_info *nlp_enc_info = &ndlp->nlp_enc_info;
+       char enc_status[FC_RPORT_ENCRYPTION_STATUS_MAX_LEN] = {0};
+       char enc_level[8] = "N/A";
+       u8 encryption;
+
+       if (phba->sli4_hba.encryption_support &&
+           ((did & Fabric_DID_MASK) != Fabric_DID_MASK)) {
+               encryption = bf_get(lpfc_wcqe_c_enc,
+                                   &rspiocb->wcqe_cmpl);
+               nlp_enc_info->status = encryption;
+
+               strscpy(enc_status, encryption ? "Encrypted" : "Unencrypted",
+                       sizeof(enc_status));
+
+               if (encryption) {
+                       nlp_enc_info->level = bf_get(lpfc_wcqe_c_enc_lvl,
+                                                    &rspiocb->wcqe_cmpl);
+                       strscpy(enc_level, nlp_enc_info->level ? "CNSA2.0" :
+                                                                "CNSA1.0",
+                               sizeof(enc_level));
+               }
+
+               lpfc_printf_vlog(vport, KERN_INFO, LOG_ENCRYPTION,
+                                "0924 DID:x%06x %s Session "
+                                "Established, Encryption Level:%s "
+                                "rpi:x%x\n",
+                                ndlp->nlp_DID, enc_status, enc_level,
+                                ndlp->nlp_rpi);
+       }
+}
+
 /**
  * lpfc_cmpl_els_plogi - Completion callback function for plogi
  * @phba: pointer to lpfc hba data structure.
@@ -2153,6 +2205,8 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                        goto out;
                ndlp = lpfc_plogi_confirm_nport(phba, prsp->virt, ndlp);
 
+               lpfc_check_encryption(phba, ndlp, cmdiocb, rspiocb);
+
                sp = (struct serv_parm *)((u8 *)prsp->virt +
                                          sizeof(u32));
 
@@ -5407,6 +5461,9 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                goto out;
        }
 
+       if (!ulp_status && test_bit(NLP_RCV_PLOGI, &ndlp->nlp_flag))
+               lpfc_check_encryption(phba, ndlp, cmdiocb, rspiocb);
+
        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
                "ELS rsp cmpl:    status:x%x/x%x did:x%x",
                ulp_status, ulp_word4, did);
index bb803f32bc1b3a92181391a76b476ac56a648445..1aeebdc0807366b612d231cc25c345b651454228 100644 (file)
@@ -5340,6 +5340,7 @@ out:
                clear_bit(NLP_NPR_ADISC, &ndlp->nlp_flag);
                if (acc_plogi)
                        clear_bit(NLP_LOGO_ACC, &ndlp->nlp_flag);
+               memset(&ndlp->nlp_enc_info, 0, sizeof(ndlp->nlp_enc_info));
                return 1;
        }
        clear_bit(NLP_LOGO_ACC, &ndlp->nlp_flag);
index a7f7ed86d2b014d425a6ae289be7a1b9eb3b6f8c..c000474c3066df0a63dc87b3a47ca0a907c8e4d5 100644 (file)
@@ -437,6 +437,12 @@ struct lpfc_wcqe_complete {
 #define lpfc_wcqe_c_cmf_bw_MASK                0x0FFFFFFF
 #define lpfc_wcqe_c_cmf_bw_WORD                total_data_placed
        uint32_t parameter;
+#define lpfc_wcqe_c_enc_SHIFT          31
+#define lpfc_wcqe_c_enc_MASK           0x00000001
+#define lpfc_wcqe_c_enc_WORD           parameter
+#define lpfc_wcqe_c_enc_lvl_SHIFT      30
+#define lpfc_wcqe_c_enc_lvl_MASK       0x00000001
+#define lpfc_wcqe_c_enc_lvl_WORD       parameter
 #define lpfc_wcqe_c_bg_edir_SHIFT      5
 #define lpfc_wcqe_c_bg_edir_MASK       0x00000001
 #define lpfc_wcqe_c_bg_edir_WORD       parameter
@@ -2942,7 +2948,10 @@ struct lpfc_mbx_read_config {
 #define lpfc_mbx_rd_conf_topology_SHIFT                24
 #define lpfc_mbx_rd_conf_topology_MASK         0x000000FF
 #define lpfc_mbx_rd_conf_topology_WORD         word2
-       uint32_t rsvd_3;
+       uint32_t word3;
+#define lpfc_mbx_rd_conf_fedif_SHIFT           6
+#define lpfc_mbx_rd_conf_fedif_MASK            0x00000001
+#define lpfc_mbx_rd_conf_fedif_WORD            word3
        uint32_t word4;
 #define lpfc_mbx_rd_conf_e_d_tov_SHIFT         0
 #define lpfc_mbx_rd_conf_e_d_tov_MASK          0x0000FFFF
index b1460b16dd91d9a2af8dd9c8ed3935db1da848a2..a116a16c4a6f826f5b8978aea358bdcfb65ea0e6 100644 (file)
@@ -9999,6 +9999,11 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
                                (phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0;
                phba->max_vports = phba->max_vpi;
 
+               if (bf_get(lpfc_mbx_rd_conf_fedif, rd_config))
+                       phba->sli4_hba.encryption_support = true;
+               else
+                       phba->sli4_hba.encryption_support = false;
+
                /* Next decide on FPIN or Signal E2E CGN support
                 * For congestion alarms and warnings valid combination are:
                 * 1. FPIN alarms / FPIN warnings
index 59bd2bafc73f0eff49a6c2061d5253c9fd3abab9..e00d101d548cef7c76df4fc38f5c690c6ab48e4c 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2017-2023 Broadcom. All Rights Reserved. The term *
+ * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term *
  * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.     *
  * Copyright (C) 2004-2009 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
@@ -47,6 +47,7 @@
 #define LOG_RSVD1      0x01000000      /* Reserved */
 #define LOG_RSVD2      0x02000000      /* Reserved */
 #define LOG_CGN_MGMT    0x04000000     /* Congestion Mgmt events */
+#define LOG_ENCRYPTION  0x40000000      /* EDIF Encryption events. */
 #define LOG_TRACE_EVENT 0x80000000     /* Dmp the DBG log on this err */
 #define LOG_ALL_MSG    0x7fffffff      /* LOG all messages */
 
index fd6dab1578872f10df372ca5002052763692b8ef..ee58383492b2bbab8f8011a8348155d94dcdb164 100644 (file)
@@ -888,6 +888,10 @@ struct lpfc_sli4_hba {
 #define LPFC_FP_EQ_MAX_INTR_SEC         10000
 
        uint32_t intr_enable;
+
+        /* Indicates whether SLI Port supports FEDIF */
+       bool encryption_support;
+
        struct lpfc_bmbx bmbx;
        struct lpfc_max_cfg_param max_cfg_param;
        uint16_t extents_in_use; /* must allocate resource extents. */