net: lan743x: Add support to Secure-ON WOL
authorRaju Lakkaraju <Raju.Lakkaraju@microchip.com>
Thu, 16 Jun 2022 04:12:24 +0000 (09:42 +0530)
committerJakub Kicinski <kuba@kernel.org>
Fri, 17 Jun 2022 03:45:48 +0000 (20:45 -0700)
Add support to Magic Packet Detection with Secure-ON for PCI11010/PCI11414 chips

Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/microchip/lan743x_ethtool.c
drivers/net/ethernet/microchip/lan743x_main.c
drivers/net/ethernet/microchip/lan743x_main.h

index 48b19dc..99776f7 100644 (file)
@@ -1149,7 +1149,12 @@ static void lan743x_ethtool_get_wol(struct net_device *netdev,
        wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST |
                WAKE_MAGIC | WAKE_PHY | WAKE_ARP;
 
        wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST |
                WAKE_MAGIC | WAKE_PHY | WAKE_ARP;
 
+       if (adapter->is_pci11x1x)
+               wol->supported |= WAKE_MAGICSECURE;
+
        wol->wolopts |= adapter->wolopts;
        wol->wolopts |= adapter->wolopts;
+       if (adapter->wolopts & WAKE_MAGICSECURE)
+               memcpy(wol->sopass, adapter->sopass, sizeof(wol->sopass));
 }
 
 static int lan743x_ethtool_set_wol(struct net_device *netdev,
 }
 
 static int lan743x_ethtool_set_wol(struct net_device *netdev,
@@ -1170,6 +1175,13 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev,
                adapter->wolopts |= WAKE_PHY;
        if (wol->wolopts & WAKE_ARP)
                adapter->wolopts |= WAKE_ARP;
                adapter->wolopts |= WAKE_PHY;
        if (wol->wolopts & WAKE_ARP)
                adapter->wolopts |= WAKE_ARP;
+       if (wol->wolopts & WAKE_MAGICSECURE &&
+           wol->wolopts & WAKE_MAGIC) {
+               memcpy(adapter->sopass, wol->sopass, sizeof(wol->sopass));
+               adapter->wolopts |= WAKE_MAGICSECURE;
+       } else {
+               memset(adapter->sopass, 0, sizeof(u8) * SOPASS_MAX);
+       }
 
        device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts);
 
 
        device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts);
 
index af81236..6352cba 100644 (file)
@@ -3124,6 +3124,7 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter)
        const u8 ipv6_multicast[3] = { 0x33, 0x33 };
        const u8 arp_type[2] = { 0x08, 0x06 };
        int mask_index;
        const u8 ipv6_multicast[3] = { 0x33, 0x33 };
        const u8 arp_type[2] = { 0x08, 0x06 };
        int mask_index;
+       u32 sopass;
        u32 pmtctl;
        u32 wucsr;
        u32 macrx;
        u32 pmtctl;
        u32 wucsr;
        u32 macrx;
@@ -3218,6 +3219,14 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter)
                pmtctl |= PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_;
        }
 
                pmtctl |= PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_;
        }
 
+       if (adapter->wolopts & WAKE_MAGICSECURE) {
+               sopass = *(u32 *)adapter->sopass;
+               lan743x_csr_write(adapter, MAC_MP_SO_LO, sopass);
+               sopass = *(u16 *)&adapter->sopass[4];
+               lan743x_csr_write(adapter, MAC_MP_SO_HI, sopass);
+               wucsr |= MAC_MP_SO_EN_;
+       }
+
        lan743x_csr_write(adapter, MAC_WUCSR, wucsr);
        lan743x_csr_write(adapter, PMT_CTL, pmtctl);
        lan743x_csr_write(adapter, MAC_RX, macrx);
        lan743x_csr_write(adapter, MAC_WUCSR, wucsr);
        lan743x_csr_write(adapter, PMT_CTL, pmtctl);
        lan743x_csr_write(adapter, MAC_RX, macrx);
@@ -3228,6 +3237,7 @@ static int lan743x_pm_suspend(struct device *dev)
        struct pci_dev *pdev = to_pci_dev(dev);
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct lan743x_adapter *adapter = netdev_priv(netdev);
        struct pci_dev *pdev = to_pci_dev(dev);
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct lan743x_adapter *adapter = netdev_priv(netdev);
+       u32 data;
 
        lan743x_pcidev_shutdown(pdev);
 
 
        lan743x_pcidev_shutdown(pdev);
 
@@ -3239,6 +3249,18 @@ static int lan743x_pm_suspend(struct device *dev)
        if (adapter->wolopts)
                lan743x_pm_set_wol(adapter);
 
        if (adapter->wolopts)
                lan743x_pm_set_wol(adapter);
 
+       if (adapter->is_pci11x1x) {
+               /* Save HW_CFG to config again in PM resume */
+               data = lan743x_csr_read(adapter, HW_CFG);
+               adapter->hw_cfg = data;
+               data |= (HW_CFG_RST_PROTECT_PCIE_ |
+                        HW_CFG_D3_RESET_DIS_ |
+                        HW_CFG_D3_VAUX_OVR_ |
+                        HW_CFG_HOT_RESET_DIS_ |
+                        HW_CFG_RST_PROTECT_);
+               lan743x_csr_write(adapter, HW_CFG, data);
+       }
+
        /* Host sets PME_En, put D3hot */
        return pci_prepare_to_sleep(pdev);
 }
        /* Host sets PME_En, put D3hot */
        return pci_prepare_to_sleep(pdev);
 }
