Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 945a5151 authored by Jesse Brandeburg's avatar Jesse Brandeburg Committed by Jeff Kirsher
Browse files

intel drivers: repair missing flush operations



after review of all intel drivers, found several instances where
drivers had the incorrect pattern of:
memory mapped write();
delay();

which should always be:
memory mapped write();
write flush(); /* aka memory mapped read */
delay();

explanation:
The reason for including the flush is that writes can be held
(posted) in PCI/PCIe bridges, but the read always has to complete
synchronously and therefore has to flush all pending writes to a
device.  If a write is held and followed by a delay, the delay
means nothing because the write may not have reached hardware
(maybe even not until the next read)

Signed-off-by: default avatarJesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: default avatarAaron Brown <aaron.f.brown@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent d3e61457
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -838,6 +838,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)

	/* Disable all the interrupts */
	ew32(IMC, 0xFFFFFFFF);
	E1000_WRITE_FLUSH();
	msleep(10);

	/* Test each interrupt */
@@ -856,6 +857,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
			adapter->test_icr = 0;
			ew32(IMC, mask);
			ew32(ICS, mask);
			E1000_WRITE_FLUSH();
			msleep(10);

			if (adapter->test_icr & mask) {
@@ -873,6 +875,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
		adapter->test_icr = 0;
		ew32(IMS, mask);
		ew32(ICS, mask);
		E1000_WRITE_FLUSH();
		msleep(10);

		if (!(adapter->test_icr & mask)) {
@@ -890,6 +893,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
			adapter->test_icr = 0;
			ew32(IMC, ~mask & 0x00007FFF);
			ew32(ICS, ~mask & 0x00007FFF);
			E1000_WRITE_FLUSH();
			msleep(10);

			if (adapter->test_icr) {
@@ -901,6 +905,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)

	/* Disable all the interrupts */
	ew32(IMC, 0xFFFFFFFF);
	E1000_WRITE_FLUSH();
	msleep(10);

	/* Unhook test interrupt handler */
@@ -1394,6 +1399,7 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)
			if (unlikely(++k == txdr->count)) k = 0;
		}
		ew32(TDT, k);
		E1000_WRITE_FLUSH();
		msleep(200);
		time = jiffies; /* set the start time for the receive */
		good_cnt = 0;
+3 −0
Original line number Diff line number Diff line
@@ -446,6 +446,7 @@ s32 e1000_reset_hw(struct e1000_hw *hw)
	/* Must reset the PHY before resetting the MAC */
	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
		ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST));
		E1000_WRITE_FLUSH();
		msleep(5);
	}

@@ -3752,6 +3753,7 @@ static s32 e1000_acquire_eeprom(struct e1000_hw *hw)
		/* Clear SK and CS */
		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
		ew32(EECD, eecd);
		E1000_WRITE_FLUSH();
		udelay(1);
	}

@@ -3824,6 +3826,7 @@ static void e1000_release_eeprom(struct e1000_hw *hw)
		eecd &= ~E1000_EECD_SK;	/* Lower SCK */

		ew32(EECD, eecd);
		E1000_WRITE_FLUSH();

		udelay(hw->eeprom.delay_usec);
	} else if (hw->eeprom.type == e1000_eeprom_microwire) {
+2 −0
Original line number Diff line number Diff line
@@ -1313,6 +1313,7 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
	               E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
	ew32(KMRNCTRLSTA, kmrnctrlsta);
	e1e_flush();

	udelay(2);

@@ -1347,6 +1348,7 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
	               E1000_KMRNCTRLSTA_OFFSET) | data;
	ew32(KMRNCTRLSTA, kmrnctrlsta);
	e1e_flush();

	udelay(2);

+9 −0
Original line number Diff line number Diff line
@@ -964,6 +964,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)

	/* Disable all the interrupts */
	ew32(IMC, 0xFFFFFFFF);
	e1e_flush();
	usleep_range(10000, 20000);

	/* Test each interrupt */
@@ -996,6 +997,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
			adapter->test_icr = 0;
			ew32(IMC, mask);
			ew32(ICS, mask);
			e1e_flush();
			usleep_range(10000, 20000);

			if (adapter->test_icr & mask) {
@@ -1014,6 +1016,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
		adapter->test_icr = 0;
		ew32(IMS, mask);
		ew32(ICS, mask);
		e1e_flush();
		usleep_range(10000, 20000);

		if (!(adapter->test_icr & mask)) {
@@ -1032,6 +1035,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
			adapter->test_icr = 0;
			ew32(IMC, ~mask & 0x00007FFF);
			ew32(ICS, ~mask & 0x00007FFF);
			e1e_flush();
			usleep_range(10000, 20000);

			if (adapter->test_icr) {
@@ -1043,6 +1047,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)

	/* Disable all the interrupts */
	ew32(IMC, 0xFFFFFFFF);
	e1e_flush();
	usleep_range(10000, 20000);

	/* Unhook test interrupt handler */
@@ -1276,6 +1281,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
			     E1000_CTRL_FD);	 /* Force Duplex to FULL */

		ew32(CTRL, ctrl_reg);
		e1e_flush();
		udelay(500);

		return 0;
@@ -1418,6 +1424,7 @@ static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter)
	 */
#define E1000_SERDES_LB_ON 0x410
	ew32(SCTL, E1000_SERDES_LB_ON);
	e1e_flush();
	usleep_range(10000, 20000);

	return 0;
@@ -1513,6 +1520,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
		    hw->phy.media_type == e1000_media_type_internal_serdes) {
#define E1000_SERDES_LB_OFF 0x400
			ew32(SCTL, E1000_SERDES_LB_OFF);
			e1e_flush();
			usleep_range(10000, 20000);
			break;
		}
@@ -1592,6 +1600,7 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)
				k = 0;
		}
		ew32(TDT, k);
		e1e_flush();
		msleep(200);
		time = jiffies; /* set the start time for the receive */
		good_cnt = 0;
+4 −0
Original line number Diff line number Diff line
@@ -283,6 +283,7 @@ static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw)
	ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE;
	ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
	ew32(CTRL, ctrl);
	e1e_flush();
	udelay(10);
	ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
	ew32(CTRL, ctrl);
@@ -1230,9 +1231,11 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
	ew32(CTRL, reg);

	ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS);
	e1e_flush();
	udelay(20);
	ew32(CTRL, ctrl_reg);
	ew32(CTRL_EXT, ctrl_ext);
	e1e_flush();
	udelay(20);

out:
@@ -3090,6 +3093,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
	ret_val = e1000_acquire_swflag_ich8lan(hw);
	e_dbg("Issuing a global reset to ich8lan\n");
	ew32(CTRL, (ctrl | E1000_CTRL_RST));
	/* cannot issue a flush here because it hangs the hardware */
	msleep(20);

	if (!ret_val)
Loading