diff --git a/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c b/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c index 786ac991..dc0b5253 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c +++ b/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c @@ -6449,6 +6449,20 @@ static int ether_suspend_noirq(struct device *dev) if (!netif_running(ndev)) return 0; + /* Keep MACSEC to suspend if MACSEC is supported on this platform */ +#ifdef MACSEC_SUPPORT + if ((osi_core->mac == OSI_MAC_HW_EQOS && osi_core->mac_ver == OSI_EQOS_MAC_5_30) || + (osi_core->mac == OSI_MAC_HW_MGBE && osi_core->mac_ver == OSI_MGBE_MAC_3_10)) { + pdata->macsec_pdata->enabled_before_suspend = + pdata->macsec_pdata->enabled; + if (pdata->macsec_pdata->enabled != OSI_DISABLE) { + ret = macsec_suspend(pdata->macsec_pdata); + if (ret < 0) + dev_err(pdata->dev, "Failed to suspend macsec"); + } + } +#endif /* MACSEC_SUPPORT */ + /* Since MAC is placed in reset during suspend, take a backup of * current configuration so that SW view of HW is maintained across * suspend/resume. @@ -6626,6 +6640,18 @@ static int ether_resume(struct ether_priv_data *pdata) /* re-start workqueue */ ether_stats_work_queue_start(pdata); + /* Keep MACSEC also to Resume if MACSEC is supported on this platform */ +#ifdef MACSEC_SUPPORT + if ((osi_core->mac == OSI_MAC_HW_EQOS && osi_core->mac_ver == OSI_EQOS_MAC_5_30) || + (osi_core->mac == OSI_MAC_HW_MGBE && osi_core->mac_ver == OSI_MGBE_MAC_3_10)) { + if (pdata->macsec_pdata->enabled_before_suspend != OSI_DISABLE) { + ret = macsec_resume(pdata->macsec_pdata); + if (ret < 0) + dev_err(pdata->dev, "Failed to resume MACSEC "); + } + } +#endif /* MACSEC_SUPPORT */ + return 0; err_start_mac: ether_napi_disable(pdata); diff --git a/drivers/net/ethernet/nvidia/nvethernet/macsec.c b/drivers/net/ethernet/nvidia/nvethernet/macsec.c index 39dd9a32..712fbcd6 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/macsec.c +++ b/drivers/net/ethernet/nvidia/nvethernet/macsec.c @@ -215,8 +215,8 @@ int macsec_open(struct macsec_priv_data *macsec_pdata, #ifndef MACSEC_KEY_PROGRAM /* Clear KT entries */ - ret = macsec_tz_kt_config(pdata, OSI_MACSEC_CMD_TZ_KT_RESET, OSI_NULL, - genl_info); + ret = macsec_tz_kt_config(pdata, OSI_MACSEC_CMD_TZ_KT_RESET, + OSI_NULL, genl_info); if (ret < 0) { dev_err(dev, "TZ key config failed %d\n", ret); goto err_osi_en; @@ -246,6 +246,45 @@ exit: return ret; } +/** + * Calling macsec_close as part of macsec_suspend as supplicant + * is disabling the current AN and creating new AN as part of + * resume. + */ +int macsec_suspend(struct macsec_priv_data *macsec_pdata) +{ + struct ether_priv_data *pdata = macsec_pdata->ether_pdata; + struct device *dev = pdata->dev; + int ret = 0; + + ret = macsec_close(macsec_pdata); + if (ret < 0) { + dev_err(dev, "Failed to close macsec\n"); + return ret; + } + macsec_disable_car(macsec_pdata); + return ret; +} + +/** + * Calling macsec_open as part of macsec_resume as supplicant + * is disabling the current AN and creating new AN as part of + * resume. + */ +int macsec_resume(struct macsec_priv_data *macsec_pdata) +{ + struct ether_priv_data *pdata = macsec_pdata->ether_pdata; + struct device *dev = pdata->dev; + int ret = 0; + + ret = macsec_enable_car(macsec_pdata); + if (ret < 0) { + dev_err(dev, "Unable to enable macsec clks & reset\n"); + return ret; + } + return macsec_open(macsec_pdata, OSI_NULL); +} + static int macsec_get_platform_res(struct macsec_priv_data *macsec_pdata) { struct ether_priv_data *pdata = macsec_pdata->ether_pdata; diff --git a/drivers/net/ethernet/nvidia/nvethernet/macsec.h b/drivers/net/ethernet/nvidia/nvethernet/macsec.h index 6faa972a..a2f9e5bf 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/macsec.h +++ b/drivers/net/ethernet/nvidia/nvethernet/macsec.h @@ -207,6 +207,8 @@ struct macsec_priv_data { unsigned int protect_frames; /** MACsec enabled flags for Tx/Rx controller status */ unsigned int enabled; + /** MACsec enabled flags for Tx/Rx controller status before Suspend */ + unsigned int enabled_before_suspend; /** MACsec Rx PN Window */ unsigned int pn_window; /** MACsec controller init reference count */ @@ -226,6 +228,8 @@ void macsec_remove(struct ether_priv_data *pdata); int macsec_open(struct macsec_priv_data *macsec_pdata, void *const genl_info); int macsec_close(struct macsec_priv_data *macsec_pdata); +int macsec_suspend(struct macsec_priv_data *macsec_pdata); +int macsec_resume(struct macsec_priv_data *macsec_pdata); #ifdef MACSEC_DEBUG #define PRINT_ENTRY() (printk(KERN_DEBUG "-->%s()\n", __func__))