Commit b18432c5 authored by Chris Healy's avatar Chris Healy Committed by David S. Miller

net: phy: sfp: Cotsworks SFF module EEPROM fixup

Some Cotsworks SFF have invalid data in the first few bytes of the
module EEPROM.  This results in these modules not being detected as
valid modules.

Address this by poking the correct EEPROM values into the module
EEPROM when the model/PN match and the existing module EEPROM contents
are not correct.
Signed-off-by: default avatarChris Healy <cphealy@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bba238ed
...@@ -1632,10 +1632,43 @@ static int sfp_sm_mod_hpower(struct sfp *sfp, bool enable) ...@@ -1632,10 +1632,43 @@ static int sfp_sm_mod_hpower(struct sfp *sfp, bool enable)
return 0; return 0;
} }
static int sfp_cotsworks_fixup_check(struct sfp *sfp, struct sfp_eeprom_id *id)
{
u8 check;
int err;
if (id->base.phys_id != SFF8024_ID_SFF_8472 ||
id->base.phys_ext_id != SFP_PHYS_EXT_ID_SFP ||
id->base.connector != SFF8024_CONNECTOR_LC) {
dev_warn(sfp->dev, "Rewriting fiber module EEPROM with corrected values\n");
id->base.phys_id = SFF8024_ID_SFF_8472;
id->base.phys_ext_id = SFP_PHYS_EXT_ID_SFP;
id->base.connector = SFF8024_CONNECTOR_LC;
err = sfp_write(sfp, false, SFP_PHYS_ID, &id->base, 3);
if (err != 3) {
dev_err(sfp->dev, "Failed to rewrite module EEPROM: %d\n", err);
return err;
}
/* Cotsworks modules have been found to require a delay between write operations. */
mdelay(50);
/* Update base structure checksum */
check = sfp_check(&id->base, sizeof(id->base) - 1);
err = sfp_write(sfp, false, SFP_CC_BASE, &check, 1);
if (err != 1) {
dev_err(sfp->dev, "Failed to update base structure checksum in fiber module EEPROM: %d\n", err);
return err;
}
}
return 0;
}
static int sfp_sm_mod_probe(struct sfp *sfp, bool report) static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
{ {
/* SFP module inserted - read I2C data */ /* SFP module inserted - read I2C data */
struct sfp_eeprom_id id; struct sfp_eeprom_id id;
bool cotsworks_sfbg;
bool cotsworks; bool cotsworks;
u8 check; u8 check;
int ret; int ret;
...@@ -1657,6 +1690,17 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report) ...@@ -1657,6 +1690,17 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
* serial number and date code. * serial number and date code.
*/ */
cotsworks = !memcmp(id.base.vendor_name, "COTSWORKS ", 16); cotsworks = !memcmp(id.base.vendor_name, "COTSWORKS ", 16);
cotsworks_sfbg = !memcmp(id.base.vendor_pn, "SFBG", 4);
/* Cotsworks SFF module EEPROM do not always have valid phys_id,
* phys_ext_id, and connector bytes. Rewrite SFF EEPROM bytes if
* Cotsworks PN matches and bytes are not correct.
*/
if (cotsworks && cotsworks_sfbg) {
ret = sfp_cotsworks_fixup_check(sfp, &id);
if (ret < 0)
return ret;
}
/* Validate the checksum over the base structure */ /* Validate the checksum over the base structure */
check = sfp_check(&id.base, sizeof(id.base) - 1); check = sfp_check(&id.base, sizeof(id.base) - 1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment