X-Git-Url: https://bbs.cooldavid.org/git/?a=blobdiff_plain;f=drivers%2Fnet%2Ftg3.c;h=7892b0034c4f956709a63f6d6b4e6b4ec137b7c0;hb=c885e824699f49bc3758a0dec760e189cd774e79;hp=573054ae7b58687dbe52eee0be849f0436159e1c;hpb=1f7f314bf2a77f1d499b41001ebdafb261f00f30;p=net-next-2.6.git diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 573054ae7b5..7892b0034c4 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -67,8 +68,11 @@ #include "tg3.h" #define DRV_MODULE_NAME "tg3" -#define DRV_MODULE_VERSION "3.110" -#define DRV_MODULE_RELDATE "April 9, 2010" +#define TG3_MAJ_NUM 3 +#define TG3_MIN_NUM 112 +#define DRV_MODULE_VERSION \ + __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) +#define DRV_MODULE_RELDATE "July 11, 2010" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -145,8 +149,6 @@ #define TG3_RX_JMB_BUFF_RING_SIZE \ (sizeof(struct ring_info) * TG3_RX_JUMBO_RING_SIZE) -#define TG3_RSS_MIN_NUM_MSIX_VECS 2 - /* Due to a hardware bug, the 5701 can only DMA to memory addresses * that are at least dword aligned when used in PCIX mode. The driver * works around this bug by double copying the packet. This workaround @@ -272,6 +274,7 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57765)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57791)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57795)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)}, {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)}, {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)}, @@ -585,18 +588,23 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) static void tg3_ape_lock_init(struct tg3 *tp) { int i; + u32 regbase; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) + regbase = TG3_APE_LOCK_GRANT; + else + regbase = TG3_APE_PER_LOCK_GRANT; /* Make sure the driver hasn't any stale locks. */ for (i = 0; i < 8; i++) - tg3_ape_write32(tp, TG3_APE_LOCK_GRANT + 4 * i, - APE_LOCK_GRANT_DRIVER); + tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER); } static int tg3_ape_lock(struct tg3 *tp, int locknum) { int i, off; int ret = 0; - u32 status; + u32 status, req, gnt; if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) return 0; @@ -609,13 +617,21 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) return -EINVAL; } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) { + req = TG3_APE_LOCK_REQ; + gnt = TG3_APE_LOCK_GRANT; + } else { + req = TG3_APE_PER_LOCK_REQ; + gnt = TG3_APE_PER_LOCK_GRANT; + } + off = 4 * locknum; - tg3_ape_write32(tp, TG3_APE_LOCK_REQ + off, APE_LOCK_REQ_DRIVER); + tg3_ape_write32(tp, req + off, APE_LOCK_REQ_DRIVER); /* Wait for up to 1 millisecond to acquire lock. */ for (i = 0; i < 100; i++) { - status = tg3_ape_read32(tp, TG3_APE_LOCK_GRANT + off); + status = tg3_ape_read32(tp, gnt + off); if (status == APE_LOCK_GRANT_DRIVER) break; udelay(10); @@ -623,7 +639,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) if (status != APE_LOCK_GRANT_DRIVER) { /* Revoke the lock request. */ - tg3_ape_write32(tp, TG3_APE_LOCK_GRANT + off, + tg3_ape_write32(tp, gnt + off, APE_LOCK_GRANT_DRIVER); ret = -EBUSY; @@ -634,7 +650,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) static void tg3_ape_unlock(struct tg3 *tp, int locknum) { - int off; + u32 gnt; if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) return; @@ -647,8 +663,12 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum) return; } - off = 4 * locknum; - tg3_ape_write32(tp, TG3_APE_LOCK_GRANT + off, APE_LOCK_GRANT_DRIVER); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) + gnt = TG3_APE_LOCK_GRANT; + else + gnt = TG3_APE_PER_LOCK_GRANT; + + tg3_ape_write32(tp, gnt + 4 * locknum, APE_LOCK_GRANT_DRIVER); } static void tg3_disable_ints(struct tg3 *tp) @@ -1069,14 +1089,11 @@ static int tg3_mdio_init(struct tg3 *tp) u32 reg; struct phy_device *phydev; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) { - u32 funcnum, is_serdes; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + u32 is_serdes; - funcnum = tr32(TG3_CPMU_STATUS) & TG3_CPMU_STATUS_PCIE_FUNC; - if (funcnum) - tp->phy_addr = 2; - else - tp->phy_addr = 1; + tp->phy_addr = PCI_FUNC(tp->pdev->devfn) + 1; if (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES; @@ -1589,7 +1606,8 @@ static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable) u32 reg; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 && + ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) && (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))) return; @@ -1964,7 +1982,8 @@ static int tg3_phy_reset(struct tg3 *tp) } } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 && + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) && (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)) return 0; @@ -2049,6 +2068,7 @@ static void tg3_frob_aux_power(struct tg3 *tp) /* The GPIOs do something completely different on 57765. */ if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) return; @@ -4191,6 +4211,8 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset) current_duplex = DUPLEX_FULL; else current_duplex = DUPLEX_HALF; + } else if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { + /* Link is up via parallel detect */ } else { current_link_up = 0; } @@ -5552,8 +5574,8 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, entry = tnapi->tx_prod; base_flags = 0; - mss = 0; - if ((mss = skb_shinfo(skb)->gso_size) != 0) { + mss = skb_shinfo(skb)->gso_size; + if (mss) { int tcp_opt_len, ip_tcp_len; u32 hdrlen; @@ -5759,9 +5781,10 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, if (skb->ip_summed == CHECKSUM_PARTIAL) base_flags |= TXD_FLAG_TCPUDP_CSUM; - if ((mss = skb_shinfo(skb)->gso_size) != 0) { + mss = skb_shinfo(skb)->gso_size; + if (mss) { struct iphdr *iph; - u32 tcp_opt_len, ip_tcp_len, hdr_len; + u32 tcp_opt_len, hdr_len; if (skb_header_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { @@ -5769,10 +5792,21 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, goto out_unlock; } + iph = ip_hdr(skb); tcp_opt_len = tcp_optlen(skb); - ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr); - hdr_len = ip_tcp_len + tcp_opt_len; + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { + hdr_len = skb_headlen(skb) - ETH_HLEN; + } else { + u32 ip_tcp_len; + + ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr); + hdr_len = ip_tcp_len + tcp_opt_len; + + iph->check = 0; + iph->tot_len = htons(mss + hdr_len); + } + if (unlikely((ETH_HLEN + hdr_len) > 80) && (tp->tg3_flags2 & TG3_FLG2_TSO_BUG)) return tg3_tso_bug(tp, skb); @@ -5780,9 +5814,6 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, base_flags |= (TXD_FLAG_CPU_PRE_DMA | TXD_FLAG_CPU_POST_DMA); - iph = ip_hdr(skb); - iph->check = 0; - iph->tot_len = htons(mss + hdr_len); if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { tcp_hdr(skb)->check = 0; base_flags &= ~TXD_FLAG_TCPUDP_CSUM; @@ -6212,6 +6243,8 @@ static void tg3_free_rings(struct tg3 *tp) for (j = 0; j < tp->irq_cnt; j++) { struct tg3_napi *tnapi = &tp->napi[j]; + tg3_rx_prodring_free(tp, &tp->prodring[j]); + if (!tnapi->tx_buffers) continue; @@ -6247,8 +6280,6 @@ static void tg3_free_rings(struct tg3 *tp) dev_kfree_skb_any(skb); } - - tg3_rx_prodring_free(tp, &tp->prodring[j]); } } @@ -6603,7 +6634,7 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) apedata = tg3_ape_read32(tp, TG3_APE_HOST_INIT_COUNT); tg3_ape_write32(tp, TG3_APE_HOST_INIT_COUNT, ++apedata); tg3_ape_write32(tp, TG3_APE_HOST_DRIVER_ID, - APE_HOST_DRIVER_ID_MAGIC); + APE_HOST_DRIVER_ID_MAGIC(TG3_MAJ_NUM, TG3_MIN_NUM)); tg3_ape_write32(tp, TG3_APE_HOST_BEHAVIOR, APE_HOST_BEHAV_NO_PHYLOCK); @@ -6782,7 +6813,8 @@ static void tg3_restore_pci_state(struct tg3 *tp) /* Allow reads and writes to the APE register and memory space. */ if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) val |= PCISTATE_ALLOW_APE_CTLSPC_WR | - PCISTATE_ALLOW_APE_SHMEM_WR; + PCISTATE_ALLOW_APE_SHMEM_WR | + PCISTATE_ALLOW_APE_PSPACE_WR; pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val); pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd); @@ -6970,8 +7002,7 @@ static int tg3_chip_reset(struct tg3 *tp) * Older PCIe devices only support the 128 byte * MPS setting. Enforce the restriction. */ - if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784)) + if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)) val16 &= ~PCI_EXP_DEVCTL_PAYLOAD; pci_write_config_word(tp->pdev, tp->pcie_cap + PCI_EXP_DEVCTL, @@ -7041,35 +7072,10 @@ static int tg3_chip_reset(struct tg3 *tp) tg3_mdio_start(tp); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) { - u8 phy_addr; - - phy_addr = tp->phy_addr; - tp->phy_addr = TG3_PHY_PCIE_ADDR; - - tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR, - TG3_PCIEPHY_TXB_BLK << TG3_PCIEPHY_BLOCK_SHIFT); - val = TG3_PCIEPHY_TX0CTRL1_TXOCM | TG3_PCIEPHY_TX0CTRL1_RDCTL | - TG3_PCIEPHY_TX0CTRL1_TXCMV | TG3_PCIEPHY_TX0CTRL1_TKSEL | - TG3_PCIEPHY_TX0CTRL1_NB_EN; - tg3_writephy(tp, TG3_PCIEPHY_TX0CTRL1, val); - udelay(10); - - tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR, - TG3_PCIEPHY_XGXS_BLK1 << TG3_PCIEPHY_BLOCK_SHIFT); - val = TG3_PCIEPHY_PWRMGMT4_LOWPWR_EN | - TG3_PCIEPHY_PWRMGMT4_L1PLLPD_EN; - tg3_writephy(tp, TG3_PCIEPHY_PWRMGMT4, val); - udelay(10); - - tp->phy_addr = phy_addr; - } - if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && tp->pci_chip_rev_id != CHIPREV_ID_5750_A0 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) { + !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { val = tr32(0x7c00); tw32(0x7c00, val | (1 << 25)); @@ -7427,7 +7433,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec) tw32(HOSTCC_TXCOAL_MAXF_INT, 0); } - if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) { + if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) { tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs); tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames); tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq); @@ -7504,7 +7510,8 @@ static void tg3_rings_reset(struct tg3 *tp) /* Disable all receive return rings but the first. */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 17; else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16; @@ -7720,7 +7727,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) */ val = tr32(TG3PCI_PCISTATE); val |= PCISTATE_ALLOW_APE_CTLSPC_WR | - PCISTATE_ALLOW_APE_SHMEM_WR; + PCISTATE_ALLOW_APE_SHMEM_WR | + PCISTATE_ALLOW_APE_PSPACE_WR; tw32(TG3PCI_PCISTATE, val); } @@ -7740,8 +7748,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (err) return err; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { val = tr32(TG3PCI_DMA_RW_CTRL) & ~DMA_RWCTRL_DIS_CACHE_ALIGNMENT; if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0) @@ -7869,7 +7876,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) ((u64) tpr->rx_std_mapping >> 32)); tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, ((u64) tpr->rx_std_mapping & 0xffffffff)); - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719) tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR, NIC_SRAM_RX_BUFFER_DESC); @@ -7894,7 +7902,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, (RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) | BDINFO_FLAGS_USE_EXT_RECV); - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) + if (!(tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR, NIC_SRAM_RX_JUMBO_BUFFER_DESC); } else { @@ -7902,8 +7911,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) BDINFO_FLAGS_DISABLED); } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) val = (RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT) | (TG3_RX_STD_DMA_SZ << 2); else @@ -7920,8 +7928,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tp->rx_jumbo_pending : 0; tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { tw32(STD_REPLENISH_LWM, 32); tw32(JMB_REPLENISH_LWM, 16); } @@ -7956,7 +7963,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | RDMAC_MODE_LNGREAD_ENAB); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) rdmac_mode |= RDMAC_MODE_MULT_DMA_RD_DIS; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || @@ -8195,6 +8203,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) } tp->tx_mode = TX_MODE_ENABLE; + if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + tp->tx_mode |= TX_MODE_MBUF_LOCKUP_FIX; tw32_f(MAC_TX_MODE, tp->tx_mode); udelay(100); @@ -8495,7 +8506,7 @@ static void tg3_timer(unsigned long __opaque) (mac_stat & MAC_STATUS_LNKSTATE_CHANGED)) { need_setup = 1; } - if (! netif_carrier_ok(tp->dev) && + if (!netif_carrier_ok(tp->dev) && (mac_stat & (MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DET))) { need_setup = 1; @@ -8511,8 +8522,10 @@ static void tg3_timer(unsigned long __opaque) } tg3_setup_phy(tp, 0); } - } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) + } else if ((tp->tg3_flags2 & TG3_FLG2_MII_SERDES) && + (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { tg3_serdes_parallel_detect(tp); + } tp->timer_counter = tp->timer_multiplier; } @@ -8605,8 +8618,7 @@ static int tg3_test_interrupt(struct tg3 *tp) * Turn off MSI one shot mode. Otherwise this test has no * observable way to know whether the interrupt was delivered. */ - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) && + if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) { val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); @@ -8649,8 +8661,7 @@ static int tg3_test_interrupt(struct tg3 *tp) if (intr_ok) { /* Reenable MSI one shot mode. */ - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) && + if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) { val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE; tw32(MSGINT_MODE, val); @@ -8775,9 +8786,9 @@ static bool tg3_enable_msix(struct tg3 *tp) } rc = pci_enable_msix(tp->pdev, msix_ent, tp->irq_cnt); - if (rc != 0) { - if (rc < TG3_RSS_MIN_NUM_MSIX_VECS) - return false; + if (rc < 0) { + return false; + } else if (rc != 0) { if (pci_enable_msix(tp->pdev, msix_ent, rc)) return false; netdev_notice(tp->dev, "Requested %d MSI-X vectors, received %d\n", @@ -8785,16 +8796,19 @@ static bool tg3_enable_msix(struct tg3 *tp) tp->irq_cnt = rc; } - tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS; - for (i = 0; i < tp->irq_max; i++) tp->napi[i].irq_vec = msix_ent[i].vector; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) { - tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS; - tp->dev->real_num_tx_queues = tp->irq_cnt - 1; - } else - tp->dev->real_num_tx_queues = 1; + tp->dev->real_num_tx_queues = 1; + if (tp->irq_cnt > 1) { + tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS; + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS; + tp->dev->real_num_tx_queues = tp->irq_cnt - 1; + } + } return true; } @@ -8838,7 +8852,7 @@ static void tg3_ints_fini(struct tg3 *tp) else if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) pci_disable_msi(tp->pdev); tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI_OR_MSIX; - tp->tg3_flags3 &= ~TG3_FLG3_ENABLE_RSS; + tp->tg3_flags3 &= ~(TG3_FLG3_ENABLE_RSS | TG3_FLG3_ENABLE_TSS); } static int tg3_open(struct net_device *dev) @@ -8942,10 +8956,8 @@ static int tg3_open(struct net_device *dev) goto err_out2; } - if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765 && - (tp->tg3_flags2 & TG3_FLG2_USING_MSI) && - (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)) { + if (!(tp->tg3_flags3 & TG3_FLG3_5717_PLUS) && + (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) { u32 val = tr32(PCIE_TRANSACTION_CFG); tw32(PCIE_TRANSACTION_CFG, @@ -8982,7 +8994,8 @@ err_out1: return err; } -static struct net_device_stats *tg3_get_stats(struct net_device *); +static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *, + struct rtnl_link_stats64 *); static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *); static int tg3_close(struct net_device *dev) @@ -9016,8 +9029,8 @@ static int tg3_close(struct net_device *dev) tg3_ints_fini(tp); - memcpy(&tp->net_stats_prev, tg3_get_stats(tp->dev), - sizeof(tp->net_stats_prev)); + tg3_get_stats64(tp->dev, &tp->net_stats_prev); + memcpy(&tp->estats_prev, tg3_get_estats(tp), sizeof(tp->estats_prev)); @@ -9030,24 +9043,12 @@ static int tg3_close(struct net_device *dev) return 0; } -static inline unsigned long get_stat64(tg3_stat64_t *val) -{ - unsigned long ret; - -#if (BITS_PER_LONG == 32) - ret = val->low; -#else - ret = ((u64)val->high << 32) | ((u64)val->low); -#endif - return ret; -} - -static inline u64 get_estat64(tg3_stat64_t *val) +static inline u64 get_stat64(tg3_stat64_t *val) { return ((u64)val->high << 32) | ((u64)val->low); } -static unsigned long calc_crc_errors(struct tg3 *tp) +static u64 calc_crc_errors(struct tg3 *tp) { struct tg3_hw_stats *hw_stats = tp->hw_stats; @@ -9075,7 +9076,7 @@ static unsigned long calc_crc_errors(struct tg3 *tp) #define ESTAT_ADD(member) \ estats->member = old_estats->member + \ - get_estat64(&hw_stats->member) + get_stat64(&hw_stats->member) static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp) { @@ -9165,11 +9166,11 @@ static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp) return estats; } -static struct net_device_stats *tg3_get_stats(struct net_device *dev) +static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) { struct tg3 *tp = netdev_priv(dev); - struct net_device_stats *stats = &tp->net_stats; - struct net_device_stats *old_stats = &tp->net_stats_prev; + struct rtnl_link_stats64 *old_stats = &tp->net_stats_prev; struct tg3_hw_stats *hw_stats = tp->hw_stats; if (!hw_stats) @@ -9356,7 +9357,7 @@ static void tg3_get_regs(struct net_device *dev, tg3_full_lock(tp, 0); #define __GET_REG32(reg) (*(p)++ = tr32(reg)) -#define GET_REG32_LOOP(base,len) \ +#define GET_REG32_LOOP(base, len) \ do { p = (u32 *)(orig_p + (base)); \ for (i = 0; i < len; i += 4) \ __GET_REG32((base) + i); \ @@ -9449,7 +9450,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, ret = tg3_nvram_read_be32(tp, offset-b_offset, &val); if (ret) return ret; - memcpy(data, ((char*)&val) + b_offset, b_count); + memcpy(data, ((char *)&val) + b_offset, b_count); len -= b_count; offset += b_count; eeprom->len += b_count; @@ -10554,7 +10555,8 @@ static int tg3_test_memory(struct tg3 *tp) int err = 0; int i; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) mem_tbl = mem_tbl_5717; else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) mem_tbl = mem_tbl_57765; @@ -10568,8 +10570,8 @@ static int tg3_test_memory(struct tg3 *tp) mem_tbl = mem_tbl_570x; for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) { - if ((err = tg3_do_mem_test(tp, mem_tbl[i].offset, - mem_tbl[i].len)) != 0) + err = tg3_do_mem_test(tp, mem_tbl[i].offset, mem_tbl[i].len); + if (err) break; } @@ -10914,7 +10916,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)) return -EAGAIN; phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]; - return phy_mii_ioctl(phydev, data, cmd); + return phy_mii_ioctl(phydev, ifr, cmd); } switch (cmd) { @@ -11634,7 +11636,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) tg3_get_57780_nvram_info(tp); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) tg3_get_5717_nvram_info(tp); else tg3_get_nvram_info(tp); @@ -12070,11 +12073,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->phy_id = eeprom_phy_id; if (eeprom_phy_serdes) { - if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) - tp->tg3_flags2 |= TG3_FLG2_MII_SERDES; - else + if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; + else + tp->tg3_flags2 |= TG3_FLG2_MII_SERDES; } if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) @@ -12760,6 +12762,13 @@ done: static struct pci_dev * __devinit tg3_find_peer(struct tg3 *); +static void inline vlan_features_add(struct net_device *dev, unsigned long flags) +{ +#if TG3_VLAN_TAG_USED + dev->vlan_features |= flags; +#endif +} + static int __devinit tg3_get_invariants(struct tg3 *tp) { static struct pci_device_id write_reorder_chipsets[] = { @@ -12804,7 +12813,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_5724) + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5724 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719) pci_read_config_dword(tp->pdev, TG3PCI_GEN2_PRODID_ASICREV, &prod_id_asic_rev); @@ -12962,6 +12972,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) tp->pdev_peer = tg3_find_peer(tp); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) + tp->tg3_flags3 |= TG3_FLG3_5717_PLUS; + /* Intentionally exclude ASIC_REV_5906 */ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || @@ -12969,8 +12984,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) + (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) tp->tg3_flags3 |= TG3_FLG3_5755_PLUS; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 || @@ -12990,16 +13004,17 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0) tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS; else { + unsigned long features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO; + tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS; - tp->dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS) - tp->dev->features |= NETIF_F_IPV6_CSUM; - tp->dev->features |= NETIF_F_GRO; + features |= NETIF_F_IPV6_CSUM; + tp->dev->features |= features; + vlan_features_add(tp->dev, features); } /* Determine TSO capabilities */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3; else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) @@ -13035,14 +13050,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI; } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX; tp->irq_max = TG3_IRQ_MAX_VECS; } } if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) tp->tg3_flags3 |= TG3_FLG3_SHORT_DMA_BUG; else if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS)) { @@ -13050,8 +13065,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG; } - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) || @@ -13242,7 +13256,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) * APE register and memory space. */ pci_state_reg |= PCISTATE_ALLOW_APE_CTLSPC_WR | - PCISTATE_ALLOW_APE_SHMEM_WR; + PCISTATE_ALLOW_APE_SHMEM_WR | + PCISTATE_ALLOW_APE_PSPACE_WR; pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg); } @@ -13251,8 +13266,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) + (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT; /* Set up tp->grc_local_ctrl before calling tg3_set_power_state(). @@ -13331,8 +13345,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) !(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && - GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765) { + !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || @@ -13372,8 +13385,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) return err; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 && - (tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 || - (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))) + tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) return -ENOTSUPP; /* Initialize data/descriptor byte/word swapping. */ @@ -13580,9 +13592,12 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) tw32_f(NVRAM_CMD, NVRAM_CMD_RESET); else tg3_nvram_unlock(tp); - } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) { - if (tr32(TG3_CPMU_STATUS) & TG3_CPMU_STATUS_PCIE_FUNC) + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + if (PCI_FUNC(tp->pdev->devfn) & 1) mac_offset = 0xcc; + if (PCI_FUNC(tp->pdev->devfn) > 1) + mac_offset += 0x18c; } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) mac_offset = 0x10; @@ -13667,8 +13682,7 @@ static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val) #endif #endif - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { val = goal ? 0 : DMA_RWCTRL_DIS_CACHE_ALIGNMENT; goto out; } @@ -13879,8 +13893,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) goto out; if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { @@ -14078,8 +14091,7 @@ static void __devinit tg3_init_link_config(struct tg3 *tp) static void __devinit tg3_init_bufmgr_config(struct tg3 *tp) { - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { tp->bufmgr_config.mbuf_read_dma_low_water = DEFAULT_MB_RDMA_LOW_WATER_5705; tp->bufmgr_config.mbuf_mac_rx_low_water = @@ -14156,6 +14168,7 @@ static char * __devinit tg3_phy_string(struct tg3 *tp) case TG3_PHY_ID_BCM5718C: return "5718C"; case TG3_PHY_ID_BCM5718S: return "5718S"; case TG3_PHY_ID_BCM57765: return "57765"; + case TG3_PHY_ID_BCM5719C: return "5719C"; case TG3_PHY_ID_BCM8002: return "8002/serdes"; case 0: return "serdes"; default: return "unknown"; @@ -14261,7 +14274,7 @@ static const struct net_device_ops tg3_netdev_ops = { .ndo_open = tg3_open, .ndo_stop = tg3_close, .ndo_start_xmit = tg3_start_xmit, - .ndo_get_stats = tg3_get_stats, + .ndo_get_stats64 = tg3_get_stats64, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = tg3_set_rx_mode, .ndo_set_mac_address = tg3_set_mac_addr, @@ -14280,7 +14293,7 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = { .ndo_open = tg3_open, .ndo_stop = tg3_close, .ndo_start_xmit = tg3_start_xmit_dma_bug, - .ndo_get_stats = tg3_get_stats, + .ndo_get_stats64 = tg3_get_stats64, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = tg3_set_rx_mode, .ndo_set_mac_address = tg3_set_mac_addr, @@ -14404,7 +14417,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, } if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) && - tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) + tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719) dev->netdev_ops = &tg3_netdev_ops; else dev->netdev_ops = &tg3_netdev_ops_dma_bug; @@ -14468,20 +14482,25 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, * is off by default, but can be enabled using ethtool. */ if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) && - (dev->features & NETIF_F_IP_CSUM)) + (dev->features & NETIF_F_IP_CSUM)) { dev->features |= NETIF_F_TSO; - + vlan_features_add(dev, NETIF_F_TSO); + } if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) || (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3)) { - if (dev->features & NETIF_F_IPV6_CSUM) + if (dev->features & NETIF_F_IPV6_CSUM) { dev->features |= NETIF_F_TSO6; + vlan_features_add(dev, NETIF_F_TSO6); + } if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 && GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) { dev->features |= NETIF_F_TSO_ECN; + vlan_features_add(dev, NETIF_F_TSO_ECN); + } } if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&