Commit 678e1a68 authored by David S. Miller's avatar David S. Miller

[TG3]: Add 5750 NVRAM programming plus 5704 MAC offset bug fix.

parent 4948bc70
......@@ -3502,6 +3502,31 @@ static int tg3_abort_hw(struct tg3 *tp)
return err;
}
/* tp->lock is held. */
static int tg3_nvram_lock(struct tg3 *tp)
{
if (tp->tg3_flags & TG3_FLAG_NVRAM) {
int i;
tw32(NVRAM_SWARB, SWARB_REQ_SET1);
for (i = 0; i < 8000; i++) {
if (tr32(NVRAM_SWARB) & SWARB_GNT1)
break;
udelay(20);
}
if (i == 8000)
return -ENODEV;
}
return 0;
}
/* tp->lock is held. */
static void tg3_nvram_unlock(struct tg3 *tp)
{
if (tp->tg3_flags & TG3_FLAG_NVRAM)
tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
}
/* tp->lock is held. */
static int tg3_chip_reset(struct tg3 *tp)
{
......@@ -3509,22 +3534,8 @@ static int tg3_chip_reset(struct tg3 *tp)
u32 flags_save;
int i;
if (!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {
/* Force NVRAM to settle.
* This deals with a chip bug which can result in EEPROM
* corruption.
*/
if (tp->tg3_flags & TG3_FLAG_NVRAM) {
int i;
tw32(NVRAM_SWARB, SWARB_REQ_SET1);
for (i = 0; i < 100000; i++) {
if (tr32(NVRAM_SWARB) & SWARB_GNT1)
break;
udelay(10);
}
}
}
if (!(tp->tg3_flags2 & TG3_FLG2_SUN_5704))
tg3_nvram_lock(tp);
/*
* We must avoid the readl() that normally takes place.
......@@ -6518,7 +6529,15 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
u32 nvcfg1 = tr32(NVRAM_CFG1);
u32 nvcfg1;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
u32 nvaccess = tr32(NVRAM_ACCESS);
tw32_f(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
}
nvcfg1 = tr32(NVRAM_CFG1);
tp->tg3_flags |= TG3_FLAG_NVRAM;
if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
......@@ -6529,6 +6548,11 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
tw32(NVRAM_CFG1, nvcfg1);
}
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
u32 nvaccess = tr32(NVRAM_ACCESS);
tw32_f(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
}
} else {
tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
}
......@@ -6571,7 +6595,7 @@ static int __devinit tg3_nvram_read_using_eeprom(struct tg3 *tp,
static int __devinit tg3_nvram_read(struct tg3 *tp,
u32 offset, u32 *val)
{
int i, saw_done_clear;
int i;
if (tp->tg3_flags2 & TG3_FLG2_SUN_5704) {
printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 5704\n");
......@@ -6589,11 +6613,12 @@ static int __devinit tg3_nvram_read(struct tg3 *tp,
if (offset > NVRAM_ADDR_MSK)
return -EINVAL;
tw32(NVRAM_SWARB, SWARB_REQ_SET1);
for (i = 0; i < 1000; i++) {
if (tr32(NVRAM_SWARB) & SWARB_GNT1)
break;
udelay(20);
tg3_nvram_lock(tp);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
u32 nvaccess = tr32(NVRAM_ACCESS);
tw32_f(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
}
tw32(NVRAM_ADDR, offset);
......@@ -6601,24 +6626,26 @@ static int __devinit tg3_nvram_read(struct tg3 *tp,
NVRAM_CMD_RD | NVRAM_CMD_GO |
NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
/* Wait for done bit to clear then set again. */
saw_done_clear = 0;
/* Wait for done bit to clear. */
for (i = 0; i < 1000; i++) {
udelay(10);
if (!saw_done_clear &&
!(tr32(NVRAM_CMD) & NVRAM_CMD_DONE))
saw_done_clear = 1;
else if (saw_done_clear &&
(tr32(NVRAM_CMD) & NVRAM_CMD_DONE))
if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
udelay(10);
*val = swab32(tr32(NVRAM_RDDATA));
break;
}
}
if (i >= 1000) {
tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
return -EBUSY;
tg3_nvram_unlock(tp);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
u32 nvaccess = tr32(NVRAM_ACCESS);
tw32_f(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
}
*val = swab32(tr32(NVRAM_RDDATA));
tw32(NVRAM_SWARB, 0x20);
if (i >= 1000)
return -EBUSY;
return 0;
}
......@@ -7355,10 +7382,16 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
return 0;
#endif
if (PCI_FUNC(tp->pdev->devfn) == 0)
mac_offset = 0x7c;
else
mac_offset = 0xcc;
mac_offset = 0x7c;
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
!(tp->tg3_flags & TG3_FLG2_SUN_5704)) {
if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
mac_offset = 0xcc;
if (tg3_nvram_lock(tp))
tw32_f(NVRAM_CMD, NVRAM_CMD_RESET);
else
tg3_nvram_unlock(tp);
}
/* First try to get it from MAC address mailbox. */
tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi);
......
......@@ -207,7 +207,11 @@
#define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */
#define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */
#define TG3PCI_SND_PROD_IDX 0x000000a8 /* 64-bit */
/* 0xb0 --> 0x100 unused */
/* 0xb0 --> 0xb8 unused */
#define TG3PCI_DUAL_MAC_CTRL 0x000000b8
#define DUAL_MAC_CTRL_CH_MASK 0x00000003
#define DUAL_MAC_CTRL_ID 0x00000004
/* 0xbc --> 0x100 unused */
/* 0x100 --> 0x200 unused */
......@@ -1337,6 +1341,9 @@
#define SWARB_REQ3 0x00008000
#define NVRAM_BUFFERED_PAGE_SIZE 264
#define NVRAM_BUFFERED_PAGE_POS 9
#define NVRAM_ACCESS 0x00007024
#define ACCESS_ENABLE 0x00000001
#define ACCESS_WR_ENABLE 0x00000002
/* 0x7024 --> 0x7400 unused */
/* 0x7400 --> 0x8000 unused */
......
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