Page MenuHomeFreeBSD

sff: add a shared EEPROM read helper and build sff(4) as a module
Needs RevisionPublic

Authored by yarshure_gmail.com on Sun, Sep 27, 1:37 PM.
Tags
None
Referenced Files
F173973144: D60066.id.diff
Tue, Sep 29, 5:46 PM
Unknown Object (File)
Mon, Sep 28, 12:23 PM
Unknown Object (File)
Mon, Sep 28, 3:57 AM
Unknown Object (File)
Mon, Sep 28, 3:49 AM
Unknown Object (File)
Sun, Sep 27, 11:36 PM
Unknown Object (File)
Sun, Sep 27, 11:21 PM
Subscribers

Details

Reviewers
mmel
Summary

sff(4) declared a get_i2c_bus method and an FDT front-end, but nothing that
actually reads a transceiver's EEPROM, so a consumer had to open-code the
i2c exchange. Add sff_read_eeprom(), which writes the byte offset and reads
the data back in one bus-held exchange (a repeat-start), so nothing else can
move the EEPROM's internal address pointer between the two halves. Holding
the bus across both messages also keeps an i2c mux upstream pointed at this
device throughout: iicbus(4) switches the mux as part of granting the bus,
and would switch it away for another consumer if we let go in between.

dev_addr is the slave address in the form iic_msg(9) uses -- the 7-bit
address shifted left by one -- which for an SFF-8472 module is 0xa0 for the
base page and 0xa2 for the diagnostics page. That is also the form
SIOCGI2C's struct ifi2creq carries, so a NIC driver passes on what it was
given.

A bus request needs an owner sitting on the bus being requested. A front-end
that is itself an i2c slave passes itself; one that only holds a reference to
the bus has to borrow a device on it, so add sff_i2c_requester() for that and
use it from the FDT front-end.

Give both kobj methods a DEFAULT returning ENXIO. kobj(9) turns a method a
class does not implement into a call to kobj_error_method(), and a front-end
may well be able to read the EEPROM but have no way to reach the module's
control lines, or the reverse.

Finally, make the module build match: sff.c was added to sys/conf/files but
not to the module's SRCS, so sff.ko carried neither sff_read_eeprom() nor its
own module record -- which means a MODULE_DEPEND on sff could never be
satisfied and any consumer would fail to load. EXPORT_SYMS is needed for the
same reason: sff(4) exists to be consumed, and kmod.mk localises every symbol
by default, including the kobj method descriptors.

Depends on D60065

Test Plan

arm64 GENERIC, and a variant with sff/dpaa2/pca954x/iicmux as modules.

The module side is what matters here and the static build does not cover it.
sff.ko now carries sff_read_eeprom() and its own module record, so a
MODULE_DEPEND on sff is satisfiable and "kldload sff" works. Checked
mechanically across every module in GENERIC: each .ko's undefined symbols
resolve against the kernel or another module, and all 2334 MODULE_DEPEND
records are satisfiable.

The read path itself is exercised by the last commit in this series. On a
SolidRun CEX7 (NXP LX2160A) two 10G SFP+ modules read correctly, including
150 concurrent reads per cage against the same PCA9547 with no cross-talk.

I have no FDT dpaa2 hardware. The change to the FDT front-end here is the
move to the shared requester helper, which does the same
device_find_child(i2c_bus, "iic", ...) lookup it did inline before.

Diff Detail

Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

mmel requested changes to this revision.Mon, Sep 28, 8:25 AM
mmel added a subscriber: mmel.

This is another gross hack. In theory, we could add read and write functions to this device to access EEPROM context. However, publishing raw EEPROM context outside of this device context would break all layering rules and is therefore nonsense.

This revision now requires changes to proceed.Mon, Sep 28, 8:25 AM