aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 56c4935b2578..ad9d8f2dd868 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -839,6 +839,94 @@ release:
839} 839}
840 840
841/** 841/**
842 * e1000_platform_pm_pch_lpt - Set platform power management values
843 * @hw: pointer to the HW structure
844 * @link: bool indicating link status
845 *
846 * Set the Latency Tolerance Reporting (LTR) values for the "PCIe-like"
847 * GbE MAC in the Lynx Point PCH based on Rx buffer size and link speed
848 * when link is up (which must not exceed the maximum latency supported
849 * by the platform), otherwise specify there is no LTR requirement.
850 * Unlike true-PCIe devices which set the LTR maximum snoop/no-snoop
851 * latencies in the LTR Extended Capability Structure in the PCIe Extended
852 * Capability register set, on this device LTR is set by writing the
853 * equivalent snoop/no-snoop latencies in the LTRV register in the MAC and
854 * set the SEND bit to send an Intel On-chip System Fabric sideband (IOSF-SB)
855 * message to the PMC.
856 **/
857static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link)
858{
859 u32 reg = link << (E1000_LTRV_REQ_SHIFT + E1000_LTRV_NOSNOOP_SHIFT) |
860 link << E1000_LTRV_REQ_SHIFT | E1000_LTRV_SEND;
861 u16 lat_enc = 0; /* latency encoded */
862
863 if (link) {
864 u16 speed, duplex, scale = 0;
865 u16 max_snoop, max_nosnoop;
866 u16 max_ltr_enc; /* max LTR latency encoded */
867 s64 lat_ns; /* latency (ns) */
868 s64 value;
869 u32 rxa;
870
871 if (!hw->adapter->max_frame_size) {
872 e_dbg("max_frame_size not set.\n");
873 return -E1000_ERR_CONFIG;
874 }
875
876 hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
877 if (!speed) {
878 e_dbg("Speed not set.\n");
879 return -E1000_ERR_CONFIG;
880 }
881
882 /* Rx Packet Buffer Allocation size (KB) */
883 rxa = er32(PBA) & E1000_PBA_RXA_MASK;
884
885 /* Determine the maximum latency tolerated by the device.
886 *
887 * Per the PCIe spec, the tolerated latencies are encoded as
888 * a 3-bit encoded scale (only 0-5 are valid) multiplied by
889 * a 10-bit value (0-1023) to provide a range from 1 ns to
890 * 2^25*(2^10-1) ns. The scale is encoded as 0=2^0ns,
891 * 1=2^5ns, 2=2^10ns,...5=2^25ns.
892 */
893 lat_ns = ((s64)rxa * 1024 -
894 (2 * (s64)hw->adapter->max_frame_size)) * 8 * 1000;
895 if (lat_ns < 0)
896 lat_ns = 0;
897 else
898 do_div(lat_ns, speed);
899
900 value = lat_ns;
901 while (value > PCI_LTR_VALUE_MASK) {
902 scale++;
903 value = DIV_ROUND_UP(value, (1 << 5));
904 }
905 if (scale > E1000_LTRV_SCALE_MAX) {
906 e_dbg("Invalid LTR latency scale %d\n", scale);
907 return -E1000_ERR_CONFIG;
908 }
909 lat_enc = (u16)((scale << PCI_LTR_SCALE_SHIFT) | value);
910
911 /* Determine the maximum latency tolerated by the platform */
912 pci_read_config_word(hw->adapter->pdev, E1000_PCI_LTR_CAP_LPT,
913 &max_snoop);
914 pci_read_config_word(hw->adapter->pdev,
915 E1000_PCI_LTR_CAP_LPT + 2, &max_nosnoop);
916 max_ltr_enc = max_t(u16, max_snoop, max_nosnoop);
917
918 if (lat_enc > max_ltr_enc)
919 lat_enc = max_ltr_enc;
920 }
921
922 /* Set Snoop and No-Snoop latencies the same */
923 reg |= lat_enc | (lat_enc << E1000_LTRV_NOSNOOP_SHIFT);
924 ew32(LTRV, reg);
925
926 return 0;
927}
928
929/**
842 * e1000_check_for_copper_link_ich8lan - Check for link (Copper) 930 * e1000_check_for_copper_link_ich8lan - Check for link (Copper)
843 * @hw: pointer to the HW structure 931 * @hw: pointer to the HW structure
844 * 932 *
@@ -911,6 +999,15 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
911 return ret_val; 999 return ret_val;
912 } 1000 }
913 1001
1002 if (hw->mac.type == e1000_pch_lpt) {
1003 /* Set platform power management values for
1004 * Latency Tolerance Reporting (LTR)
1005 */
1006 ret_val = e1000_platform_pm_pch_lpt(hw, link);
1007 if (ret_val)
1008 return ret_val;
1009 }
1010
914 /* Clear link partner's EEE ability */ 1011 /* Clear link partner's EEE ability */
915 hw->dev_spec.ich8lan.eee_lp_ability = 0; 1012 hw->dev_spec.ich8lan.eee_lp_ability = 0;
916 1013