@@ -3254,6 +3276,10 @@ static int lan743x_pm_resume(struct device *dev)
        pci_restore_state(pdev);
        pci_save_state(pdev);
 
        pci_restore_state(pdev);
        pci_save_state(pdev);
 
+       /* Restore HW_CFG that was saved during pm suspend */
+       if (adapter->is_pci11x1x)
+               lan743x_csr_write(adapter, HW_CFG, adapter->hw_cfg);
+
        ret = lan743x_hardware_init(adapter, pdev);
        if (ret) {
                netif_err(adapter, probe, adapter->netdev,
        ret = lan743x_hardware_init(adapter, pdev);
        if (ret) {
                netif_err(adapter, probe, adapter->netdev,
@@ -3270,6 +3296,9 @@ static int lan743x_pm_resume(struct device *dev)
                lan743x_netdev_open(netdev);
 
        netif_device_attach(netdev);
                lan743x_netdev_open(netdev);
 
        netif_device_attach(netdev);
+       ret = lan743x_csr_read(adapter, MAC_WK_SRC);
+       netif_info(adapter, drv, adapter->netdev,
+                  "Wakeup source : 0x%08X\n", ret);
 
        return 0;
 }
 
        return 0;
 }
index 1ca5f32..5d37263 100644 (file)
 #define STRAP_READ_ADV_PM_DISABLE_     BIT(0)
 
 #define HW_CFG                                 (0x010)
 #define STRAP_READ_ADV_PM_DISABLE_     BIT(0)
 
 #define HW_CFG                                 (0x010)
+#define HW_CFG_RST_PROTECT_PCIE_               BIT(19)
+#define HW_CFG_HOT_RESET_DIS_                  BIT(15)
+#define HW_CFG_D3_VAUX_OVR_                    BIT(14)
+#define HW_CFG_D3_RESET_DIS_                   BIT(13)
+#define HW_CFG_RST_PROTECT_                    BIT(12)
 #define HW_CFG_RELOAD_TYPE_ALL_                        (0x00000FC0)
 #define HW_CFG_EE_OTP_RELOAD_                  BIT(4)
 #define HW_CFG_LRST_                           BIT(1)
 #define HW_CFG_RELOAD_TYPE_ALL_                        (0x00000FC0)
 #define HW_CFG_EE_OTP_RELOAD_                  BIT(4)
 #define HW_CFG_LRST_                           BIT(1)
 #define MAC_EEE_TX_LPI_REQ_DLY_CNT             (0x130)
 
 #define MAC_WUCSR                              (0x140)
 #define MAC_EEE_TX_LPI_REQ_DLY_CNT             (0x130)
 
 #define MAC_WUCSR                              (0x140)
+#define MAC_MP_SO_EN_                          BIT(21)
 #define MAC_WUCSR_RFE_WAKE_EN_                 BIT(14)
 #define MAC_WUCSR_PFDA_EN_                     BIT(3)
 #define MAC_WUCSR_WAKE_EN_                     BIT(2)
 #define MAC_WUCSR_RFE_WAKE_EN_                 BIT(14)
 #define MAC_WUCSR_PFDA_EN_                     BIT(3)
 #define MAC_WUCSR_WAKE_EN_                     BIT(2)
 #define MAC_WUCSR_BCST_EN_                     BIT(0)
 
 #define MAC_WK_SRC                             (0x144)
 #define MAC_WUCSR_BCST_EN_                     BIT(0)
 
 #define MAC_WK_SRC                             (0x144)
+#define MAC_MP_SO_HI                           (0x148)
+#define MAC_MP_SO_LO                           (0x14C)
 
 #define MAC_WUF_CFG0                   (0x150)
 #define MAC_NUM_OF_WUF_CFG             (32)
 
 #define MAC_WUF_CFG0                   (0x150)
 #define MAC_NUM_OF_WUF_CFG             (32)
@@ -912,6 +920,7 @@ struct lan743x_adapter {
        int                     msg_enable;
 #ifdef CONFIG_PM
        u32                     wolopts;
        int                     msg_enable;
 #ifdef CONFIG_PM
        u32                     wolopts;
+       u8                      sopass[SOPASS_MAX];
 #endif
        struct pci_dev          *pdev;
        struct lan743x_csr      csr;
 #endif
        struct pci_dev          *pdev;
        struct lan743x_csr      csr;
@@ -937,6 +946,7 @@ struct lan743x_adapter {
 
 #define LAN743X_ADAPTER_FLAG_OTP               BIT(0)
        u32                     flags;
 
 #define LAN743X_ADAPTER_FLAG_OTP               BIT(0)
        u32                     flags;
+       u32                     hw_cfg;
 };
 
 #define LAN743X_COMPONENT_FLAG_RX(channel)  BIT(20 + (channel))
 };
 
 #define LAN743X_COMPONENT_FLAG_RX(channel)  BIT(20 + (channel))