Skip to content

Commit 5d54cb1

Browse files
github-cygwinkuba-moo
authored andcommitted
igb: conditionalize I2C bit banging on external thermal sensor support
Commit a97f878 ("igb: unbreak I2C bit-banging on i350") introduced code to change I2C settings to bit banging unconditionally. However, this patch introduced a regression: On an Intel S2600CWR Server Board with three NICs: - 1x dual-port copper Intel I350 Gigabit Network Connection [8086:1521] (rev 01) fw 1.63, 0x80000dda - 2x quad-port SFP+ with copper SFP Avago ABCU-5700RZ Intel I350 Gigabit Fiber Network Connection [8086:1522] (rev 01) fw 1.52.0 the SFP NICs no longer get link at all. Reverting commit a97f878 or switching to the Intel out-of-tree driver both fix the problem. Per the igb out-of-tree driver, I2C bit banging on i350 depends on support for an external thermal sensor (ETS). However, commit a97f878 added bit banging unconditionally. Additionally, the out-of-tree driver always calls init_thermal_sensor_thresh on probe, while our driver only calls init_thermal_sensor_thresh only in igb_reset(), and only if an ETS is present, ignoring the internal thermal sensor. The affected SFPs don't provide an ETS. Per Intel, the behaviour is a result of i350 firmware requirements. This patch fixes the problem by aligning the behaviour to the out-of-tree driver: - split igb_init_i2c() into two functions: - igb_init_i2c() only performs the basic I2C initialization. - igb_set_i2c_bb() makes sure that E1000_CTRL_I2C_ENA is set and enables bit-banging. - igb_probe() only calls igb_set_i2c_bb() if an ETS is present. - igb_probe() calls init_thermal_sensor_thresh() unconditionally. - igb_reset() aligns its behaviour to igb_probe(), i. e., call igb_set_i2c_bb() if an ETS is present and call init_thermal_sensor_thresh() unconditionally. Fixes: a97f878 ("igb: unbreak I2C bit-banging on i350") Tested-by: Mateusz Palczewski <[email protected]> Co-developed-by: Jamie Bainbridge <[email protected]> Signed-off-by: Jamie Bainbridge <[email protected]> Signed-off-by: Corinna Vinschen <[email protected]> Signed-off-by: Tony Nguyen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent dee4bf7 commit 5d54cb1

File tree

1 file changed

+32
-10
lines changed

1 file changed

+32
-10
lines changed

drivers/net/ethernet/intel/igb/igb_main.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,6 +2256,30 @@ static void igb_enable_mas(struct igb_adapter *adapter)
22562256
}
22572257
}
22582258

2259+
#ifdef CONFIG_IGB_HWMON
2260+
/**
2261+
* igb_set_i2c_bb - Init I2C interface
2262+
* @hw: pointer to hardware structure
2263+
**/
2264+
static void igb_set_i2c_bb(struct e1000_hw *hw)
2265+
{
2266+
u32 ctrl_ext;
2267+
s32 i2cctl;
2268+
2269+
ctrl_ext = rd32(E1000_CTRL_EXT);
2270+
ctrl_ext |= E1000_CTRL_I2C_ENA;
2271+
wr32(E1000_CTRL_EXT, ctrl_ext);
2272+
wrfl();
2273+
2274+
i2cctl = rd32(E1000_I2CPARAMS);
2275+
i2cctl |= E1000_I2CBB_EN
2276+
| E1000_I2C_CLK_OE_N
2277+
| E1000_I2C_DATA_OE_N;
2278+
wr32(E1000_I2CPARAMS, i2cctl);
2279+
wrfl();
2280+
}
2281+
#endif
2282+
22592283
void igb_reset(struct igb_adapter *adapter)
22602284
{
22612285
struct pci_dev *pdev = adapter->pdev;
@@ -2400,7 +2424,8 @@ void igb_reset(struct igb_adapter *adapter)
24002424
* interface.
24012425
*/
24022426
if (adapter->ets)
2403-
mac->ops.init_thermal_sensor_thresh(hw);
2427+
igb_set_i2c_bb(hw);
2428+
mac->ops.init_thermal_sensor_thresh(hw);
24042429
}
24052430
}
24062431
#endif
@@ -3117,21 +3142,12 @@ static void igb_init_mas(struct igb_adapter *adapter)
31173142
**/
31183143
static s32 igb_init_i2c(struct igb_adapter *adapter)
31193144
{
3120-
struct e1000_hw *hw = &adapter->hw;
31213145
s32 status = 0;
3122-
s32 i2cctl;
31233146

31243147
/* I2C interface supported on i350 devices */
31253148
if (adapter->hw.mac.type != e1000_i350)
31263149
return 0;
31273150

3128-
i2cctl = rd32(E1000_I2CPARAMS);
3129-
i2cctl |= E1000_I2CBB_EN
3130-
| E1000_I2C_CLK_OUT | E1000_I2C_CLK_OE_N
3131-
| E1000_I2C_DATA_OUT | E1000_I2C_DATA_OE_N;
3132-
wr32(E1000_I2CPARAMS, i2cctl);
3133-
wrfl();
3134-
31353151
/* Initialize the i2c bus which is controlled by the registers.
31363152
* This bus will use the i2c_algo_bit structure that implements
31373153
* the protocol through toggling of the 4 bits in the register.
@@ -3521,6 +3537,12 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
35213537
adapter->ets = true;
35223538
else
35233539
adapter->ets = false;
3540+
/* Only enable I2C bit banging if an external thermal
3541+
* sensor is supported.
3542+
*/
3543+
if (adapter->ets)
3544+
igb_set_i2c_bb(hw);
3545+
hw->mac.ops.init_thermal_sensor_thresh(hw);
35243546
if (igb_sysfs_init(adapter))
35253547
dev_err(&pdev->dev,
35263548
"failed to allocate sysfs resources\n");

0 commit comments

Comments
 (0)