Commit 6b3768ac authored by Raju Lakkaraju's avatar Raju Lakkaraju Committed by Jakub Kicinski

net: lan743x: Add support to Secure-ON WOL

Add support to Magic Packet Detection with Secure-ON for PCI11010/PCI11414 chips
Signed-off-by: default avatarRaju Lakkaraju <Raju.Lakkaraju@microchip.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 9aeb87d2
...@@ -1149,7 +1149,12 @@ static void lan743x_ethtool_get_wol(struct net_device *netdev, ...@@ -1149,7 +1149,12 @@ static void lan743x_ethtool_get_wol(struct net_device *netdev,
wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST | wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST |
WAKE_MAGIC | WAKE_PHY | WAKE_ARP; 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, ...@@ -1170,6 +1175,13 @@ static int lan743x_ethtool_set_wol(struct net_device *netdev,
adapter->wolopts |= WAKE_PHY; adapter->wolopts |= WAKE_PHY;
if (wol->wolopts & WAKE_ARP) if (wol->wolopts & WAKE_ARP)
adapter->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);
......
...@@ -3124,6 +3124,7 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter) ...@@ -3124,6 +3124,7 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter)
const u8 ipv6_multicast[3] = { 0x33, 0x33 }; const u8 ipv6_multicast[3] = { 0x33, 0x33 };
const u8 arp_type[2] = { 0x08, 0x06 }; const u8 arp_type[2] = { 0x08, 0x06 };
int mask_index; int mask_index;
u32 sopass;
u32 pmtctl; u32 pmtctl;
u32 wucsr; u32 wucsr;
u32 macrx; u32 macrx;
...@@ -3218,6 +3219,14 @@ static void lan743x_pm_set_wol(struct lan743x_adapter *adapter) ...@@ -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, MAC_WUCSR, wucsr);
lan743x_csr_write(adapter, PMT_CTL, pmtctl); lan743x_csr_write(adapter, PMT_CTL, pmtctl);
lan743x_csr_write(adapter, MAC_RX, macrx); lan743x_csr_write(adapter, MAC_RX, macrx);
...@@ -3228,6 +3237,7 @@ static int lan743x_pm_suspend(struct device *dev) ...@@ -3228,6 +3237,7 @@ static int lan743x_pm_suspend(struct device *dev)
struct pci_dev *pdev = to_pci_dev(dev); struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct lan743x_adapter *adapter = netdev_priv(netdev); 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) ...@@ -3239,6 +3249,18 @@ static int lan743x_pm_suspend(struct device *dev)
if (adapter->wolopts) if (adapter->wolopts)
lan743x_pm_set_wol(adapter); 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 */ /* Host sets PME_En, put D3hot */
return pci_prepare_to_sleep(pdev); return pci_prepare_to_sleep(pdev);
} }
...@@ -3254,6 +3276,10 @@ static int lan743x_pm_resume(struct device *dev) ...@@ -3254,6 +3276,10 @@ static int lan743x_pm_resume(struct device *dev)
pci_restore_state(pdev); pci_restore_state(pdev);
pci_save_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); ret = lan743x_hardware_init(adapter, pdev);
if (ret) { if (ret) {
netif_err(adapter, probe, adapter->netdev, netif_err(adapter, probe, adapter->netdev,
...@@ -3270,6 +3296,9 @@ static int lan743x_pm_resume(struct device *dev) ...@@ -3270,6 +3296,9 @@ static int lan743x_pm_resume(struct device *dev)
lan743x_netdev_open(netdev); lan743x_netdev_open(netdev);
netif_device_attach(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;
} }
......
...@@ -43,6 +43,11 @@ ...@@ -43,6 +43,11 @@
#define STRAP_READ_ADV_PM_DISABLE_ BIT(0) #define STRAP_READ_ADV_PM_DISABLE_ BIT(0)
#define HW_CFG (0x010) #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_RELOAD_TYPE_ALL_ (0x00000FC0)
#define HW_CFG_EE_OTP_RELOAD_ BIT(4) #define HW_CFG_EE_OTP_RELOAD_ BIT(4)
#define HW_CFG_LRST_ BIT(1) #define HW_CFG_LRST_ BIT(1)
...@@ -214,6 +219,7 @@ ...@@ -214,6 +219,7 @@
#define MAC_EEE_TX_LPI_REQ_DLY_CNT (0x130) #define MAC_EEE_TX_LPI_REQ_DLY_CNT (0x130)
#define MAC_WUCSR (0x140) #define MAC_WUCSR (0x140)
#define MAC_MP_SO_EN_ BIT(21)
#define MAC_WUCSR_RFE_WAKE_EN_ BIT(14) #define MAC_WUCSR_RFE_WAKE_EN_ BIT(14)
#define MAC_WUCSR_PFDA_EN_ BIT(3) #define MAC_WUCSR_PFDA_EN_ BIT(3)
#define MAC_WUCSR_WAKE_EN_ BIT(2) #define MAC_WUCSR_WAKE_EN_ BIT(2)
...@@ -221,6 +227,8 @@ ...@@ -221,6 +227,8 @@
#define MAC_WUCSR_BCST_EN_ BIT(0) #define MAC_WUCSR_BCST_EN_ BIT(0)
#define MAC_WK_SRC (0x144) #define MAC_WK_SRC (0x144)
#define MAC_MP_SO_HI (0x148)
#define MAC_MP_SO_LO (0x14C)
#define MAC_WUF_CFG0 (0x150) #define MAC_WUF_CFG0 (0x150)
#define MAC_NUM_OF_WUF_CFG (32) #define MAC_NUM_OF_WUF_CFG (32)
...@@ -912,6 +920,7 @@ struct lan743x_adapter { ...@@ -912,6 +920,7 @@ struct lan743x_adapter {
int msg_enable; int msg_enable;
#ifdef CONFIG_PM #ifdef CONFIG_PM
u32 wolopts; u32 wolopts;
u8 sopass[SOPASS_MAX];
#endif #endif
struct pci_dev *pdev; struct pci_dev *pdev;
struct lan743x_csr csr; struct lan743x_csr csr;
...@@ -937,6 +946,7 @@ struct lan743x_adapter { ...@@ -937,6 +946,7 @@ struct lan743x_adapter {
#define LAN743X_ADAPTER_FLAG_OTP BIT(0) #define LAN743X_ADAPTER_FLAG_OTP BIT(0)
u32 flags; u32 flags;
u32 hw_cfg;
}; };
#define LAN743X_COMPONENT_FLAG_RX(channel) BIT(20 + (channel)) #define LAN743X_COMPONENT_FLAG_RX(channel) BIT(20 + (channel))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment