@@ -6294,6 +6294,174 @@ static void e1000e_flush_lpic(struct pci_dev *pdev)
62946294 pm_runtime_put_sync (netdev -> dev .parent );
62956295}
62966296
6297+ /* S0ix implementation */
6298+ static void e1000e_s0ix_entry_flow (struct e1000_adapter * adapter )
6299+ {
6300+ struct e1000_hw * hw = & adapter -> hw ;
6301+ u32 mac_data ;
6302+ u16 phy_data ;
6303+
6304+ /* Disable the periodic inband message,
6305+ * don't request PCIe clock in K1 page770_17[10:9] = 10b
6306+ */
6307+ e1e_rphy (hw , HV_PM_CTRL , & phy_data );
6308+ phy_data &= ~HV_PM_CTRL_K1_CLK_REQ ;
6309+ phy_data |= BIT (10 );
6310+ e1e_wphy (hw , HV_PM_CTRL , phy_data );
6311+
6312+ /* Make sure we don't exit K1 every time a new packet arrives
6313+ * 772_29[5] = 1 CS_Mode_Stay_In_K1
6314+ */
6315+ e1e_rphy (hw , I217_CGFREG , & phy_data );
6316+ phy_data |= BIT (5 );
6317+ e1e_wphy (hw , I217_CGFREG , phy_data );
6318+
6319+ /* Change the MAC/PHY interface to SMBus
6320+ * Force the SMBus in PHY page769_23[0] = 1
6321+ * Force the SMBus in MAC CTRL_EXT[11] = 1
6322+ */
6323+ e1e_rphy (hw , CV_SMB_CTRL , & phy_data );
6324+ phy_data |= CV_SMB_CTRL_FORCE_SMBUS ;
6325+ e1e_wphy (hw , CV_SMB_CTRL , phy_data );
6326+ mac_data = er32 (CTRL_EXT );
6327+ mac_data |= E1000_CTRL_EXT_FORCE_SMBUS ;
6328+ ew32 (CTRL_EXT , mac_data );
6329+
6330+ /* DFT control: PHY bit: page769_20[0] = 1
6331+ * Gate PPW via EXTCNF_CTRL - set 0x0F00[7] = 1
6332+ */
6333+ e1e_rphy (hw , I82579_DFT_CTRL , & phy_data );
6334+ phy_data |= BIT (0 );
6335+ e1e_wphy (hw , I82579_DFT_CTRL , phy_data );
6336+
6337+ mac_data = er32 (EXTCNF_CTRL );
6338+ mac_data |= E1000_EXTCNF_CTRL_GATE_PHY_CFG ;
6339+ ew32 (EXTCNF_CTRL , mac_data );
6340+
6341+ /* Check MAC Tx/Rx packet buffer pointers.
6342+ * Reset MAC Tx/Rx packet buffer pointers to suppress any
6343+ * pending traffic indication that would prevent power gating.
6344+ */
6345+ mac_data = er32 (TDFH );
6346+ if (mac_data )
6347+ ew32 (TDFH , 0 );
6348+ mac_data = er32 (TDFT );
6349+ if (mac_data )
6350+ ew32 (TDFT , 0 );
6351+ mac_data = er32 (TDFHS );
6352+ if (mac_data )
6353+ ew32 (TDFHS , 0 );
6354+ mac_data = er32 (TDFTS );
6355+ if (mac_data )
6356+ ew32 (TDFTS , 0 );
6357+ mac_data = er32 (TDFPC );
6358+ if (mac_data )
6359+ ew32 (TDFPC , 0 );
6360+ mac_data = er32 (RDFH );
6361+ if (mac_data )
6362+ ew32 (RDFH , 0 );
6363+ mac_data = er32 (RDFT );
6364+ if (mac_data )
6365+ ew32 (RDFT , 0 );
6366+ mac_data = er32 (RDFHS );
6367+ if (mac_data )
6368+ ew32 (RDFHS , 0 );
6369+ mac_data = er32 (RDFTS );
6370+ if (mac_data )
6371+ ew32 (RDFTS , 0 );
6372+ mac_data = er32 (RDFPC );
6373+ if (mac_data )
6374+ ew32 (RDFPC , 0 );
6375+
6376+ /* Enable the Dynamic Power Gating in the MAC */
6377+ mac_data = er32 (FEXTNVM7 );
6378+ mac_data |= BIT (22 );
6379+ ew32 (FEXTNVM7 , mac_data );
6380+
6381+ /* Disable the time synchronization clock */
6382+ mac_data = er32 (FEXTNVM7 );
6383+ mac_data |= BIT (31 );
6384+ mac_data &= ~BIT (0 );
6385+ ew32 (FEXTNVM7 , mac_data );
6386+
6387+ /* Dynamic Power Gating Enable */
6388+ mac_data = er32 (CTRL_EXT );
6389+ mac_data |= BIT (3 );
6390+ ew32 (CTRL_EXT , mac_data );
6391+
6392+ /* Enable the Dynamic Clock Gating in the DMA and MAC */
6393+ mac_data = er32 (CTRL_EXT );
6394+ mac_data |= E1000_CTRL_EXT_DMA_DYN_CLK_EN ;
6395+ ew32 (CTRL_EXT , mac_data );
6396+
6397+ /* No MAC DPG gating SLP_S0 in modern standby
6398+ * Switch the logic of the lanphypc to use PMC counter
6399+ */
6400+ mac_data = er32 (FEXTNVM5 );
6401+ mac_data |= BIT (7 );
6402+ ew32 (FEXTNVM5 , mac_data );
6403+ }
6404+
6405+ static void e1000e_s0ix_exit_flow (struct e1000_adapter * adapter )
6406+ {
6407+ struct e1000_hw * hw = & adapter -> hw ;
6408+ u32 mac_data ;
6409+ u16 phy_data ;
6410+
6411+ /* Disable the Dynamic Power Gating in the MAC */
6412+ mac_data = er32 (FEXTNVM7 );
6413+ mac_data &= 0xFFBFFFFF ;
6414+ ew32 (FEXTNVM7 , mac_data );
6415+
6416+ /* Enable the time synchronization clock */
6417+ mac_data = er32 (FEXTNVM7 );
6418+ mac_data |= BIT (0 );
6419+ ew32 (FEXTNVM7 , mac_data );
6420+
6421+ /* Disable Dynamic Power Gating */
6422+ mac_data = er32 (CTRL_EXT );
6423+ mac_data &= 0xFFFFFFF7 ;
6424+ ew32 (CTRL_EXT , mac_data );
6425+
6426+ /* Disable the Dynamic Clock Gating in the DMA and MAC */
6427+ mac_data = er32 (CTRL_EXT );
6428+ mac_data &= 0xFFF7FFFF ;
6429+ ew32 (CTRL_EXT , mac_data );
6430+
6431+ /* Revert the lanphypc logic to use the internal Gbe counter
6432+ * and not the PMC counter
6433+ */
6434+ mac_data = er32 (FEXTNVM5 );
6435+ mac_data &= 0xFFFFFF7F ;
6436+ ew32 (FEXTNVM5 , mac_data );
6437+
6438+ /* Enable the periodic inband message,
6439+ * Request PCIe clock in K1 page770_17[10:9] =01b
6440+ */
6441+ e1e_rphy (hw , HV_PM_CTRL , & phy_data );
6442+ phy_data &= 0xFBFF ;
6443+ phy_data |= HV_PM_CTRL_K1_CLK_REQ ;
6444+ e1e_wphy (hw , HV_PM_CTRL , phy_data );
6445+
6446+ /* Return back configuration
6447+ * 772_29[5] = 0 CS_Mode_Stay_In_K1
6448+ */
6449+ e1e_rphy (hw , I217_CGFREG , & phy_data );
6450+ phy_data &= 0xFFDF ;
6451+ e1e_wphy (hw , I217_CGFREG , phy_data );
6452+
6453+ /* Change the MAC/PHY interface to Kumeran
6454+ * Unforce the SMBus in PHY page769_23[0] = 0
6455+ * Unforce the SMBus in MAC CTRL_EXT[11] = 0
6456+ */
6457+ e1e_rphy (hw , CV_SMB_CTRL , & phy_data );
6458+ phy_data &= ~CV_SMB_CTRL_FORCE_SMBUS ;
6459+ e1e_wphy (hw , CV_SMB_CTRL , phy_data );
6460+ mac_data = er32 (CTRL_EXT );
6461+ mac_data &= ~E1000_CTRL_EXT_FORCE_SMBUS ;
6462+ ew32 (CTRL_EXT , mac_data );
6463+ }
6464+
62976465static int e1000e_pm_freeze (struct device * dev )
62986466{
62996467 struct net_device * netdev = dev_get_drvdata (dev );
@@ -6649,7 +6817,10 @@ static int e1000e_pm_thaw(struct device *dev)
66496817
66506818static int e1000e_pm_suspend (struct device * dev )
66516819{
6820+ struct net_device * netdev = pci_get_drvdata (to_pci_dev (dev ));
6821+ struct e1000_adapter * adapter = netdev_priv (netdev );
66526822 struct pci_dev * pdev = to_pci_dev (dev );
6823+ struct e1000_hw * hw = & adapter -> hw ;
66536824 int rc ;
66546825
66556826 e1000e_flush_lpic (pdev );
@@ -6660,14 +6831,25 @@ static int e1000e_pm_suspend(struct device *dev)
66606831 if (rc )
66616832 e1000e_pm_thaw (dev );
66626833
6834+ /* Introduce S0ix implementation */
6835+ if (hw -> mac .type >= e1000_pch_cnp )
6836+ e1000e_s0ix_entry_flow (adapter );
6837+
66636838 return rc ;
66646839}
66656840
66666841static int e1000e_pm_resume (struct device * dev )
66676842{
6843+ struct net_device * netdev = pci_get_drvdata (to_pci_dev (dev ));
6844+ struct e1000_adapter * adapter = netdev_priv (netdev );
66686845 struct pci_dev * pdev = to_pci_dev (dev );
6846+ struct e1000_hw * hw = & adapter -> hw ;
66696847 int rc ;
66706848
6849+ /* Introduce S0ix implementation */
6850+ if (hw -> mac .type >= e1000_pch_cnp )
6851+ e1000e_s0ix_exit_flow (adapter );
6852+
66716853 rc = __e1000_resume (pdev );
66726854 if (rc )
66736855 return rc ;
0 commit comments