linux/drivers/net/ethernet/intel/igb
Jan Kundrát a97f8783a9 igb: unbreak I2C bit-banging on i350
The driver tried to use Linux' native software I2C bus master
(i2c-algo-bits) for exporting the I2C interface that talks to the SFP
cage(s) towards userspace. As-is, however, the physical SCL/SDA pins
were not moving at all, staying at logical 1 all the time.

The main culprit was the I2CPARAMS register where igb was not setting
the I2CBB_EN bit. That meant that all the careful signal bit-banging was
actually not being propagated to the chip pads (I verified this with a
scope).

The bit-banging was not correct either, because I2C is supposed to be an
open-collector bus, and the code was driving both lines via a totem
pole. The code was also trying to do operations which did not make any
sense with the i2c-algo-bits, namely manipulating both SDA and SCL from
igb_set_i2c_data (which is only supposed to set SDA). I'm not sure if
that was meant as an optimization, or was just flat out wrong, but given
that the i2c-algo-bits is set up to work with a totally dumb GPIO-ish
implementation underneath, there's no need for this code to be smart.

The open-drain vs. totem-pole is fixed by the usual trick where the
logical zero is implemented via regular output mode and outputting a
logical 0, and the logical high is implemented via the IO pad configured
as an input (thus floating), and letting the mandatory pull-up resistors
do the rest. Anything else is actually wrong on I2C where all devices
are supposed to have open-drain connection to the bus.

The missing I2CBB_EN is set (along with a safe initial value of the
GPIOs) just before registering this software I2C bus.

The chip datasheet mentions HW-implemented I2C transactions (SFP EEPROM
reads and writes) as well, but I'm not touching these for simplicity.

Tested on a LR-Link LRES2203PF-2SFP (which is an almost-miniPCIe form
factor card, a cable, and a module with two SFP cages). There was one
casualty, an old broken SFP we had laying around, which was used to
solder some thin wires as a DIY I2C breakout. Thanks for your service.
With this patch in place, I can `i2cdump -y 3 0x51 c` and read back data
which make sense. Yay.

Signed-off-by: Jan Kundrát <jan.kundrat@cesnet.cz>
See-also: https://www.spinics.net/lists/netdev/msg490554.html
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Tony Brelinski <tony.brelinski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
2021-10-29 09:42:59 -07:00
..
e1000_82575.c igb: Fix -Wunused-const-variable warning 2021-06-01 17:00:51 -07:00
e1000_82575.h igb: Add UDP segmentation offload support 2019-10-29 21:05:33 -07:00
e1000_defines.h igb: Redistribute memory for transmit packet buffers when in Qav mode 2021-04-16 10:42:52 -07:00
e1000_hw.h igb: Fix duplicate include guard 2021-03-19 08:47:46 -07:00
e1000_i210.c intel-ethernet: clean up W=1 warnings in kdoc 2020-09-25 16:28:59 -07:00
e1000_i210.h
e1000_mac.c igb: Add counter to i21x doublecheck 2021-07-23 09:08:11 -07:00
e1000_mac.h
e1000_mbx.c intel: clean up mismatched header comments 2021-03-23 11:34:02 -07:00
e1000_mbx.h
e1000_nvm.c ethernet/intel: Convert fallthrough code comments 2020-07-01 13:47:43 -07:00
e1000_nvm.h
e1000_phy.c igb: Fix fall-through warnings for Clang 2021-03-23 11:34:02 -07:00
e1000_phy.h
e1000_regs.h igb: add RR2DCDELAY to ethtool registers dump 2019-06-28 16:00:06 -07:00
igb_ethtool.c ethtool: extend coalesce setting uAPI with CQE mode 2021-08-24 07:38:29 -07:00
igb_hwmon.c igb: convert to use i2c_new_client_device() 2020-03-26 19:31:21 -07:00
igb_main.c igb: unbreak I2C bit-banging on i350 2021-10-29 09:42:59 -07:00
igb_ptp.c Merge ra.kernel.org:/pub/scm/linux/kernel/git/netdev/net 2021-06-07 13:01:52 -07:00
igb.h igb: Fix XDP with PTP enabled 2021-06-03 08:38:37 -07:00
Makefile