diff options
Diffstat (limited to 'drivers/net/ethernet/realtek/r8169_main.c')
-rw-r--r-- | drivers/net/ethernet/realtek/r8169_main.c | 342 |
1 files changed, 120 insertions, 222 deletions
diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 791d99b9e1cf..9971135a7ab5 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -212,7 +212,6 @@ enum rtl_registers { /* Unlimited maximum PCI burst. */ #define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT) - RxMissed = 0x4c, Cfg9346 = 0x50, Config0 = 0x51, Config1 = 0x52, @@ -576,6 +575,7 @@ struct rtl8169_tc_offsets { __le64 tx_errors; __le32 tx_multi_collision; __le16 tx_aborted; + __le16 rx_missed; }; enum rtl_flag { @@ -689,6 +689,12 @@ static void rtl_unlock_config_regs(struct rtl8169_private *tp) RTL_W8(tp, Cfg9346, Cfg9346_Unlock); } +static void rtl_pci_commit(struct rtl8169_private *tp) +{ + /* Read an arbitrary register to commit a preceding PCI write */ + RTL_R8(tp, ChipCmd); +} + static bool rtl_is_8125(struct rtl8169_private *tp) { return tp->mac_version >= RTL_GIGA_MAC_VER_60; @@ -1302,10 +1308,6 @@ static void rtl_irq_disable(struct rtl8169_private *tp) tp->irq_enabled = 0; } -#define RTL_EVENT_NAPI_RX (RxOK | RxErr) -#define RTL_EVENT_NAPI_TX (TxOK | TxErr) -#define RTL_EVENT_NAPI (RTL_EVENT_NAPI_RX | RTL_EVENT_NAPI_TX) - static void rtl_irq_enable(struct rtl8169_private *tp) { tp->irq_enabled = 1; @@ -1319,18 +1321,13 @@ static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) { rtl_irq_disable(tp); rtl_ack_events(tp, 0xffffffff); - /* PCI commit */ - RTL_R8(tp, ChipCmd); + rtl_pci_commit(tp); } static void rtl_link_chg_patch(struct rtl8169_private *tp) { - struct net_device *dev = tp->dev; struct phy_device *phydev = tp->phydev; - if (!netif_running(dev)) - return; - if (tp->mac_version == RTL_GIGA_MAC_VER_34 || tp->mac_version == RTL_GIGA_MAC_VER_38) { if (phydev->speed == SPEED_1000) { @@ -1536,7 +1533,7 @@ static int rtl8169_set_features(struct net_device *dev, } RTL_W16(tp, CPlusCmd, tp->cp_cmd); - RTL_R16(tp, CPlusCmd); + rtl_pci_commit(tp); rtl_unlock_work(tp); @@ -1622,7 +1619,7 @@ static bool rtl8169_do_counters(struct rtl8169_private *tp, u32 counter_cmd) u32 cmd; RTL_W32(tp, CounterAddrHigh, (u64)paddr >> 32); - RTL_R32(tp, CounterAddrHigh); + rtl_pci_commit(tp); cmd = (u64)paddr & DMA_BIT_MASK(32); RTL_W32(tp, CounterAddrLow, cmd); RTL_W32(tp, CounterAddrLow, cmd | counter_cmd); @@ -1689,6 +1686,7 @@ static bool rtl8169_init_counter_offsets(struct rtl8169_private *tp) tp->tc_offset.tx_errors = counters->tx_errors; tp->tc_offset.tx_multi_collision = counters->tx_multi_collision; tp->tc_offset.tx_aborted = counters->tx_aborted; + tp->tc_offset.rx_missed = counters->rx_missed; tp->tc_offset.inited = true; return ret; @@ -1946,7 +1944,7 @@ static int rtl_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) tp->cp_cmd = (tp->cp_cmd & ~INTT_MASK) | cp01; RTL_W16(tp, CPlusCmd, tp->cp_cmd); - RTL_R16(tp, CPlusCmd); + rtl_pci_commit(tp); rtl_unlock_work(tp); @@ -2008,6 +2006,8 @@ out: } static const struct ethtool_ops rtl8169_ethtool_ops = { + .supported_coalesce_params = ETHTOOL_COALESCE_USECS | + ETHTOOL_COALESCE_MAX_FRAMES, .get_drvinfo = rtl8169_get_drvinfo, .get_regs_len = rtl8169_get_regs_len, .get_link = ethtool_op_get_link, @@ -2044,7 +2044,7 @@ static void rtl_enable_eee(struct rtl8169_private *tp) phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv); } -static void rtl8169_get_mac_version(struct rtl8169_private *tp) +static enum mac_version rtl8169_get_mac_version(u16 xid, bool gmii) { /* * The driver currently handles the 8168Bf and the 8168Be identically @@ -2060,7 +2060,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp) static const struct rtl_mac_info { u16 mask; u16 val; - u16 mac_version; + enum mac_version ver; } mac_info[] = { /* 8125 family. */ { 0x7cf, 0x608, RTL_GIGA_MAC_VER_60 }, @@ -2147,22 +2147,22 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp) { 0x000, 0x000, RTL_GIGA_MAC_NONE } }; const struct rtl_mac_info *p = mac_info; - u16 reg = RTL_R32(tp, TxConfig) >> 20; + enum mac_version ver; - while ((reg & p->mask) != p->val) + while ((xid & p->mask) != p->val) p++; - tp->mac_version = p->mac_version; - - if (tp->mac_version == RTL_GIGA_MAC_NONE) { - dev_err(tp_to_dev(tp), "unknown chip XID %03x\n", reg & 0xfcf); - } else if (!tp->supports_gmii) { - if (tp->mac_version == RTL_GIGA_MAC_VER_42) - tp->mac_version = RTL_GIGA_MAC_VER_43; - else if (tp->mac_version == RTL_GIGA_MAC_VER_45) - tp->mac_version = RTL_GIGA_MAC_VER_47; - else if (tp->mac_version == RTL_GIGA_MAC_VER_46) - tp->mac_version = RTL_GIGA_MAC_VER_48; + ver = p->ver; + + if (ver != RTL_GIGA_MAC_NONE && !gmii) { + if (ver == RTL_GIGA_MAC_VER_42) + ver = RTL_GIGA_MAC_VER_43; + else if (ver == RTL_GIGA_MAC_VER_45) + ver = RTL_GIGA_MAC_VER_47; + else if (ver == RTL_GIGA_MAC_VER_46) + ver = RTL_GIGA_MAC_VER_48; } + + return ver; } static void rtl_release_firmware(struct rtl8169_private *tp) @@ -2228,8 +2228,8 @@ u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp) static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) { - if (!test_and_set_bit(flag, tp->wk.flags)) - schedule_work(&tp->wk.work); + set_bit(flag, tp->wk.flags); + schedule_work(&tp->wk.work); } static void rtl8169_init_phy(struct rtl8169_private *tp) @@ -2264,10 +2264,10 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) rtl_unlock_config_regs(tp); RTL_W32(tp, MAC4, addr[4] | addr[5] << 8); - RTL_R32(tp, MAC4); + rtl_pci_commit(tp); RTL_W32(tp, MAC0, addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); - RTL_R32(tp, MAC0); + rtl_pci_commit(tp); if (tp->mac_version == RTL_GIGA_MAC_VER_34) rtl_rar_exgmac_set(tp, addr); @@ -2471,66 +2471,52 @@ static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp) RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0)); } -static void rtl_hw_jumbo_enable(struct rtl8169_private *tp) +static void rtl_jumbo_config(struct rtl8169_private *tp) { - rtl_unlock_config_regs(tp); - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_12: - case RTL_GIGA_MAC_VER_17: - pcie_set_readrq(tp->pci_dev, 512); - r8168b_1_hw_jumbo_enable(tp); - break; - case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26: - pcie_set_readrq(tp->pci_dev, 512); - r8168c_hw_jumbo_enable(tp); - break; - case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28: - r8168dp_hw_jumbo_enable(tp); - break; - case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33: - pcie_set_readrq(tp->pci_dev, 512); - r8168e_hw_jumbo_enable(tp); - break; - default: - break; - } - rtl_lock_config_regs(tp); -} + bool jumbo = tp->dev->mtu > ETH_DATA_LEN; -static void rtl_hw_jumbo_disable(struct rtl8169_private *tp) -{ rtl_unlock_config_regs(tp); switch (tp->mac_version) { case RTL_GIGA_MAC_VER_12: case RTL_GIGA_MAC_VER_17: - r8168b_1_hw_jumbo_disable(tp); + if (jumbo) { + pcie_set_readrq(tp->pci_dev, 512); + r8168b_1_hw_jumbo_enable(tp); + } else { + r8168b_1_hw_jumbo_disable(tp); + } break; case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26: - r8168c_hw_jumbo_disable(tp); + if (jumbo) { + pcie_set_readrq(tp->pci_dev, 512); + r8168c_hw_jumbo_enable(tp); + } else { + r8168c_hw_jumbo_disable(tp); + } break; case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28: - r8168dp_hw_jumbo_disable(tp); + if (jumbo) + r8168dp_hw_jumbo_enable(tp); + else + r8168dp_hw_jumbo_disable(tp); break; case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33: - r8168e_hw_jumbo_disable(tp); + if (jumbo) { + pcie_set_readrq(tp->pci_dev, 512); + r8168e_hw_jumbo_enable(tp); + } else { + r8168e_hw_jumbo_disable(tp); + } break; default: break; } rtl_lock_config_regs(tp); - if (pci_is_pcie(tp->pci_dev) && tp->supports_gmii) + if (!jumbo && pci_is_pcie(tp->pci_dev) && tp->supports_gmii) pcie_set_readrq(tp->pci_dev, 4096); } -static void rtl_jumbo_config(struct rtl8169_private *tp, int mtu) -{ - if (mtu > ETH_DATA_LEN) - rtl_hw_jumbo_enable(tp); - else - rtl_hw_jumbo_disable(tp); -} - DECLARE_RTL_COND(rtl_chipcmd_cond) { return RTL_R8(tp, ChipCmd) & CmdReset; @@ -3838,9 +3824,6 @@ static void rtl_hw_start_8168(struct rtl8169_private *tp) static void rtl_hw_start_8169(struct rtl8169_private *tp) { - if (tp->mac_version == RTL_GIGA_MAC_VER_05) - pci_write_config_byte(tp->pci_dev, PCI_CACHE_LINE_SIZE, 0x08); - RTL_W8(tp, EarlyTxThres, NoEarlyTx); tp->cp_cmd |= PCIMulRW; @@ -3853,8 +3836,6 @@ static void rtl_hw_start_8169(struct rtl8169_private *tp) rtl8169_set_magic_reg(tp, tp->mac_version); - RTL_W32(tp, RxMissed, 0); - /* disable interrupt coalescing */ RTL_W16(tp, IntrMitigate, 0x0000); } @@ -3877,10 +3858,11 @@ static void rtl_hw_start(struct rtl8169_private *tp) rtl_set_rx_tx_desc_registers(tp); rtl_lock_config_regs(tp); - rtl_jumbo_config(tp, tp->dev->mtu); + rtl_jumbo_config(tp); /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ - RTL_R16(tp, CPlusCmd); + rtl_pci_commit(tp); + RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb); rtl_init_rxcfg(tp); rtl_set_tx_config_registers(tp); @@ -3892,10 +3874,9 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) { struct rtl8169_private *tp = netdev_priv(dev); - rtl_jumbo_config(tp, new_mtu); - dev->mtu = new_mtu; netdev_update_features(dev); + rtl_jumbo_config(tp); return 0; } @@ -3910,6 +3891,7 @@ static inline void rtl8169_mark_to_asic(struct RxDesc *desc) { u32 eor = le32_to_cpu(desc->opts1) & RingEnd; + desc->opts2 = 0; /* Force memory writes to complete before releasing descriptor */ dma_wmb(); @@ -3991,17 +3973,15 @@ static int rtl8169_init_ring(struct rtl8169_private *tp) return rtl8169_rx_fill(tp); } -static void rtl8169_unmap_tx_skb(struct device *d, struct ring_info *tx_skb, - struct TxDesc *desc) +static void rtl8169_unmap_tx_skb(struct rtl8169_private *tp, unsigned int entry) { - unsigned int len = tx_skb->len; + struct ring_info *tx_skb = tp->tx_skb + entry; + struct TxDesc *desc = tp->TxDescArray + entry; - dma_unmap_single(d, le64_to_cpu(desc->addr), len, DMA_TO_DEVICE); - - desc->opts1 = 0x00; - desc->opts2 = 0x00; - desc->addr = 0x00; - tx_skb->len = 0; + dma_unmap_single(tp_to_dev(tp), le64_to_cpu(desc->addr), tx_skb->len, + DMA_TO_DEVICE); + memset(desc, 0, sizeof(*desc)); + memset(tx_skb, 0, sizeof(*tx_skb)); } static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start, @@ -4017,12 +3997,9 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start, if (len) { struct sk_buff *skb = tx_skb->skb; - rtl8169_unmap_tx_skb(tp_to_dev(tp), tx_skb, - tp->TxDescArray + entry); - if (skb) { + rtl8169_unmap_tx_skb(tp, entry); + if (skb) dev_consume_skb_any(skb); - tx_skb->skb = NULL; - } } } } @@ -4108,12 +4085,10 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, tp->tx_skb[entry].len = len; } - if (cur_frag) { - tp->tx_skb[entry].skb = skb; - txd->opts1 |= cpu_to_le32(LastFrag); - } + tp->tx_skb[entry].skb = skb; + txd->opts1 |= cpu_to_le32(LastFrag); - return cur_frag; + return 0; err_out: rtl8169_tx_clear_range(tp, tp->cur_tx + 1, cur_frag); @@ -4125,29 +4100,6 @@ static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb) return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; } -/* msdn_giant_send_check() - * According to the document of microsoft, the TCP Pseudo Header excludes the - * packet length for IPv6 TCP large packets. - */ -static int msdn_giant_send_check(struct sk_buff *skb) -{ - const struct ipv6hdr *ipv6h; - struct tcphdr *th; - int ret; - - ret = skb_cow_head(skb, 0); - if (ret) - return ret; - - ipv6h = ipv6_hdr(skb); - th = tcp_hdr(skb); - - th->check = 0; - th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0); - - return ret; -} - static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts) { u32 mss = skb_shinfo(skb)->gso_size; @@ -4180,9 +4132,10 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, break; case htons(ETH_P_IPV6): - if (msdn_giant_send_check(skb)) + if (skb_cow_head(skb, 0)) return false; + tcp_v6_gso_csum_prep(skb); opts[0] |= TD1_GTSENV6; break; @@ -4260,6 +4213,7 @@ static void rtl8169_doorbell(struct rtl8169_private *tp) static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev) { + unsigned int frags = skb_shinfo(skb)->nr_frags; struct rtl8169_private *tp = netdev_priv(dev); unsigned int entry = tp->cur_tx % NUM_TX_DESC; struct TxDesc *txd = tp->TxDescArray + entry; @@ -4268,9 +4222,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, u32 opts[2], len; bool stop_queue; bool door_bell; - int frags; - if (unlikely(!rtl_tx_slots_avail(tp, skb_shinfo(skb)->nr_frags))) { + if (unlikely(!rtl_tx_slots_avail(tp, frags))) { netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n"); goto err_stop_0; } @@ -4299,14 +4252,13 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, tp->tx_skb[entry].len = len; txd->addr = cpu_to_le64(mapping); - frags = rtl8169_xmit_frags(tp, skb, opts); - if (frags < 0) - goto err_dma_1; - else if (frags) - opts[0] |= FirstFrag; - else { + if (!frags) { opts[0] |= FirstFrag | LastFrag; tp->tx_skb[entry].skb = skb; + } else { + if (rtl8169_xmit_frags(tp, skb, opts)) + goto err_dma_1; + opts[0] |= FirstFrag; } txd->opts2 = cpu_to_le32(opts[1]); @@ -4354,7 +4306,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; err_dma_1: - rtl8169_unmap_tx_skb(d, tp->tx_skb + entry, txd); + rtl8169_unmap_tx_skb(tp, entry); err_dma_0: dev_kfree_skb_any(skb); dev->stats.tx_dropped++; @@ -4403,13 +4355,15 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); struct pci_dev *pdev = tp->pci_dev; - u16 pci_status, pci_cmd; + int pci_status_errs; + u16 pci_cmd; pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); - pci_read_config_word(pdev, PCI_STATUS, &pci_status); - netif_err(tp, intr, dev, "PCI error (cmd = 0x%04x, status = 0x%04x)\n", - pci_cmd, pci_status); + pci_status_errs = pci_status_get_and_clear_errors(pdev); + + netif_err(tp, intr, dev, "PCI error (cmd = 0x%04x, status_errs = 0x%04x)\n", + pci_cmd, pci_status_errs); /* * The recovery sequence below admits a very elaborated explanation: @@ -4426,11 +4380,6 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); - pci_write_config_word(pdev, PCI_STATUS, - pci_status & (PCI_STATUS_DETECTED_PARITY | - PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_REC_MASTER_ABORT | - PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_SIG_TARGET_ABORT)); - rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } @@ -4441,33 +4390,24 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp, dirty_tx = tp->dirty_tx; smp_rmb(); - tx_left = tp->cur_tx - dirty_tx; - while (tx_left > 0) { + for (tx_left = tp->cur_tx - dirty_tx; tx_left > 0; tx_left--) { unsigned int entry = dirty_tx % NUM_TX_DESC; - struct ring_info *tx_skb = tp->tx_skb + entry; + struct sk_buff *skb = tp->tx_skb[entry].skb; u32 status; status = le32_to_cpu(tp->TxDescArray[entry].opts1); if (status & DescOwn) break; - /* This barrier is needed to keep us from reading - * any other fields out of the Tx descriptor until - * we know the status of DescOwn - */ - dma_rmb(); + rtl8169_unmap_tx_skb(tp, entry); - rtl8169_unmap_tx_skb(tp_to_dev(tp), tx_skb, - tp->TxDescArray + entry); - if (tx_skb->skb) { + if (skb) { pkts_compl++; - bytes_compl += tx_skb->skb->len; - napi_consume_skb(tx_skb->skb, budget); - tx_skb->skb = NULL; + bytes_compl += skb->len; + napi_consume_skb(skb, budget); } dirty_tx++; - tx_left--; } if (tp->dirty_tx != dirty_tx) { @@ -4606,7 +4546,6 @@ process_pkt: u64_stats_update_end(&tp->rx_stats.syncp); } release_descriptor: - desc->opts2 = 0; rtl8169_mark_to_asic(desc); } @@ -4636,8 +4575,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) if (unlikely(status & RxFIFOOver && tp->mac_version == RTL_GIGA_MAC_VER_11)) { netif_stop_queue(tp->dev); - /* XXX - Hack alert. See rtl_task(). */ - set_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } rtl_irq_disable(tp); @@ -4650,31 +4588,17 @@ out: static void rtl_task(struct work_struct *work) { - static const struct { - int bitnr; - void (*action)(struct rtl8169_private *); - } rtl_work[] = { - { RTL_FLAG_TASK_RESET_PENDING, rtl_reset_work }, - }; struct rtl8169_private *tp = container_of(work, struct rtl8169_private, wk.work); - struct net_device *dev = tp->dev; - int i; rtl_lock_work(tp); - if (!netif_running(dev) || + if (!netif_running(tp->dev) || !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags)) goto out_unlock; - for (i = 0; i < ARRAY_SIZE(rtl_work); i++) { - bool pending; - - pending = test_and_clear_bit(rtl_work[i].bitnr, tp->wk.flags); - if (pending) - rtl_work[i].action(tp); - } - + if (test_and_clear_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags)) + rtl_reset_work(tp); out_unlock: rtl_unlock_work(tp); } @@ -4697,17 +4621,6 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) return work_done; } -static void rtl8169_rx_missed(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - - if (tp->mac_version > RTL_GIGA_MAC_VER_06) - return; - - dev->stats.rx_missed_errors += RTL_R32(tp, RxMissed) & 0xffffff; - RTL_W32(tp, RxMissed, 0); -} - static void r8169_phylink_handler(struct net_device *ndev) { struct rtl8169_private *tp = netdev_priv(ndev); @@ -4757,12 +4670,6 @@ static void rtl8169_down(struct net_device *dev) netif_stop_queue(dev); rtl8169_hw_reset(tp); - /* - * At this point device interrupts can not be enabled in any function, - * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task) - * and napi is disabled (rtl8169_poll). - */ - rtl8169_rx_missed(dev); /* Give a racing hard_start_xmit a few cycles to complete. */ synchronize_rcu(); @@ -4907,8 +4814,7 @@ rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) pm_runtime_get_noresume(&pdev->dev); - if (netif_running(dev) && pm_runtime_active(&pdev->dev)) - rtl8169_rx_missed(dev); + netdev_stats_to_stats64(stats, &dev->stats); do { start = u64_stats_fetch_begin_irq(&tp->rx_stats.syncp); @@ -4922,15 +4828,6 @@ rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) stats->tx_bytes = tp->tx_stats.bytes; } while (u64_stats_fetch_retry_irq(&tp->tx_stats.syncp, start)); - stats->rx_dropped = dev->stats.rx_dropped; - stats->tx_dropped = dev->stats.tx_dropped; - stats->rx_length_errors = dev->stats.rx_length_errors; - stats->rx_errors = dev->stats.rx_errors; - stats->rx_crc_errors = dev->stats.rx_crc_errors; - stats->rx_fifo_errors = dev->stats.rx_fifo_errors; - stats->rx_missed_errors = dev->stats.rx_missed_errors; - stats->multicast = dev->stats.multicast; - /* * Fetch additional counter values missing in stats collected by driver * from tally counters. @@ -4948,6 +4845,8 @@ rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) le32_to_cpu(tp->tc_offset.tx_multi_collision); stats->tx_aborted_errors = le16_to_cpu(counters->tx_aborted) - le16_to_cpu(tp->tc_offset.tx_aborted); + stats->rx_missed_errors = le16_to_cpu(counters->rx_missed) - + le16_to_cpu(tp->tc_offset.rx_missed); pm_runtime_put_noidle(&pdev->dev); } @@ -5033,7 +4932,6 @@ static int rtl8169_runtime_suspend(struct device *device) rtl8169_net_suspend(dev); /* Update counters before going runtime suspend */ - rtl8169_rx_missed(dev); rtl8169_update_counters(tp); return 0; @@ -5098,8 +4996,7 @@ static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp) pci_clear_master(tp->pci_dev); RTL_W8(tp, ChipCmd, CmdRxEnb); - /* PCI commit */ - RTL_R8(tp, ChipCmd); + rtl_pci_commit(tp); break; default: break; @@ -5173,7 +5070,7 @@ static const struct net_device_ops rtl_netdev_ops = { static void rtl_set_irq_mask(struct rtl8169_private *tp) { - tp->irq_mask = RTL_EVENT_NAPI | LinkChg; + tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg; if (tp->mac_version <= RTL_GIGA_MAC_VER_06) tp->irq_mask |= SYSErr | RxOverflow | RxFIFOOver; @@ -5449,9 +5346,10 @@ done: static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { struct rtl8169_private *tp; + int jumbo_max, region, rc; + enum mac_version chipset; struct net_device *dev; - int chipset, region; - int jumbo_max, rc; + u16 xid; dev = devm_alloc_etherdev(&pdev->dev, sizeof (*tp)); if (!dev) @@ -5509,10 +5407,16 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->mmio_addr = pcim_iomap_table(pdev)[region]; + xid = (RTL_R32(tp, TxConfig) >> 20) & 0xfcf; + /* Identify chip attached to board */ - rtl8169_get_mac_version(tp); - if (tp->mac_version == RTL_GIGA_MAC_NONE) + chipset = rtl8169_get_mac_version(xid, tp->supports_gmii); + if (chipset == RTL_GIGA_MAC_NONE) { + dev_err(&pdev->dev, "unknown chip XID %03x\n", xid); return -ENODEV; + } + + tp->mac_version = chipset; tp->cp_cmd = RTL_R16(tp, CPlusCmd); @@ -5530,8 +5434,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); - chipset = tp->mac_version; - rc = rtl_alloc_irq(tp); if (rc < 0) { dev_err(&pdev->dev, "Can't allocate interrupt\n"); @@ -5549,9 +5451,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) netif_napi_add(dev, &tp->napi, rtl8169_poll, NAPI_POLL_WEIGHT); - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | - NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX; dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; @@ -5573,7 +5472,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rtl_chip_supports_csum_v2(tp)) { dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; - dev->features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; dev->gso_max_size = RTL_GSO_MAX_SIZE_V2; dev->gso_max_segs = RTL_GSO_MAX_SEGS_V2; } else { @@ -5588,9 +5486,10 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->mac_version == RTL_GIGA_MAC_VER_22) { dev->vlan_features &= ~(NETIF_F_ALL_TSO | NETIF_F_SG); dev->hw_features &= ~(NETIF_F_ALL_TSO | NETIF_F_SG); - dev->features &= ~(NETIF_F_ALL_TSO | NETIF_F_SG); } + dev->features |= dev->hw_features; + dev->hw_features |= NETIF_F_RXALL; dev->hw_features |= NETIF_F_RXFCS; @@ -5622,8 +5521,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_mdio_unregister; netif_info(tp, probe, dev, "%s, %pM, XID %03x, IRQ %d\n", - rtl_chip_infos[chipset].name, dev->dev_addr, - (RTL_R32(tp, TxConfig) >> 20) & 0xfcf, + rtl_chip_infos[chipset].name, dev->dev_addr, xid, pci_irq_vector(pdev, 0)); if (jumbo_max) |