Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

qed*: esl priv flag support through ethtool

ESL(Enhanced System Lockdown) was designed to lock PCI adapter firmware
images and prevent changes to critical non-volatile configuration data
so that uncontrolled, malicious or unintentional modification to the
adapters are avoided, ensuring it's operational state. Once this feature is
enabled, the device is locked, rejecting any modification to non-volatile
images. Once unlocked, the protection is off such that firmware and
non-volatile configurations may be altered.

Driver just reflects the capability and status of this through
the ethtool private flag.

Signed-off-by: Manish Chopra <manishc@marvell.com>
Signed-off-by: Prabhakar Kushwaha <pkushwaha@marvell.com>
Signed-off-by: Alok Prasad <palok@marvell.com>
Signed-off-by: Ariel Elior <aelior@marvell.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Manish Chopra and committed by
Jakub Kicinski
823163ba 0cc3a801

+83 -1
+24 -1
drivers/net/ethernet/qlogic/qed/qed_main.c
··· 447 447 dev_info->wol_support = true; 448 448 449 449 dev_info->smart_an = qed_mcp_is_smart_an_supported(p_hwfn); 450 - 450 + dev_info->esl = qed_mcp_is_esl_supported(p_hwfn); 451 451 dev_info->abs_pf_id = QED_LEADING_HWFN(cdev)->abs_pf_id; 452 452 } else { 453 453 qed_vf_get_fw_version(&cdev->hwfns[0], &dev_info->fw_major, ··· 3028 3028 return QED_AFFIN_HWFN_IDX(cdev); 3029 3029 } 3030 3030 3031 + static int qed_get_esl_status(struct qed_dev *cdev, bool *esl_active) 3032 + { 3033 + struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev); 3034 + struct qed_ptt *ptt; 3035 + int rc = 0; 3036 + 3037 + *esl_active = false; 3038 + 3039 + if (IS_VF(cdev)) 3040 + return 0; 3041 + 3042 + ptt = qed_ptt_acquire(hwfn); 3043 + if (!ptt) 3044 + return -EAGAIN; 3045 + 3046 + rc = qed_mcp_get_esl_status(hwfn, ptt, esl_active); 3047 + 3048 + qed_ptt_release(hwfn, ptt); 3049 + 3050 + return rc; 3051 + } 3052 + 3031 3053 static struct qed_selftest_ops qed_selftest_ops_pass = { 3032 3054 .selftest_memory = &qed_selftest_memory, 3033 3055 .selftest_interrupt = &qed_selftest_interrupt, ··· 3107 3085 .set_grc_config = &qed_set_grc_config, 3108 3086 .mfw_report = &qed_mfw_report, 3109 3087 .get_sb_info = &qed_get_sb_info, 3088 + .get_esl_status = &qed_get_esl_status, 3110 3089 }; 3111 3090 3112 3091 void qed_get_protocol_stats(struct qed_dev *cdev,
+22
drivers/net/ethernet/qlogic/qed/qed_mcp.c
··· 4158 4158 return qed_mcp_send_debug_data(p_hwfn, p_ptt, 4159 4159 QED_MCP_DBG_DATA_TYPE_RAW, p_buf, size); 4160 4160 } 4161 + 4162 + bool qed_mcp_is_esl_supported(struct qed_hwfn *p_hwfn) 4163 + { 4164 + return !!(p_hwfn->mcp_info->capabilities & 4165 + FW_MB_PARAM_FEATURE_SUPPORT_ENHANCED_SYS_LCK); 4166 + } 4167 + 4168 + int qed_mcp_get_esl_status(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, bool *active) 4169 + { 4170 + u32 resp = 0, param = 0; 4171 + int rc; 4172 + 4173 + rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_GET_MANAGEMENT_STATUS, 0, &resp, &param); 4174 + if (rc) { 4175 + DP_NOTICE(p_hwfn, "Failed to send ESL command, rc = %d\n", rc); 4176 + return rc; 4177 + } 4178 + 4179 + *active = !!(param & FW_MB_PARAM_MANAGEMENT_STATUS_LOCKDOWN_ENABLED); 4180 + 4181 + return 0; 4182 + }
+20
drivers/net/ethernet/qlogic/qed/qed_mcp.h
··· 1339 1339 int qed_mcp_nvm_set_cfg(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, 1340 1340 u16 option_id, u8 entity_id, u16 flags, u8 *p_buf, 1341 1341 u32 len); 1342 + 1343 + /** 1344 + * qed_mcp_is_esl_supported(): Return whether management firmware support ESL or not. 1345 + * 1346 + * @p_hwfn: hw function pointer 1347 + * 1348 + * Return: true if esl is supported, otherwise return false 1349 + */ 1350 + bool qed_mcp_is_esl_supported(struct qed_hwfn *p_hwfn); 1351 + 1352 + /** 1353 + * qed_mcp_get_esl_status(): Get enhanced system lockdown status 1354 + * 1355 + * @p_hwfn: hw function pointer 1356 + * @p_ptt: ptt resource pointer 1357 + * @active: ESL active status data pointer 1358 + * 1359 + * Return: 0 with esl status info on success, otherwise return error 1360 + */ 1361 + int qed_mcp_get_esl_status(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, bool *active); 1342 1362 #endif
+1
drivers/net/ethernet/qlogic/qed/qed_mfw_hsi.h
··· 1191 1191 DRV_MSG_CODE_CFG_VF_MSIX = DRV_MSG_CODE(0xc001), 1192 1192 DRV_MSG_CODE_CFG_PF_VFS_MSIX = DRV_MSG_CODE(0xc002), 1193 1193 DRV_MSG_CODE_DEBUG_DATA_SEND = DRV_MSG_CODE(0xc004), 1194 + DRV_MSG_CODE_GET_MANAGEMENT_STATUS = DRV_MSG_CODE(0xc007), 1194 1195 }; 1195 1196 1196 1197 #define DRV_MSG_CODE_VMAC_TYPE_SHIFT 4
+13
drivers/net/ethernet/qlogic/qede/qede_ethtool.c
··· 168 168 QEDE_PRI_FLAG_CMT, 169 169 QEDE_PRI_FLAG_SMART_AN_SUPPORT, /* MFW supports SmartAN */ 170 170 QEDE_PRI_FLAG_RECOVER_ON_ERROR, 171 + QEDE_PRI_FLAG_ESL_SUPPORT, /* MFW supports Enhanced System Lockdown */ 172 + QEDE_PRI_FLAG_ESL_ACTIVE, /* Enhanced System Lockdown Active status */ 171 173 QEDE_PRI_FLAG_LEN, 172 174 }; 173 175 ··· 177 175 "Coupled-Function", 178 176 "SmartAN capable", 179 177 "Recover on error", 178 + "ESL capable", 179 + "ESL active", 180 180 }; 181 181 182 182 enum qede_ethtool_tests { ··· 482 478 static u32 qede_get_priv_flags(struct net_device *dev) 483 479 { 484 480 struct qede_dev *edev = netdev_priv(dev); 481 + bool esl_active; 485 482 u32 flags = 0; 486 483 487 484 if (edev->dev_info.common.num_hwfns > 1) ··· 493 488 494 489 if (edev->err_flags & BIT(QEDE_ERR_IS_RECOVERABLE)) 495 490 flags |= BIT(QEDE_PRI_FLAG_RECOVER_ON_ERROR); 491 + 492 + if (edev->dev_info.common.esl) 493 + flags |= BIT(QEDE_PRI_FLAG_ESL_SUPPORT); 494 + 495 + edev->ops->common->get_esl_status(edev->cdev, &esl_active); 496 + 497 + if (esl_active) 498 + flags |= BIT(QEDE_PRI_FLAG_ESL_ACTIVE); 496 499 497 500 return flags; 498 501 }
+3
include/linux/qed/qed_if.h
··· 652 652 653 653 bool wol_support; 654 654 bool smart_an; 655 + bool esl; 655 656 656 657 /* MBI version */ 657 658 u32 mbi_version; ··· 1206 1205 1207 1206 int (*get_sb_info)(struct qed_dev *cdev, struct qed_sb_info *sb, 1208 1207 u16 qid, struct qed_sb_info_dbg *sb_dbg); 1208 + 1209 + int (*get_esl_status)(struct qed_dev *cdev, bool *esl_active); 1209 1210 }; 1210 1211 1211 1212 #define MASK_FIELD(_name, _value) \