Commit 981f1f80 authored by Russell King's avatar Russell King Committed by David S. Miller

sfp: allow cotsworks modules

Cotsworks modules fail the checksums - it appears that Cotsworks
reprograms the EEPROM at the end of production with the final product
information (serial, date code, and exact part number for module
options) and fails to update the checksum.

Work around this by detecting the Cotsworks name in the manufacturer
field, and reducing the checksum failures to warnings rather than a
hard error.
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5593e334
...@@ -560,6 +560,7 @@ static int sfp_sm_mod_probe(struct sfp *sfp) ...@@ -560,6 +560,7 @@ static int sfp_sm_mod_probe(struct sfp *sfp)
{ {
/* SFP module inserted - read I2C data */ /* SFP module inserted - read I2C data */
struct sfp_eeprom_id id; struct sfp_eeprom_id id;
bool cotsworks;
u8 check; u8 check;
int ret; int ret;
...@@ -574,24 +575,44 @@ static int sfp_sm_mod_probe(struct sfp *sfp) ...@@ -574,24 +575,44 @@ static int sfp_sm_mod_probe(struct sfp *sfp)
return -EAGAIN; return -EAGAIN;
} }
/* Cotsworks do not seem to update the checksums when they
* do the final programming with the final module part number,
* serial number and date code.
*/
cotsworks = !memcmp(id.base.vendor_name, "COTSWORKS ", 16);
/* 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);
if (check != id.base.cc_base) { if (check != id.base.cc_base) {
if (cotsworks) {
dev_warn(sfp->dev,
"EEPROM base structure checksum failure (0x%02x != 0x%02x)\n",
check, id.base.cc_base);
} else {
dev_err(sfp->dev, dev_err(sfp->dev,
"EEPROM base structure checksum failure: 0x%02x\n", "EEPROM base structure checksum failure: 0x%02x != 0x%02x\n",
check); check, id.base.cc_base);
print_hex_dump(KERN_ERR, "sfp EE: ", DUMP_PREFIX_OFFSET, print_hex_dump(KERN_ERR, "sfp EE: ", DUMP_PREFIX_OFFSET,
16, 1, &id, sizeof(id.base) - 1, true); 16, 1, &id, sizeof(id), true);
return -EINVAL; return -EINVAL;
} }
}
check = sfp_check(&id.ext, sizeof(id.ext) - 1); check = sfp_check(&id.ext, sizeof(id.ext) - 1);
if (check != id.ext.cc_ext) { if (check != id.ext.cc_ext) {
if (cotsworks) {
dev_warn(sfp->dev,
"EEPROM extended structure checksum failure (0x%02x != 0x%02x)\n",
check, id.ext.cc_ext);
} else {
dev_err(sfp->dev, dev_err(sfp->dev,
"EEPROM extended structure checksum failure: 0x%02x\n", "EEPROM extended structure checksum failure: 0x%02x != 0x%02x\n",
check); check, id.ext.cc_ext);
print_hex_dump(KERN_ERR, "sfp EE: ", DUMP_PREFIX_OFFSET,
16, 1, &id, sizeof(id), true);
memset(&id.ext, 0, sizeof(id.ext)); memset(&id.ext, 0, sizeof(id.ext));
} }
}
sfp->id = id; sfp->id = id;
......
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