aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2013-03-06 04:03:02 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2013-03-28 03:25:11 -0400
commitcf8fb73c23aa806c990c8b926f61e60cf6a7bda9 (patch)
treedb1ccf0f76ff2633df09dc504414599dd65c205d
parent1fc06b0aaa66740181b0cbaed6ef514a50dc6171 (diff)
e1000e: add support for LTR on I217/I218
Set the Latency Tolerance Reporting (LTR) values for the "PCIe-like" GbE MAC in the Lynx Point PCH based on Rx buffer size and link speed when link is up (which must not exceed the maximum latency supported by the platform), otherwise specify there is no LTR requirement. Unlike true-PCIe devices which set the LTR maximum snoop/no-snoop latencies in the LTR Extended Capability Structure in the PCIe Extended Capability register set, on this device LTR is set by writing the equivalent snoop/no-snoop latencies in the LTRV register in the MAC and set the SEND bit to send an Intel On-chip System Fabric sideband (IOSF-SB) message to the PMC. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-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