diff options
author | Michael Chan <mchan@broadcom.com> | 2006-03-21 01:27:48 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-03-21 01:27:48 -0500 |
commit | 1b27777a9b9b2b6d1c06000b7a31262d198b4238 (patch) | |
tree | 4690a8fe70231e4b09171957a5d3e8a7b4ccb00c /drivers/net/tg3.c | |
parent | d9ab5ad12b0d865bdb1b750d81192d34465541e9 (diff) |
[TG3]: Add 5787 nvram support
Support additional nvrams and new nvram format for 5787 and 5754.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 143 |
1 files changed, 123 insertions, 20 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e6ed940d7714..9cd8613625f8 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -7816,29 +7816,53 @@ static void tg3_get_ethtool_stats (struct net_device *dev, | |||
7816 | } | 7816 | } |
7817 | 7817 | ||
7818 | #define NVRAM_TEST_SIZE 0x100 | 7818 | #define NVRAM_TEST_SIZE 0x100 |
7819 | #define NVRAM_SELFBOOT_FORMAT1_SIZE 0x14 | ||
7819 | 7820 | ||
7820 | static int tg3_test_nvram(struct tg3 *tp) | 7821 | static int tg3_test_nvram(struct tg3 *tp) |
7821 | { | 7822 | { |
7822 | u32 *buf, csum; | 7823 | u32 *buf, csum, magic; |
7823 | int i, j, err = 0; | 7824 | int i, j, err = 0, size; |
7824 | 7825 | ||
7825 | buf = kmalloc(NVRAM_TEST_SIZE, GFP_KERNEL); | 7826 | if (tg3_nvram_read(tp, 0, &magic) != 0) |
7827 | return -EIO; | ||
7828 | |||
7829 | magic = swab32(magic); | ||
7830 | if (magic == TG3_EEPROM_MAGIC) | ||
7831 | size = NVRAM_TEST_SIZE; | ||
7832 | else if ((magic & 0xff000000) == 0xa5000000) { | ||
7833 | if ((magic & 0xe00000) == 0x200000) | ||
7834 | size = NVRAM_SELFBOOT_FORMAT1_SIZE; | ||
7835 | else | ||
7836 | return 0; | ||
7837 | } else | ||
7838 | return -EIO; | ||
7839 | |||
7840 | buf = kmalloc(size, GFP_KERNEL); | ||
7826 | if (buf == NULL) | 7841 | if (buf == NULL) |
7827 | return -ENOMEM; | 7842 | return -ENOMEM; |
7828 | 7843 | ||
7829 | for (i = 0, j = 0; i < NVRAM_TEST_SIZE; i += 4, j++) { | 7844 | err = -EIO; |
7845 | for (i = 0, j = 0; i < size; i += 4, j++) { | ||
7830 | u32 val; | 7846 | u32 val; |
7831 | 7847 | ||
7832 | if ((err = tg3_nvram_read(tp, i, &val)) != 0) | 7848 | if ((err = tg3_nvram_read(tp, i, &val)) != 0) |
7833 | break; | 7849 | break; |
7834 | buf[j] = cpu_to_le32(val); | 7850 | buf[j] = cpu_to_le32(val); |
7835 | } | 7851 | } |
7836 | if (i < NVRAM_TEST_SIZE) | 7852 | if (i < size) |
7837 | goto out; | 7853 | goto out; |
7838 | 7854 | ||
7839 | err = -EIO; | 7855 | /* Selfboot format */ |
7840 | if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) | 7856 | if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) { |
7841 | goto out; | 7857 | u8 *buf8 = (u8 *) buf, csum8 = 0; |
7858 | |||
7859 | for (i = 0; i < size; i++) | ||
7860 | csum8 += buf8[i]; | ||
7861 | |||
7862 | if (csum8 == 0) | ||
7863 | return 0; | ||
7864 | return -EIO; | ||
7865 | } | ||
7842 | 7866 | ||
7843 | /* Bootstrap checksum at offset 0x10 */ | 7867 | /* Bootstrap checksum at offset 0x10 */ |
7844 | csum = calc_crc((unsigned char *) buf, 0x10); | 7868 | csum = calc_crc((unsigned char *) buf, 0x10); |
@@ -8561,14 +8585,15 @@ static struct ethtool_ops tg3_ethtool_ops = { | |||
8561 | 8585 | ||
8562 | static void __devinit tg3_get_eeprom_size(struct tg3 *tp) | 8586 | static void __devinit tg3_get_eeprom_size(struct tg3 *tp) |
8563 | { | 8587 | { |
8564 | u32 cursize, val; | 8588 | u32 cursize, val, magic; |
8565 | 8589 | ||
8566 | tp->nvram_size = EEPROM_CHIP_SIZE; | 8590 | tp->nvram_size = EEPROM_CHIP_SIZE; |
8567 | 8591 | ||
8568 | if (tg3_nvram_read(tp, 0, &val) != 0) | 8592 | if (tg3_nvram_read(tp, 0, &val) != 0) |
8569 | return; | 8593 | return; |
8570 | 8594 | ||
8571 | if (swab32(val) != TG3_EEPROM_MAGIC) | 8595 | magic = swab32(val); |
8596 | if ((magic != TG3_EEPROM_MAGIC) && ((magic & 0xff000000) != 0xa5000000)) | ||
8572 | return; | 8597 | return; |
8573 | 8598 | ||
8574 | /* | 8599 | /* |
@@ -8576,13 +8601,13 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp) | |||
8576 | * When we encounter our validation signature, we know the addressing | 8601 | * When we encounter our validation signature, we know the addressing |
8577 | * has wrapped around, and thus have our chip size. | 8602 | * has wrapped around, and thus have our chip size. |
8578 | */ | 8603 | */ |
8579 | cursize = 0x800; | 8604 | cursize = 0x10; |
8580 | 8605 | ||
8581 | while (cursize < tp->nvram_size) { | 8606 | while (cursize < tp->nvram_size) { |
8582 | if (tg3_nvram_read(tp, cursize, &val) != 0) | 8607 | if (tg3_nvram_read(tp, cursize, &val) != 0) |
8583 | return; | 8608 | return; |
8584 | 8609 | ||
8585 | if (swab32(val) == TG3_EEPROM_MAGIC) | 8610 | if (swab32(val) == magic) |
8586 | break; | 8611 | break; |
8587 | 8612 | ||
8588 | cursize <<= 1; | 8613 | cursize <<= 1; |
@@ -8595,6 +8620,15 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp) | |||
8595 | { | 8620 | { |
8596 | u32 val; | 8621 | u32 val; |
8597 | 8622 | ||
8623 | if (tg3_nvram_read(tp, 0, &val) != 0) | ||
8624 | return; | ||
8625 | |||
8626 | /* Selfboot format */ | ||
8627 | if (swab32(val) != TG3_EEPROM_MAGIC) { | ||
8628 | tg3_get_eeprom_size(tp); | ||
8629 | return; | ||
8630 | } | ||
8631 | |||
8598 | if (tg3_nvram_read(tp, 0xf0, &val) == 0) { | 8632 | if (tg3_nvram_read(tp, 0xf0, &val) == 0) { |
8599 | if (val != 0) { | 8633 | if (val != 0) { |
8600 | tp->nvram_size = (val >> 16) * 1024; | 8634 | tp->nvram_size = (val >> 16) * 1024; |
@@ -8718,6 +8752,44 @@ static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp) | |||
8718 | } | 8752 | } |
8719 | } | 8753 | } |
8720 | 8754 | ||
8755 | static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp) | ||
8756 | { | ||
8757 | u32 nvcfg1; | ||
8758 | |||
8759 | nvcfg1 = tr32(NVRAM_CFG1); | ||
8760 | |||
8761 | switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { | ||
8762 | case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ: | ||
8763 | case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ: | ||
8764 | case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ: | ||
8765 | case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ: | ||
8766 | tp->nvram_jedecnum = JEDEC_ATMEL; | ||
8767 | tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; | ||
8768 | tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; | ||
8769 | |||
8770 | nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; | ||
8771 | tw32(NVRAM_CFG1, nvcfg1); | ||
8772 | break; | ||
8773 | case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED: | ||
8774 | case FLASH_5755VENDOR_ATMEL_FLASH_1: | ||
8775 | case FLASH_5755VENDOR_ATMEL_FLASH_2: | ||
8776 | case FLASH_5755VENDOR_ATMEL_FLASH_3: | ||
8777 | tp->nvram_jedecnum = JEDEC_ATMEL; | ||
8778 | tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; | ||
8779 | tp->tg3_flags2 |= TG3_FLG2_FLASH; | ||
8780 | tp->nvram_pagesize = 264; | ||
8781 | break; | ||
8782 | case FLASH_5752VENDOR_ST_M45PE10: | ||
8783 | case FLASH_5752VENDOR_ST_M45PE20: | ||
8784 | case FLASH_5752VENDOR_ST_M45PE40: | ||
8785 | tp->nvram_jedecnum = JEDEC_ST; | ||
8786 | tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; | ||
8787 | tp->tg3_flags2 |= TG3_FLG2_FLASH; | ||
8788 | tp->nvram_pagesize = 256; | ||
8789 | break; | ||
8790 | } | ||
8791 | } | ||
8792 | |||
8721 | /* Chips other than 5700/5701 use the NVRAM for fetching info. */ | 8793 | /* Chips other than 5700/5701 use the NVRAM for fetching info. */ |
8722 | static void __devinit tg3_nvram_init(struct tg3 *tp) | 8794 | static void __devinit tg3_nvram_init(struct tg3 *tp) |
8723 | { | 8795 | { |
@@ -8753,6 +8825,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) | |||
8753 | 8825 | ||
8754 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) | 8826 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) |
8755 | tg3_get_5752_nvram_info(tp); | 8827 | tg3_get_5752_nvram_info(tp); |
8828 | else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) | ||
8829 | tg3_get_5787_nvram_info(tp); | ||
8756 | else | 8830 | else |
8757 | tg3_get_nvram_info(tp); | 8831 | tg3_get_nvram_info(tp); |
8758 | 8832 | ||
@@ -9041,6 +9115,7 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, | |||
9041 | nvram_cmd |= NVRAM_CMD_LAST; | 9115 | nvram_cmd |= NVRAM_CMD_LAST; |
9042 | 9116 | ||
9043 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) && | 9117 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) && |
9118 | (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) && | ||
9044 | (tp->nvram_jedecnum == JEDEC_ST) && | 9119 | (tp->nvram_jedecnum == JEDEC_ST) && |
9045 | (nvram_cmd & NVRAM_CMD_FIRST)) { | 9120 | (nvram_cmd & NVRAM_CMD_FIRST)) { |
9046 | 9121 | ||
@@ -9444,6 +9519,7 @@ static void __devinit tg3_read_partno(struct tg3 *tp) | |||
9444 | { | 9519 | { |
9445 | unsigned char vpd_data[256]; | 9520 | unsigned char vpd_data[256]; |
9446 | int i; | 9521 | int i; |
9522 | u32 magic; | ||
9447 | 9523 | ||
9448 | if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { | 9524 | if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { |
9449 | /* Sun decided not to put the necessary bits in the | 9525 | /* Sun decided not to put the necessary bits in the |
@@ -9453,16 +9529,43 @@ static void __devinit tg3_read_partno(struct tg3 *tp) | |||
9453 | return; | 9529 | return; |
9454 | } | 9530 | } |
9455 | 9531 | ||
9456 | for (i = 0; i < 256; i += 4) { | 9532 | if (tg3_nvram_read(tp, 0x0, &magic)) |
9457 | u32 tmp; | 9533 | return; |
9458 | 9534 | ||
9459 | if (tg3_nvram_read(tp, 0x100 + i, &tmp)) | 9535 | if (swab32(magic) == TG3_EEPROM_MAGIC) { |
9460 | goto out_not_found; | 9536 | for (i = 0; i < 256; i += 4) { |
9537 | u32 tmp; | ||
9461 | 9538 | ||
9462 | vpd_data[i + 0] = ((tmp >> 0) & 0xff); | 9539 | if (tg3_nvram_read(tp, 0x100 + i, &tmp)) |
9463 | vpd_data[i + 1] = ((tmp >> 8) & 0xff); | 9540 | goto out_not_found; |
9464 | vpd_data[i + 2] = ((tmp >> 16) & 0xff); | 9541 | |
9465 | vpd_data[i + 3] = ((tmp >> 24) & 0xff); | 9542 | vpd_data[i + 0] = ((tmp >> 0) & 0xff); |
9543 | vpd_data[i + 1] = ((tmp >> 8) & 0xff); | ||
9544 | vpd_data[i + 2] = ((tmp >> 16) & 0xff); | ||
9545 | vpd_data[i + 3] = ((tmp >> 24) & 0xff); | ||
9546 | } | ||
9547 | } else { | ||
9548 | int vpd_cap; | ||
9549 | |||
9550 | vpd_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_VPD); | ||
9551 | for (i = 0; i < 256; i += 4) { | ||
9552 | u32 tmp, j = 0; | ||
9553 | u16 tmp16; | ||
9554 | |||
9555 | pci_write_config_word(tp->pdev, vpd_cap + PCI_VPD_ADDR, | ||
9556 | i); | ||
9557 | while (j++ < 100) { | ||
9558 | pci_read_config_word(tp->pdev, vpd_cap + | ||
9559 | PCI_VPD_ADDR, &tmp16); | ||
9560 | if (tmp16 & 0x8000) | ||
9561 | break; | ||
9562 | msleep(1); | ||
9563 | } | ||
9564 | pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA, | ||
9565 | &tmp); | ||
9566 | tmp = cpu_to_le32(tmp); | ||
9567 | memcpy(&vpd_data[i], &tmp, 4); | ||
9568 | } | ||
9466 | } | 9569 | } |
9467 | 9570 | ||
9468 | /* Now parse and find the part number. */ | 9571 | /* Now parse and find the part number. */ |