Skip to content

Commit cf8fb73

Browse files
bwallanJeff Kirsher
authored andcommitted
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 <[email protected]> Tested-by: Jeff Pieper <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent 1fc06b0 commit cf8fb73

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

drivers/net/ethernet/intel/e1000e/ich8lan.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,94 @@ static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link)
838838
return ret_val;
839839
}
840840

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+
**/
857+
static 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+
841929
/**
842930
* e1000_check_for_copper_link_ich8lan - Check for link (Copper)
843931
* @hw: pointer to the HW structure
@@ -911,6 +999,15 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
911999
return ret_val;
9121000
}
9131001

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+
9141011
/* Clear link partner's EEE ability */
9151012
hw->dev_spec.ich8lan.eee_lp_ability = 0;
9161013

0 commit comments

Comments
 (0)