diff options
| -rw-r--r-- | drivers/net/tg3.c | 158 | ||||
| -rw-r--r-- | drivers/net/tg3.h | 26 | ||||
| -rw-r--r-- | drivers/pci/pci.ids | 1 | ||||
| -rw-r--r-- | include/linux/pci_ids.h | 1 |
4 files changed, 164 insertions, 22 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 79d2d5400418..122b5aa10204 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -149,6 +149,8 @@ static struct pci_device_id tg3_pci_tbl[] __devinitdata = { 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, @@ -407,7 +409,6 @@ static int tg3_set_power_state(struct tg3 *tp, int state) tr32(GRC_LOCAL_CTRL); udelay(100); - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02); return 0; case 1: @@ -873,6 +874,8 @@ static int tg3_setup_copper_phy(struct tg3 *tp) 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); @@ -3111,9 +3114,11 @@ static void tg3_chip_reset(struct tg3 *tp) 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); @@ -3128,11 +3133,33 @@ static void tg3_chip_reset(struct tg3 *tp) } /* 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, @@ -3152,6 +3179,17 @@ static int tg3_halt(struct tg3 *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; } @@ -3849,6 +3887,8 @@ static int tg3_reset_hw(struct tg3 *tp) tg3_disable_ints(tp); + tg3_stop_fw(tp); + if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) { err = tg3_abort_hw(tp); if (err) @@ -3883,6 +3923,13 @@ static int tg3_reset_hw(struct tg3 *tp) 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. @@ -3892,6 +3939,13 @@ static int tg3_reset_hw(struct tg3 *tp) 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; @@ -3929,7 +3983,10 @@ static int tg3_reset_hw(struct tg3 *tp) /* 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); @@ -4195,11 +4252,25 @@ static int tg3_reset_hw(struct tg3 *tp) 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); @@ -4392,6 +4463,21 @@ static void tg3_timer(unsigned long __opaque) 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); @@ -4440,6 +4526,7 @@ static int tg3_open(struct net_device *dev) } 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; @@ -5703,6 +5790,9 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) 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 @@ -5770,6 +5860,11 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) 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); @@ -6085,9 +6180,16 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) 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! @@ -6177,7 +6279,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) 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); @@ -6192,8 +6299,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) 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); @@ -6321,16 +6428,26 @@ static int __devinit tg3_test_dma(struct tg3 *tp) (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; } @@ -6505,6 +6622,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp) 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"; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 445c5067178a..6b358ff82387 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -58,6 +58,11 @@ #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 @@ -109,10 +114,13 @@ #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 @@ -165,6 +173,7 @@ #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 @@ -843,6 +852,8 @@ #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 @@ -1126,6 +1137,8 @@ #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 @@ -1297,7 +1310,8 @@ #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 @@ -1749,6 +1763,7 @@ struct tg3 { #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 @@ -1772,14 +1787,20 @@ struct tg3 { #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; @@ -1820,6 +1841,7 @@ struct tg3 { #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 @@ -1839,7 +1861,7 @@ struct tg3 { #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; diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids index 186c8fdd99ad..3290c4213660 100644 --- a/drivers/pci/pci.ids +++ b/drivers/pci/pci.ids @@ -5053,6 +5053,7 @@ 14e4 000b BCM5703 1000BaseTX 14e4 8009 BCM5703 1000BaseTX 14e4 800a BCM5703 1000BaseTX + 1648 NetXtreme BCM5704 Gigabit Ethernet 164d NetXtreme BCM5702FE Gigabit Ethernet 16a6 NetXtreme BCM5702X Gigabit Ethernet 16a7 NetXtreme BCM5703X Gigabit Ethernet diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 5eea9545b69a..9a1ad256e2cc 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1561,6 +1561,7 @@ #define PCI_DEVICE_ID_TIGON3_5701 0x1645 #define PCI_DEVICE_ID_TIGON3_5702 0x1646 #define PCI_DEVICE_ID_TIGON3_5703 0x1647 +#define PCI_DEVICE_ID_TIGON3_5704 0x1648 #define PCI_DEVICE_ID_TIGON3_5702FE 0x164d #define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 #define PCI_DEVICE_ID_TIGON3_5703X 0x16a7 |
