Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

asix: Add support for programming the EEPROM

This patch adds the asix_set_eeprom() function to provide support for
programming the configuration EEPROM via ethtool.

Signed-off-by: Christian Riesch <christian.riesch@omicron.at>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Christian Riesch and committed by
David S. Miller
cb7b24cd ceb02c91

+87
+2
drivers/net/usb/asix.h
··· 208 208 int asix_get_eeprom_len(struct net_device *net); 209 209 int asix_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, 210 210 u8 *data); 211 + int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, 212 + u8 *data); 211 213 212 214 void asix_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info); 213 215
+81
drivers/net/usb/asix_common.c
··· 516 516 return 0; 517 517 } 518 518 519 + int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, 520 + u8 *data) 521 + { 522 + struct usbnet *dev = netdev_priv(net); 523 + u16 *eeprom_buff; 524 + int first_word, last_word; 525 + int i; 526 + int ret; 527 + 528 + netdev_dbg(net, "write EEPROM len %d, offset %d, magic 0x%x\n", 529 + eeprom->len, eeprom->offset, eeprom->magic); 530 + 531 + if (eeprom->len == 0) 532 + return -EINVAL; 533 + 534 + if (eeprom->magic != AX_EEPROM_MAGIC) 535 + return -EINVAL; 536 + 537 + first_word = eeprom->offset >> 1; 538 + last_word = (eeprom->offset + eeprom->len - 1) >> 1; 539 + 540 + eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1), 541 + GFP_KERNEL); 542 + if (!eeprom_buff) 543 + return -ENOMEM; 544 + 545 + /* align data to 16 bit boundaries, read the missing data from 546 + the EEPROM */ 547 + if (eeprom->offset & 1) { 548 + ret = asix_read_cmd(dev, AX_CMD_READ_EEPROM, first_word, 0, 2, 549 + &(eeprom_buff[0])); 550 + if (ret < 0) { 551 + netdev_err(net, "Failed to read EEPROM at offset 0x%02x.\n", first_word); 552 + goto free; 553 + } 554 + } 555 + 556 + if ((eeprom->offset + eeprom->len) & 1) { 557 + ret = asix_read_cmd(dev, AX_CMD_READ_EEPROM, last_word, 0, 2, 558 + &(eeprom_buff[last_word - first_word])); 559 + if (ret < 0) { 560 + netdev_err(net, "Failed to read EEPROM at offset 0x%02x.\n", last_word); 561 + goto free; 562 + } 563 + } 564 + 565 + memcpy((u8 *)eeprom_buff + (eeprom->offset & 1), data, eeprom->len); 566 + 567 + /* write data to EEPROM */ 568 + ret = asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0x0000, 0, 0, NULL); 569 + if (ret < 0) { 570 + netdev_err(net, "Failed to enable EEPROM write\n"); 571 + goto free; 572 + } 573 + msleep(20); 574 + 575 + for (i = first_word; i <= last_word; i++) { 576 + netdev_dbg(net, "write to EEPROM at offset 0x%02x, data 0x%04x\n", 577 + i, eeprom_buff[i - first_word]); 578 + ret = asix_write_cmd(dev, AX_CMD_WRITE_EEPROM, i, 579 + eeprom_buff[i - first_word], 0, NULL); 580 + if (ret < 0) { 581 + netdev_err(net, "Failed to write EEPROM at offset 0x%02x.\n", 582 + i); 583 + goto free; 584 + } 585 + msleep(20); 586 + } 587 + 588 + ret = asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0x0000, 0, 0, NULL); 589 + if (ret < 0) { 590 + netdev_err(net, "Failed to disable EEPROM write\n"); 591 + goto free; 592 + } 593 + 594 + ret = 0; 595 + free: 596 + kfree(eeprom_buff); 597 + return ret; 598 + } 599 + 519 600 void asix_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) 520 601 { 521 602 /* Inherit standard device info */
+3
drivers/net/usb/asix_devices.c
··· 119 119 .set_wol = asix_set_wol, 120 120 .get_eeprom_len = asix_get_eeprom_len, 121 121 .get_eeprom = asix_get_eeprom, 122 + .set_eeprom = asix_set_eeprom, 122 123 .get_settings = usbnet_get_settings, 123 124 .set_settings = usbnet_set_settings, 124 125 .nway_reset = usbnet_nway_reset, ··· 259 258 .set_wol = asix_set_wol, 260 259 .get_eeprom_len = asix_get_eeprom_len, 261 260 .get_eeprom = asix_get_eeprom, 261 + .set_eeprom = asix_set_eeprom, 262 262 .get_settings = usbnet_get_settings, 263 263 .set_settings = usbnet_set_settings, 264 264 .nway_reset = usbnet_nway_reset, ··· 480 478 .set_wol = asix_set_wol, 481 479 .get_eeprom_len = asix_get_eeprom_len, 482 480 .get_eeprom = asix_get_eeprom, 481 + .set_eeprom = asix_set_eeprom, 483 482 .get_settings = usbnet_get_settings, 484 483 .set_settings = usbnet_set_settings, 485 484 .nway_reset = usbnet_nway_reset,
+1
drivers/net/usb/ax88172a.c
··· 194 194 .set_wol = asix_set_wol, 195 195 .get_eeprom_len = asix_get_eeprom_len, 196 196 .get_eeprom = asix_get_eeprom, 197 + .set_eeprom = asix_set_eeprom, 197 198 .get_settings = ax88172a_get_settings, 198 199 .set_settings = ax88172a_set_settings, 199 200 .nway_reset = ax88172a_nway_reset,