Skip to content

Commit

Permalink
net: sfp: add support for module quirks
Browse files Browse the repository at this point in the history
Add support for applying module quirks to the list of supported
ethtool link modes.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Russell King authored and David S. Miller committed Nov 21, 2019
1 parent 9bb59a2 commit b34bb2c
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions drivers/net/phy/sfp-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@

#include "sfp.h"

struct sfp_quirk {
const char *vendor;
const char *part;
void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
};

/**
* struct sfp_bus - internal representation of a sfp bus
*/
Expand All @@ -22,6 +28,7 @@ struct sfp_bus {
const struct sfp_socket_ops *socket_ops;
struct device *sfp_dev;
struct sfp *sfp;
const struct sfp_quirk *sfp_quirk;

const struct sfp_upstream_ops *upstream_ops;
void *upstream;
Expand All @@ -31,6 +38,46 @@ struct sfp_bus {
bool started;
};

static const struct sfp_quirk sfp_quirks[] = {
};

static size_t sfp_strlen(const char *str, size_t maxlen)
{
size_t size, i;

/* Trailing characters should be filled with space chars */
for (i = 0, size = 0; i < maxlen; i++)
if (str[i] != ' ')
size = i + 1;

return size;
}

static bool sfp_match(const char *qs, const char *str, size_t len)
{
if (!qs)
return true;
if (strlen(qs) != len)
return false;
return !strncmp(qs, str, len);
}

static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
{
const struct sfp_quirk *q;
unsigned int i;
size_t vs, ps;

vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));

for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
sfp_match(q->part, id->base.vendor_pn, ps))
return q;

return NULL;
}
/**
* sfp_parse_port() - Parse the EEPROM base ID, setting the port type
* @bus: a pointer to the &struct sfp_bus structure for the sfp module
Expand Down Expand Up @@ -234,6 +281,9 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
phylink_set(modes, 1000baseX_Full);
}

if (bus->sfp_quirk)
bus->sfp_quirk->modes(id, modes);

bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS);

phylink_set(support, Autoneg);
Expand Down Expand Up @@ -610,6 +660,8 @@ int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id)
const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
int ret = 0;

bus->sfp_quirk = sfp_lookup_quirk(id);

if (ops && ops->module_insert)
ret = ops->module_insert(bus->upstream, id);

Expand All @@ -623,6 +675,8 @@ void sfp_module_remove(struct sfp_bus *bus)

if (ops && ops->module_remove)
ops->module_remove(bus->upstream);

bus->sfp_quirk = NULL;
}
EXPORT_SYMBOL_GPL(sfp_module_remove);

Expand Down

0 comments on commit b34bb2c

Please sign in to comment.