PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702FE,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702X,
tr32(GRC_LOCAL_CTRL);
udelay(100);
- tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);
return 0;
case 1:
tr32(MAC_MI_MODE);
udelay(40);
+ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);
+
if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
tg3_readphy(tp, MII_BMSR, &bmsr);
tg3_readphy(tp, MII_BMSR, &bmsr);
tp->misc_host_ctrl);
/* Set MAX PCI retry to zero. */
- pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE,
- (PCISTATE_ROM_ENABLE |
- PCISTATE_ROM_RETRY_ENABLE));
+ val = (PCISTATE_ROM_ENABLE | PCISTATE_ROM_RETRY_ENABLE);
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
+ (tp->tg3_flags & TG3_FLAG_PCIX_MODE))
+ val |= PCISTATE_RETRY_SAME_DMA;
+ pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val);
pci_restore_state(tp->pdev, tp->pci_cfg_state);
tw32(TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);
}
+/* tp->lock is held. */
+static void tg3_stop_fw(struct tg3 *tp)
+{
+ if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+ u32 val;
+ int i;
+
+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
+ val = tr32(GRC_RX_CPU_EVENT);
+ val |= (1 << 14);
+ tw32(GRC_RX_CPU_EVENT, val);
+
+ /* Wait for RX cpu to ACK the event. */
+ for (i = 0; i < 100; i++) {
+ if (!(tr32(GRC_RX_CPU_EVENT) & (1 << 14)))
+ break;
+ udelay(1);
+ }
+ }
+}
+
/* tp->lock is held. */
static int tg3_halt(struct tg3 *tp)
{
u32 val;
int i;
+ tg3_stop_fw(tp);
tg3_abort_hw(tp);
tg3_chip_reset(tp);
tg3_write_mem(tp,
return -ENODEV;
}
+ if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+ if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)
+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
+ DRV_STATE_WOL);
+ else
+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
+ DRV_STATE_UNLOAD);
+ } else
+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
+ DRV_STATE_SUSPEND);
+
return 0;
}
tg3_disable_ints(tp);
+ tg3_stop_fw(tp);
+
if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) {
err = tg3_abort_hw(tp);
if (err)
return -ENODEV;
}
+ if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
+ DRV_STATE_START);
+ else
+ tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
+ DRV_STATE_SUSPEND);
+
/* This works around an issue with Athlon chipsets on
* B3 tigon3 silicon. This bit has no effect on any
* other revision.
tw32(TG3PCI_CLOCK_CTRL, val);
tr32(TG3PCI_CLOCK_CTRL);
+ if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
+ (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {
+ val = tr32(TG3PCI_PCISTATE);
+ val |= PCISTATE_RETRY_SAME_DMA;
+ tw32(TG3PCI_PCISTATE, val);
+ }
+
/* Clear statistics/status block in chip, and status block in ram. */
for (i = NIC_SRAM_STATS_BLK;
i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
/* Initialize MBUF/DESC pool. */
tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE);
- tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
+ tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE64);
+ else
+ tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96);
tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE);
tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE);
tr32(WDMAC_MODE);
udelay(40);
- tw32(RDMAC_MODE, (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB |
- RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB |
- RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
- RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
- RDMAC_MODE_LNGREAD_ENAB));
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
+ (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {
+ val = tr32(TG3PCI_X_CAPS);
+ val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK);
+ val |= (PCIX_CAPS_MAX_BURST_5704 << PCIX_CAPS_BURST_SHIFT);
+ if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
+ val |= (tp->split_mode_max_reqs <<
+ PCIX_CAPS_SPLIT_SHIFT);
+ tw32(TG3PCI_X_CAPS, val);
+ }
+
+ val = (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB |
+ RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB |
+ RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
+ RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
+ RDMAC_MODE_LNGREAD_ENAB);
+ if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
+ val |= RDMAC_MODE_SPLIT_ENABLE;
+ tw32(RDMAC_MODE, val);
tr32(RDMAC_MODE);
udelay(40);
tp->timer_counter = tp->timer_multiplier;
}
+ /* Heartbeat is only sent once every 120 seconds. */
+ if (!--tp->asf_counter) {
+ if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+ u32 val;
+
+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_ALIVE);
+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
+ tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 3);
+ val = tr32(GRC_RX_CPU_EVENT);
+ val |= (1 << 14);
+ tw32(GRC_RX_CPU_EVENT, val);
+ }
+ tp->asf_counter = tp->asf_multiplier;
+ }
+
spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock);
} else {
tp->timer_offset = HZ / 10;
tp->timer_counter = tp->timer_multiplier = 10;
+ tp->asf_counter = tp->asf_multiplier = (10 * 120);
init_timer(&tp->timer);
tp->timer.expires = jiffies + tp->timer_offset;
tp->pci_chip_rev_id == CHIPREV_ID_5703_A2) &&
(nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP))
tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
+
+ if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE)
+ tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
}
/* Now read the physical PHY_ID from the chip and verify
tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa);
}
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+ tg3_writephy(tp, 0x1c, 0x8d68);
+ tg3_writephy(tp, 0x1c, 0x8d68);
+ }
+
/* Enable Ethernet@WireSpeed */
tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007);
tg3_readphy(tp, MII_TG3_AUX_CTRL, &val);
grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5702FE &&
grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703 &&
grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703S &&
+ grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5704 &&
grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_AC91002A1)
return -ENODEV;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
+ grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) {
+ tp->tg3_flags |= TG3_FLAG_SPLIT_MODE;
+ tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ;
+ }
+
/* ROFL, you should see Broadcom's driver code implementing
* this, stuff like "if (a || b)" where a and b are always
* mutually exclusive. DaveM finds like 6 bugs today, hello!
static int __devinit tg3_get_device_address(struct tg3 *tp)
{
struct net_device *dev = tp->dev;
- u32 hi, lo;
+ u32 hi, lo, mac_offset;
+
+ if (PCI_FUNC(tp->pdev->devfn) == 0)
+ mac_offset = 0x7c;
+ else
+ mac_offset = 0xcc;
/* First try to get it from MAC address mailbox. */
tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi);
dev->dev_addr[5] = (lo >> 0) & 0xff;
}
/* Next, try NVRAM. */
- else if (!tg3_nvram_read(tp, 0x7c, &hi) &&
- !tg3_nvram_read(tp, 0x80, &lo)) {
+ else if (!tg3_nvram_read(tp, mac_offset + 0, &hi) &&
+ !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
dev->dev_addr[0] = ((hi >> 16) & 0xff);
dev->dev_addr[1] = ((hi >> 24) & 0xff);
dev->dev_addr[2] = ((lo >> 0) & 0xff);
(0x7 << DMA_RWCTRL_READ_WATER_SHIFT) |
(0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
} else {
- tp->dma_rwctrl =
- (0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
- (0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
- (0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
- (0x3 << DMA_RWCTRL_READ_WATER_SHIFT) |
- (0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
+ tp->dma_rwctrl =
+ (0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
+ (0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
+ (0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
+ (0x7 << DMA_RWCTRL_READ_WATER_SHIFT) |
+ (0x00 << DMA_RWCTRL_MIN_DMA_SHIFT);
+ else
+ tp->dma_rwctrl =
+ (0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
+ (0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
+ (0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
+ (0x3 << DMA_RWCTRL_READ_WATER_SHIFT) |
+ (0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
/* Wheee, some more chip bugs... */
if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1 ||
- tp->pci_chip_rev_id == CHIPREV_ID_5703_A2)
+ tp->pci_chip_rev_id == CHIPREV_ID_5703_A2 ||
+ tp->pci_chip_rev_id == CHIPREV_ID_5703_A3 ||
+ tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
}
case PHY_ID_BCM5411: return "5411";
case PHY_ID_BCM5701: return "5701";
case PHY_ID_BCM5703: return "5703";
+ case PHY_ID_BCM5704: return "5704";
case PHY_ID_BCM8002: return "8002";
case PHY_ID_SERDES: return "serdes";
default: return "unknown";
#define TG3PCI_MAX_LAT 0x0000003f
#define TG3PCI_X_CAPS 0x00000040
#define PCIX_CAPS_RELAXED_ORDERING 0x00020000
+#define PCIX_CAPS_SPLIT_MASK 0x00700000
+#define PCIX_CAPS_SPLIT_SHIFT 20
+#define PCIX_CAPS_BURST_MASK 0x000c0000
+#define PCIX_CAPS_BURST_SHIFT 18
+#define PCIX_CAPS_MAX_BURST_5704 2
#define TG3PCI_PM_CAP_PTR 0x00000041
#define TG3PCI_X_COMMAND 0x00000042
#define TG3PCI_X_STATUS 0x00000044
#define CHIPREV_ID_5703_A0 0x1000
#define CHIPREV_ID_5703_A1 0x1001
#define CHIPREV_ID_5703_A2 0x1002
+#define CHIPREV_ID_5703_A3 0x1003
+#define CHIPREV_ID_5704_A0 0x2000
#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
#define ASIC_REV_5700 0x07
#define ASIC_REV_5701 0x00
#define ASIC_REV_5703 0x01
+#define ASIC_REV_5704 0x02
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
#define CHIPREV_5700_AX 0x70
#define CHIPREV_5700_BX 0x71
#define PCISTATE_ROM_ENABLE 0x00000020
#define PCISTATE_ROM_RETRY_ENABLE 0x00000040
#define PCISTATE_FLAT_VIEW 0x00000100
+#define PCISTATE_RETRY_SAME_DMA 0x00002000
#define TG3PCI_CLOCK_CTRL 0x00000074
#define CLOCK_CTRL_CORECLK_DISABLE 0x00000200
#define CLOCK_CTRL_RXCLK_DISABLE 0x00000400
#define RDMAC_MODE_FIFOURUN_ENAB 0x00000080
#define RDMAC_MODE_FIFOOREAD_ENAB 0x00000100
#define RDMAC_MODE_LNGREAD_ENAB 0x00000200
+#define RDMAC_MODE_SPLIT_ENABLE 0x00000800
+#define RDMAC_MODE_SPLIT_RESET 0x00001000
#define RDMAC_STATUS 0x00004804
#define RDMAC_STATUS_TGTABORT 0x00000004
#define RDMAC_STATUS_MSTABORT 0x00000008
#define GRC_MISC_CFG_BOARD_ID_5702FE 0x00004000
#define GRC_MISC_CFG_BOARD_ID_5703 0x00000000
#define GRC_MISC_CFG_BOARD_ID_5703S 0x00002000
+#define GRC_MISC_CFG_BOARD_ID_5704 0x00000000
+#define GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00000000
#define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000
#define GRC_LOCAL_CTRL 0x00006808
#define GRC_LCLCTRL_INT_ACTIVE 0x00000001
#define NIC_SRAM_RX_BUFFER_DESC 0x00006000 /* 256 entries */
#define NIC_SRAM_RX_JUMBO_BUFFER_DESC 0x00007000 /* 256 entries */
#define NIC_SRAM_MBUF_POOL_BASE 0x00008000
-#define NIC_SRAM_MBUF_POOL_SIZE 0x00018000
+#define NIC_SRAM_MBUF_POOL_SIZE96 0x00018000
+#define NIC_SRAM_MBUF_POOL_SIZE64 0x00018000
/* Currently this is fixed. */
#define PHY_ADDR 0x01
#define TG3_FLAG_RX_CHECKSUMS 0x00000004
#define TG3_FLAG_USE_LINKCHG_REG 0x00000008
#define TG3_FLAG_USE_MI_INTERRUPT 0x00000010
+#define TG3_FLAG_ENABLE_ASF 0x00000020
#define TG3_FLAG_POLL_SERDES 0x00000080
#define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100
#define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200
#define TG3_FLAG_PAUSE_TX 0x08000000
#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000
+#define TG3_FLAG_SPLIT_MODE 0x40000000
#define TG3_FLAG_INIT_COMPLETE 0x80000000
u32 msg_enable;
+ u32 split_mode_max_reqs;
+#define SPLIT_MODE_5704_MAX_REQ 3
+
struct timer_list timer;
u16 timer_counter;
u16 timer_multiplier;
u32 timer_offset;
+ u16 asf_counter;
+ u16 asf_multiplier;
struct tg3_link_config link_config;
struct tg3_bufmgr_config bufmgr_config;
#define PHY_ID_BCM5411 0x60008070
#define PHY_ID_BCM5701 0x60008110
#define PHY_ID_BCM5703 0x60008160
+#define PHY_ID_BCM5704 0x60008190
#define PHY_ID_BCM8002 0x60010140
#define PHY_ID_SERDES 0xfeedbee0
#define PHY_ID_INVALID 0xffffffff
#define KNOWN_PHY_ID(X) \
((X) == PHY_ID_BCM5400 || (X) == PHY_ID_BCM5401 || \
(X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
- (X) == PHY_ID_BCM5703 || \
+ (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
(X) == PHY_ID_BCM8002 || (X) == PHY_ID_SERDES)
unsigned long regs;