Skip to content

Commit

Permalink
phy: sfp: add netlink SFP support to generic SFP code
Browse files Browse the repository at this point in the history
The new netlink API for reading SFP data requires a new op to be
implemented. The idea of the new netlink SFP code is that userspace is
responsible to parsing the EEPROM data and requesting pages, rather
than have the kernel decide what pages are interesting and returning
them. This allows greater flexibility for newer formats.

Currently the generic SFP code only supports simple SFPs. Allow i2c
address 0x50 and 0x51 to be accessed with page and bank must always be
0. This interface will later be extended when for example QSFP support
is added.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Vladyslav Tarasiuk <vladyslavt@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
lunn authored and davem330 committed Apr 11, 2021
1 parent 96d971e commit d740513
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 0 deletions.
20 changes: 20 additions & 0 deletions drivers/net/phy/sfp-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,26 @@ int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee,
}
EXPORT_SYMBOL_GPL(sfp_get_module_eeprom);

/**
* sfp_get_module_eeprom_by_page() - Read a page from the SFP module EEPROM
* @bus: a pointer to the &struct sfp_bus structure for the sfp module
* @page: a &struct ethtool_module_eeprom
* @extack: extack for reporting problems
*
* Read an EEPROM page as specified by the supplied @page. See the
* documentation for &struct ethtool_module_eeprom for the page to be read.
*
* Returns 0 on success or a negative errno number. More error
* information might be provided via extack
*/
int sfp_get_module_eeprom_by_page(struct sfp_bus *bus,
const struct ethtool_module_eeprom *page,
struct netlink_ext_ack *extack)
{
return bus->socket_ops->module_eeprom_by_page(bus->sfp, page, extack);
}
EXPORT_SYMBOL_GPL(sfp_get_module_eeprom_by_page);

/**
* sfp_upstream_start() - Inform the SFP that the network device is up
* @bus: a pointer to the &struct sfp_bus structure for the sfp module
Expand Down
25 changes: 25 additions & 0 deletions drivers/net/phy/sfp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2330,13 +2330,38 @@ static int sfp_module_eeprom(struct sfp *sfp, struct ethtool_eeprom *ee,
return 0;
}

static int sfp_module_eeprom_by_page(struct sfp *sfp,
const struct ethtool_module_eeprom *page,
struct netlink_ext_ack *extack)
{
if (page->bank) {
NL_SET_ERR_MSG(extack, "Banks not supported");
return -EOPNOTSUPP;
}

if (page->page) {
NL_SET_ERR_MSG(extack, "Only page 0 supported");
return -EOPNOTSUPP;
}

if (page->i2c_address != 0x50 &&
page->i2c_address != 0x51) {
NL_SET_ERR_MSG(extack, "Only address 0x50 and 0x51 supported");
return -EOPNOTSUPP;
}

return sfp_read(sfp, page->i2c_address == 0x51, page->offset,
page->data, page->length);
};

static const struct sfp_socket_ops sfp_module_ops = {
.attach = sfp_attach,
.detach = sfp_detach,
.start = sfp_start,
.stop = sfp_stop,
.module_info = sfp_module_info,
.module_eeprom = sfp_module_eeprom,
.module_eeprom_by_page = sfp_module_eeprom_by_page,
};

static void sfp_timeout(struct work_struct *work)
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/phy/sfp.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ struct sfp_socket_ops {
int (*module_info)(struct sfp *sfp, struct ethtool_modinfo *modinfo);
int (*module_eeprom)(struct sfp *sfp, struct ethtool_eeprom *ee,
u8 *data);
int (*module_eeprom_by_page)(struct sfp *sfp,
const struct ethtool_module_eeprom *page,
struct netlink_ext_ack *extack);
};

int sfp_add_phy(struct sfp_bus *bus, struct phy_device *phydev);
Expand Down
10 changes: 10 additions & 0 deletions include/linux/sfp.h
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,9 @@ phy_interface_t sfp_select_interface(struct sfp_bus *bus,
int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo);
int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee,
u8 *data);
int sfp_get_module_eeprom_by_page(struct sfp_bus *bus,
const struct ethtool_module_eeprom *page,
struct netlink_ext_ack *extack);
void sfp_upstream_start(struct sfp_bus *bus);
void sfp_upstream_stop(struct sfp_bus *bus);
void sfp_bus_put(struct sfp_bus *bus);
Expand Down Expand Up @@ -587,6 +590,13 @@ static inline int sfp_get_module_eeprom(struct sfp_bus *bus,
return -EOPNOTSUPP;
}

static inline int sfp_get_module_eeprom_by_page(struct sfp_bus *bus,
const struct ethtool_module_eeprom *page,
struct netlink_ext_ack *extack)
{
return -EOPNOTSUPP;
}

static inline void sfp_upstream_start(struct sfp_bus *bus)
{
}
Expand Down

0 comments on commit d740513

Please sign in to comment.