aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2006-09-27 19:10:14 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-28 21:01:42 -0400
commitb16250e3d1c55820f08f0296624a423122ea9805 (patch)
tree9559f4acd5e740b727c42e635699b7427f21d3c3 /drivers/net/tg3.c
parent715116a12610b67c1d301a9b845ce95f7247dad3 (diff)
[TG3]: Add 5709 self-test support.
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.c123
1 files changed, 107 insertions, 16 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 23f5744bdffa..21843de4a88a 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -3615,8 +3615,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id,
3615 3615
3616 if ((sblk->status & SD_STATUS_UPDATED) || 3616 if ((sblk->status & SD_STATUS_UPDATED) ||
3617 !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { 3617 !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
3618 tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 3618 tg3_disable_ints(tp);
3619 0x00000001);
3620 return IRQ_RETVAL(1); 3619 return IRQ_RETVAL(1);
3621 } 3620 }
3622 return IRQ_RETVAL(0); 3621 return IRQ_RETVAL(0);
@@ -6860,8 +6859,7 @@ static int tg3_request_irq(struct tg3 *tp)
6860static int tg3_test_interrupt(struct tg3 *tp) 6859static int tg3_test_interrupt(struct tg3 *tp)
6861{ 6860{
6862 struct net_device *dev = tp->dev; 6861 struct net_device *dev = tp->dev;
6863 int err, i; 6862 int err, i, intr_ok = 0;
6864 u32 int_mbox = 0;
6865 6863
6866 if (!netif_running(dev)) 6864 if (!netif_running(dev))
6867 return -ENODEV; 6865 return -ENODEV;
@@ -6882,10 +6880,18 @@ static int tg3_test_interrupt(struct tg3 *tp)
6882 HOSTCC_MODE_NOW); 6880 HOSTCC_MODE_NOW);
6883 6881
6884 for (i = 0; i < 5; i++) { 6882 for (i = 0; i < 5; i++) {
6883 u32 int_mbox, misc_host_ctrl;
6884
6885 int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 + 6885 int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 +
6886 TG3_64BIT_REG_LOW); 6886 TG3_64BIT_REG_LOW);
6887 if (int_mbox != 0) 6887 misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
6888
6889 if ((int_mbox != 0) ||
6890 (misc_host_ctrl & MISC_HOST_CTRL_MASK_PCI_INT)) {
6891 intr_ok = 1;
6888 break; 6892 break;
6893 }
6894
6889 msleep(10); 6895 msleep(10);
6890 } 6896 }
6891 6897
@@ -6898,7 +6904,7 @@ static int tg3_test_interrupt(struct tg3 *tp)
6898 if (err) 6904 if (err)
6899 return err; 6905 return err;
6900 6906
6901 if (int_mbox != 0) 6907 if (intr_ok)
6902 return 0; 6908 return 0;
6903 6909
6904 return -EIO; 6910 return -EIO;
@@ -8288,6 +8294,8 @@ static void tg3_get_ethtool_stats (struct net_device *dev,
8288 8294
8289#define NVRAM_TEST_SIZE 0x100 8295#define NVRAM_TEST_SIZE 0x100
8290#define NVRAM_SELFBOOT_FORMAT1_SIZE 0x14 8296#define NVRAM_SELFBOOT_FORMAT1_SIZE 0x14
8297#define NVRAM_SELFBOOT_HW_SIZE 0x20
8298#define NVRAM_SELFBOOT_DATA_SIZE 0x1c
8291 8299
8292static int tg3_test_nvram(struct tg3 *tp) 8300static int tg3_test_nvram(struct tg3 *tp)
8293{ 8301{
@@ -8299,12 +8307,14 @@ static int tg3_test_nvram(struct tg3 *tp)
8299 8307
8300 if (magic == TG3_EEPROM_MAGIC) 8308 if (magic == TG3_EEPROM_MAGIC)
8301 size = NVRAM_TEST_SIZE; 8309 size = NVRAM_TEST_SIZE;
8302 else if ((magic & 0xff000000) == 0xa5000000) { 8310 else if ((magic & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW) {
8303 if ((magic & 0xe00000) == 0x200000) 8311 if ((magic & 0xe00000) == 0x200000)
8304 size = NVRAM_SELFBOOT_FORMAT1_SIZE; 8312 size = NVRAM_SELFBOOT_FORMAT1_SIZE;
8305 else 8313 else
8306 return 0; 8314 return 0;
8307 } else 8315 } else if ((magic & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW)
8316 size = NVRAM_SELFBOOT_HW_SIZE;
8317 else
8308 return -EIO; 8318 return -EIO;
8309 8319
8310 buf = kmalloc(size, GFP_KERNEL); 8320 buf = kmalloc(size, GFP_KERNEL);
@@ -8323,7 +8333,8 @@ static int tg3_test_nvram(struct tg3 *tp)
8323 goto out; 8333 goto out;
8324 8334
8325 /* Selfboot format */ 8335 /* Selfboot format */
8326 if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) { 8336 if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_FW_MSK) ==
8337 TG3_EEPROM_MAGIC_FW) {
8327 u8 *buf8 = (u8 *) buf, csum8 = 0; 8338 u8 *buf8 = (u8 *) buf, csum8 = 0;
8328 8339
8329 for (i = 0; i < size; i++) 8340 for (i = 0; i < size; i++)
@@ -8338,6 +8349,51 @@ static int tg3_test_nvram(struct tg3 *tp)
8338 goto out; 8349 goto out;
8339 } 8350 }
8340 8351
8352 if ((cpu_to_be32(buf[0]) & TG3_EEPROM_MAGIC_HW_MSK) ==
8353 TG3_EEPROM_MAGIC_HW) {
8354 u8 data[NVRAM_SELFBOOT_DATA_SIZE];
8355 u8 parity[NVRAM_SELFBOOT_DATA_SIZE];
8356 u8 *buf8 = (u8 *) buf;
8357 int j, k;
8358
8359 /* Separate the parity bits and the data bytes. */
8360 for (i = 0, j = 0, k = 0; i < NVRAM_SELFBOOT_HW_SIZE; i++) {
8361 if ((i == 0) || (i == 8)) {
8362 int l;
8363 u8 msk;
8364
8365 for (l = 0, msk = 0x80; l < 7; l++, msk >>= 1)
8366 parity[k++] = buf8[i] & msk;
8367 i++;
8368 }
8369 else if (i == 16) {
8370 int l;
8371 u8 msk;
8372
8373 for (l = 0, msk = 0x20; l < 6; l++, msk >>= 1)
8374 parity[k++] = buf8[i] & msk;
8375 i++;
8376
8377 for (l = 0, msk = 0x80; l < 8; l++, msk >>= 1)
8378 parity[k++] = buf8[i] & msk;
8379 i++;
8380 }
8381 data[j++] = buf8[i];
8382 }
8383
8384 err = -EIO;
8385 for (i = 0; i < NVRAM_SELFBOOT_DATA_SIZE; i++) {
8386 u8 hw8 = hweight8(data[i]);
8387
8388 if ((hw8 & 0x1) && parity[i])
8389 goto out;
8390 else if (!(hw8 & 0x1) && !parity[i])
8391 goto out;
8392 }
8393 err = 0;
8394 goto out;
8395 }
8396
8341 /* Bootstrap checksum at offset 0x10 */ 8397 /* Bootstrap checksum at offset 0x10 */
8342 csum = calc_crc((unsigned char *) buf, 0x10); 8398 csum = calc_crc((unsigned char *) buf, 0x10);
8343 if(csum != cpu_to_le32(buf[0x10/4])) 8399 if(csum != cpu_to_le32(buf[0x10/4]))
@@ -8384,7 +8440,7 @@ static int tg3_test_link(struct tg3 *tp)
8384/* Only test the commonly used registers */ 8440/* Only test the commonly used registers */
8385static int tg3_test_registers(struct tg3 *tp) 8441static int tg3_test_registers(struct tg3 *tp)
8386{ 8442{
8387 int i, is_5705; 8443 int i, is_5705, is_5750;
8388 u32 offset, read_mask, write_mask, val, save_val, read_val; 8444 u32 offset, read_mask, write_mask, val, save_val, read_val;
8389 static struct { 8445 static struct {
8390 u16 offset; 8446 u16 offset;
@@ -8392,6 +8448,7 @@ static int tg3_test_registers(struct tg3 *tp)
8392#define TG3_FL_5705 0x1 8448#define TG3_FL_5705 0x1
8393#define TG3_FL_NOT_5705 0x2 8449#define TG3_FL_NOT_5705 0x2
8394#define TG3_FL_NOT_5788 0x4 8450#define TG3_FL_NOT_5788 0x4
8451#define TG3_FL_NOT_5750 0x8
8395 u32 read_mask; 8452 u32 read_mask;
8396 u32 write_mask; 8453 u32 write_mask;
8397 } reg_tbl[] = { 8454 } reg_tbl[] = {
@@ -8502,9 +8559,9 @@ static int tg3_test_registers(struct tg3 *tp)
8502 0xffffffff, 0x00000000 }, 8559 0xffffffff, 0x00000000 },
8503 8560
8504 /* Buffer Manager Control Registers. */ 8561 /* Buffer Manager Control Registers. */
8505 { BUFMGR_MB_POOL_ADDR, 0x0000, 8562 { BUFMGR_MB_POOL_ADDR, TG3_FL_NOT_5750,
8506 0x00000000, 0x007fff80 }, 8563 0x00000000, 0x007fff80 },
8507 { BUFMGR_MB_POOL_SIZE, 0x0000, 8564 { BUFMGR_MB_POOL_SIZE, TG3_FL_NOT_5750,
8508 0x00000000, 0x007fffff }, 8565 0x00000000, 0x007fffff },
8509 { BUFMGR_MB_RDMA_LOW_WATER, 0x0000, 8566 { BUFMGR_MB_RDMA_LOW_WATER, 0x0000,
8510 0x00000000, 0x0000003f }, 8567 0x00000000, 0x0000003f },
@@ -8530,10 +8587,12 @@ static int tg3_test_registers(struct tg3 *tp)
8530 { 0xffff, 0x0000, 0x00000000, 0x00000000 }, 8587 { 0xffff, 0x0000, 0x00000000, 0x00000000 },
8531 }; 8588 };
8532 8589
8533 if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) 8590 is_5705 = is_5750 = 0;
8591 if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
8534 is_5705 = 1; 8592 is_5705 = 1;
8535 else 8593 if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
8536 is_5705 = 0; 8594 is_5750 = 1;
8595 }
8537 8596
8538 for (i = 0; reg_tbl[i].offset != 0xffff; i++) { 8597 for (i = 0; reg_tbl[i].offset != 0xffff; i++) {
8539 if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705)) 8598 if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705))
@@ -8546,6 +8605,9 @@ static int tg3_test_registers(struct tg3 *tp)
8546 (reg_tbl[i].flags & TG3_FL_NOT_5788)) 8605 (reg_tbl[i].flags & TG3_FL_NOT_5788))
8547 continue; 8606 continue;
8548 8607
8608 if (is_5750 && (reg_tbl[i].flags & TG3_FL_NOT_5750))
8609 continue;
8610
8549 offset = (u32) reg_tbl[i].offset; 8611 offset = (u32) reg_tbl[i].offset;
8550 read_mask = reg_tbl[i].read_mask; 8612 read_mask = reg_tbl[i].read_mask;
8551 write_mask = reg_tbl[i].write_mask; 8613 write_mask = reg_tbl[i].write_mask;
@@ -8637,6 +8699,13 @@ static int tg3_test_memory(struct tg3 *tp)
8637 { 0x00008000, 0x02000}, 8699 { 0x00008000, 0x02000},
8638 { 0x00010000, 0x0c000}, 8700 { 0x00010000, 0x0c000},
8639 { 0xffffffff, 0x00000} 8701 { 0xffffffff, 0x00000}
8702 }, mem_tbl_5906[] = {
8703 { 0x00000200, 0x00008},
8704 { 0x00004000, 0x00400},
8705 { 0x00006000, 0x00400},
8706 { 0x00008000, 0x01000},
8707 { 0x00010000, 0x01000},
8708 { 0xffffffff, 0x00000}
8640 }; 8709 };
8641 struct mem_entry *mem_tbl; 8710 struct mem_entry *mem_tbl;
8642 int err = 0; 8711 int err = 0;
@@ -8646,6 +8715,8 @@ static int tg3_test_memory(struct tg3 *tp)
8646 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || 8715 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
8647 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) 8716 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
8648 mem_tbl = mem_tbl_5755; 8717 mem_tbl = mem_tbl_5755;
8718 else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
8719 mem_tbl = mem_tbl_5906;
8649 else 8720 else
8650 mem_tbl = mem_tbl_5705; 8721 mem_tbl = mem_tbl_5705;
8651 } else 8722 } else
@@ -8691,6 +8762,21 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
8691 } else if (loopback_mode == TG3_PHY_LOOPBACK) { 8762 } else if (loopback_mode == TG3_PHY_LOOPBACK) {
8692 u32 val; 8763 u32 val;
8693 8764
8765 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
8766 u32 phytest;
8767
8768 if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phytest)) {
8769 u32 phy;
8770
8771 tg3_writephy(tp, MII_TG3_EPHY_TEST,
8772 phytest | MII_TG3_EPHY_SHADOW_EN);
8773 if (!tg3_readphy(tp, 0x1b, &phy))
8774 tg3_writephy(tp, 0x1b, phy & ~0x20);
8775 if (!tg3_readphy(tp, 0x10, &phy))
8776 tg3_writephy(tp, 0x10, phy & ~0x4000);
8777 tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest);
8778 }
8779 }
8694 val = BMCR_LOOPBACK | BMCR_FULLDPLX; 8780 val = BMCR_LOOPBACK | BMCR_FULLDPLX;
8695 if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) 8781 if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
8696 val |= BMCR_SPEED100; 8782 val |= BMCR_SPEED100;
@@ -8699,6 +8785,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
8699 8785
8700 tg3_writephy(tp, MII_BMCR, val); 8786 tg3_writephy(tp, MII_BMCR, val);
8701 udelay(40); 8787 udelay(40);
8788 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
8789 tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800);
8790
8702 /* reset to prevent losing 1st rx packet intermittently */ 8791 /* reset to prevent losing 1st rx packet intermittently */
8703 if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { 8792 if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
8704 tw32_f(MAC_RX_MODE, RX_MODE_RESET); 8793 tw32_f(MAC_RX_MODE, RX_MODE_RESET);
@@ -9112,7 +9201,9 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
9112 if (tg3_nvram_read_swab(tp, 0, &magic) != 0) 9201 if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
9113 return; 9202 return;
9114 9203
9115 if ((magic != TG3_EEPROM_MAGIC) && ((magic & 0xff000000) != 0xa5000000)) 9204 if ((magic != TG3_EEPROM_MAGIC) &&
9205 ((magic & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW) &&
9206 ((magic & TG3_EEPROM_MAGIC_HW_MSK) != TG3_EEPROM_MAGIC_HW))
9116 return; 9207 return;
9117 9208
9118 /* 9209 /*