]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'trivial/for-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Mon, 2 Apr 2012 02:03:00 +0000 (12:03 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Mon, 2 Apr 2012 02:03:00 +0000 (12:03 +1000)
Conflicts:
drivers/net/ethernet/realtek/r8169.c

1  2 
MAINTAINERS
drivers/net/ethernet/realtek/r8169.c
sound/pci/hda/patch_realtek.c

diff --cc MAINTAINERS
Simple merge
index 7b23554f80b6c0f8540bccddea0c9ae31c75f35e,7f06508df9ff2bc24939536c577916db3345338c..d2ec075487379018eff32e4d1e7e7d4f567865c1
@@@ -5529,768 -5390,823 +5529,768 @@@ static void rtl_task(struct work_struc
        struct net_device *dev = tp->dev;
        int i;
  
 -      rtnl_lock();
 +      rtl_lock_work(tp);
  
 -      if (!netif_running(dev))
 +      if (!netif_running(dev) ||
 +          !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
                goto out_unlock;
  
 -      rtl8169_hw_reset(tp);
 -
 -      rtl8169_wait_for_quiescence(dev);
 -
 -      for (i = 0; i < NUM_RX_DESC; i++)
 -              rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz);
 -
 -      rtl8169_tx_clear(tp);
 -      rtl8169_init_ring_indexes(tp);
 +      for (i = 0; i < ARRAY_SIZE(rtl_work); i++) {
 +              bool pending;
  
 -      rtl_hw_start(dev);
 -      netif_wake_queue(dev);
 -      rtl8169_check_link_status(dev, tp, tp->mmio_addr);
 +              pending = test_and_clear_bit(rtl_work[i].bitnr, tp->wk.flags);
 +              if (pending)
 +                      rtl_work[i].action(tp);
 +      }
  
  out_unlock:
 -      rtnl_unlock();
 -}
 -
 -static void rtl8169_tx_timeout(struct net_device *dev)
 -{
 -      rtl8169_schedule_work(dev, rtl8169_reset_task);
 +      rtl_unlock_work(tp);
  }
  
 -static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
 -                            u32 *opts)
 +static int rtl8169_poll(struct napi_struct *napi, int budget)
  {
 -      struct skb_shared_info *info = skb_shinfo(skb);
 -      unsigned int cur_frag, entry;
 -      struct TxDesc * uninitialized_var(txd);
 -      struct device *d = &tp->pci_dev->dev;
 -
 -      entry = tp->cur_tx;
 -      for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) {
 -              const skb_frag_t *frag = info->frags + cur_frag;
 -              dma_addr_t mapping;
 -              u32 status, len;
 -              void *addr;
 +      struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi);
 +      struct net_device *dev = tp->dev;
 +      u16 enable_mask = RTL_EVENT_NAPI | tp->event_slow;
 +      int work_done= 0;
 +      u16 status;
  
 -              entry = (entry + 1) % NUM_TX_DESC;
 +      status = rtl_get_events(tp);
 +      rtl_ack_events(tp, status & ~tp->event_slow);
  
 -              txd = tp->TxDescArray + entry;
 -              len = skb_frag_size(frag);
 -              addr = skb_frag_address(frag);
 -              mapping = dma_map_single(d, addr, len, DMA_TO_DEVICE);
 -              if (unlikely(dma_mapping_error(d, mapping))) {
 -                      if (net_ratelimit())
 -                              netif_err(tp, drv, tp->dev,
 -                                        "Failed to map TX fragments DMA!\n");
 -                      goto err_out;
 -              }
 +      if (status & RTL_EVENT_NAPI_RX)
 +              work_done = rtl_rx(dev, tp, (u32) budget);
  
 -              /* Anti gcc 2.95.3 bugware (sic) */
 -              status = opts[0] | len |
 -                      (RingEnd * !((entry + 1) % NUM_TX_DESC));
 +      if (status & RTL_EVENT_NAPI_TX)
 +              rtl_tx(dev, tp);
  
 -              txd->opts1 = cpu_to_le32(status);
 -              txd->opts2 = cpu_to_le32(opts[1]);
 -              txd->addr = cpu_to_le64(mapping);
 +      if (status & tp->event_slow) {
 +              enable_mask &= ~tp->event_slow;
  
 -              tp->tx_skb[entry].len = len;
 +              rtl_schedule_task(tp, RTL_FLAG_TASK_SLOW_PENDING);
        }
  
 -      if (cur_frag) {
 -              tp->tx_skb[entry].skb = skb;
 -              txd->opts1 |= cpu_to_le32(LastFrag);
 -      }
 +      if (work_done < budget) {
 +              napi_complete(napi);
  
 -      return cur_frag;
 +              rtl_irq_enable(tp, enable_mask);
 +              mmiowb();
 +      }
  
 -err_out:
 -      rtl8169_tx_clear_range(tp, tp->cur_tx + 1, cur_frag);
 -      return -EIO;
 +      return work_done;
  }
  
 -static inline void rtl8169_tso_csum(struct rtl8169_private *tp,
 -                                  struct sk_buff *skb, u32 *opts)
 +static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr)
  {
 -      const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version;
 -      u32 mss = skb_shinfo(skb)->gso_size;
 -      int offset = info->opts_offset;
 +      struct rtl8169_private *tp = netdev_priv(dev);
  
 -      if (mss) {
 -              opts[0] |= TD_LSO;
 -              opts[offset] |= min(mss, TD_MSS_MAX) << info->mss_shift;
 -      } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 -              const struct iphdr *ip = ip_hdr(skb);
 +      if (tp->mac_version > RTL_GIGA_MAC_VER_06)
 +              return;
  
 -              if (ip->protocol == IPPROTO_TCP)
 -                      opts[offset] |= info->checksum.tcp;
 -              else if (ip->protocol == IPPROTO_UDP)
 -                      opts[offset] |= info->checksum.udp;
 -              else
 -                      WARN_ON_ONCE(1);
 -      }
 +      dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff);
 +      RTL_W32(RxMissed, 0);
  }
  
 -static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
 -                                    struct net_device *dev)
 +static void rtl8169_down(struct net_device *dev)
  {
        struct rtl8169_private *tp = netdev_priv(dev);
 -      unsigned int entry = tp->cur_tx % NUM_TX_DESC;
 -      struct TxDesc *txd = tp->TxDescArray + entry;
        void __iomem *ioaddr = tp->mmio_addr;
 -      struct device *d = &tp->pci_dev->dev;
 -      dma_addr_t mapping;
 -      u32 status, len;
 -      u32 opts[2];
 -      int frags;
  
 -      if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
 -              netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n");
 -              goto err_stop_0;
 -      }
 +      del_timer_sync(&tp->timer);
  
 -      if (unlikely(le32_to_cpu(txd->opts1) & DescOwn))
 -              goto err_stop_0;
 +      napi_disable(&tp->napi);
 +      netif_stop_queue(dev);
  
 -      len = skb_headlen(skb);
 -      mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE);
 -      if (unlikely(dma_mapping_error(d, mapping))) {
 -              if (net_ratelimit())
 -                      netif_err(tp, drv, dev, "Failed to map TX DMA!\n");
 -              goto err_dma_0;
 -      }
 +      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, ioaddr);
  
 -      tp->tx_skb[entry].len = len;
 -      txd->addr = cpu_to_le64(mapping);
 +      /* Give a racing hard_start_xmit a few cycles to complete. */
 +      synchronize_sched();
  
 -      opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb));
 -      opts[0] = DescOwn;
 +      rtl8169_tx_clear(tp);
  
 -      rtl8169_tso_csum(tp, skb, opts);
 +      rtl8169_rx_clear(tp);
  
 -      frags = rtl8169_xmit_frags(tp, skb, opts);
 -      if (frags < 0)
 -              goto err_dma_1;
 -      else if (frags)
 -              opts[0] |= FirstFrag;
 -      else {
 -              opts[0] |= FirstFrag | LastFrag;
 -              tp->tx_skb[entry].skb = skb;
 -      }
 +      rtl_pll_power_down(tp);
 +}
  
 -      txd->opts2 = cpu_to_le32(opts[1]);
 +static int rtl8169_close(struct net_device *dev)
 +{
 +      struct rtl8169_private *tp = netdev_priv(dev);
 +      struct pci_dev *pdev = tp->pci_dev;
  
 -      wmb();
 +      pm_runtime_get_sync(&pdev->dev);
  
 -      /* Anti gcc 2.95.3 bugware (sic) */
 -      status = opts[0] | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
 -      txd->opts1 = cpu_to_le32(status);
 +      /* Update counters before going down */
 +      rtl8169_update_counters(dev);
  
 -      tp->cur_tx += frags + 1;
 +      rtl_lock_work(tp);
 +      clear_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
  
 -      wmb();
 +      rtl8169_down(dev);
 +      rtl_unlock_work(tp);
  
 -      RTL_W8(TxPoll, NPQ);
 +      free_irq(pdev->irq, dev);
  
 -      if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
 -              netif_stop_queue(dev);
 -              smp_rmb();
 -              if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)
 -                      netif_wake_queue(dev);
 -      }
 +      dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
 +                        tp->RxPhyAddr);
 +      dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray,
 +                        tp->TxPhyAddr);
 +      tp->TxDescArray = NULL;
 +      tp->RxDescArray = NULL;
  
 -      return NETDEV_TX_OK;
 +      pm_runtime_put_sync(&pdev->dev);
  
 -err_dma_1:
 -      rtl8169_unmap_tx_skb(d, tp->tx_skb + entry, txd);
 -err_dma_0:
 -      dev_kfree_skb(skb);
 -      dev->stats.tx_dropped++;
 -      return NETDEV_TX_OK;
 +      return 0;
 +}
  
 -err_stop_0:
 -      netif_stop_queue(dev);
 -      dev->stats.tx_dropped++;
 -      return NETDEV_TX_BUSY;
 +#ifdef CONFIG_NET_POLL_CONTROLLER
 +static void rtl8169_netpoll(struct net_device *dev)
 +{
 +      struct rtl8169_private *tp = netdev_priv(dev);
 +
 +      rtl8169_interrupt(tp->pci_dev->irq, dev);
  }
 +#endif
  
 -static void rtl8169_pcierr_interrupt(struct net_device *dev)
 +static int rtl_open(struct net_device *dev)
  {
        struct rtl8169_private *tp = netdev_priv(dev);
 +      void __iomem *ioaddr = tp->mmio_addr;
        struct pci_dev *pdev = tp->pci_dev;
 -      u16 pci_status, pci_cmd;
 -
 -      pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
 -      pci_read_config_word(pdev, PCI_STATUS, &pci_status);
 +      int retval = -ENOMEM;
  
 -      netif_err(tp, intr, dev, "PCI error (cmd = 0x%04x, status = 0x%04x)\n",
 -                pci_cmd, pci_status);
 +      pm_runtime_get_sync(&pdev->dev);
  
        /*
-        * Rx and Tx desscriptors needs 256 bytes alignment.
 -       * The recovery sequence below admits a very elaborated explanation:
 -       * - it seems to work;
 -       * - I did not see what else could be done;
 -       * - it makes iop3xx happy.
 -       *
 -       * Feel free to adjust to your needs.
++       * Rx and Tx desscriptors need 256 bytes alignment.
 +       * dma_alloc_coherent provides more.
         */
 -      if (pdev->broken_parity_status)
 -              pci_cmd &= ~PCI_COMMAND_PARITY;
 -      else
 -              pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY;
 +      tp->TxDescArray = dma_alloc_coherent(&pdev->dev, R8169_TX_RING_BYTES,
 +                                           &tp->TxPhyAddr, GFP_KERNEL);
 +      if (!tp->TxDescArray)
 +              goto err_pm_runtime_put;
  
 -      pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
 +      tp->RxDescArray = dma_alloc_coherent(&pdev->dev, R8169_RX_RING_BYTES,
 +                                           &tp->RxPhyAddr, GFP_KERNEL);
 +      if (!tp->RxDescArray)
 +              goto err_free_tx_0;
  
 -      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));
 +      retval = rtl8169_init_ring(dev);
 +      if (retval < 0)
 +              goto err_free_rx_1;
  
 -      /* The infamous DAC f*ckup only happens at boot time */
 -      if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) {
 -              void __iomem *ioaddr = tp->mmio_addr;
 +      INIT_WORK(&tp->wk.work, rtl_task);
  
 -              netif_info(tp, intr, dev, "disabling PCI DAC\n");
 -              tp->cp_cmd &= ~PCIDAC;
 -              RTL_W16(CPlusCmd, tp->cp_cmd);
 -              dev->features &= ~NETIF_F_HIGHDMA;
 -      }
 +      smp_mb();
  
 -      rtl8169_hw_reset(tp);
 +      rtl_request_firmware(tp);
  
 -      rtl8169_schedule_work(dev, rtl8169_reinit_task);
 -}
 +      retval = request_irq(pdev->irq, rtl8169_interrupt,
 +                           (tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED,
 +                           dev->name, dev);
 +      if (retval < 0)
 +              goto err_release_fw_2;
  
 -static void rtl8169_tx_interrupt(struct net_device *dev,
 -                               struct rtl8169_private *tp,
 -                               void __iomem *ioaddr)
 -{
 -      unsigned int dirty_tx, tx_left;
 +      rtl_lock_work(tp);
  
 -      dirty_tx = tp->dirty_tx;
 -      smp_rmb();
 -      tx_left = tp->cur_tx - dirty_tx;
 +      set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
  
 -      while (tx_left > 0) {
 -              unsigned int entry = dirty_tx % NUM_TX_DESC;
 -              struct ring_info *tx_skb = tp->tx_skb + entry;
 -              u32 status;
 +      napi_enable(&tp->napi);
  
 -              rmb();
 -              status = le32_to_cpu(tp->TxDescArray[entry].opts1);
 -              if (status & DescOwn)
 -                      break;
 +      rtl8169_init_phy(dev, tp);
  
 -              rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
 -                                   tp->TxDescArray + entry);
 -              if (status & LastFrag) {
 -                      dev->stats.tx_packets++;
 -                      dev->stats.tx_bytes += tx_skb->skb->len;
 -                      dev_kfree_skb(tx_skb->skb);
 -                      tx_skb->skb = NULL;
 -              }
 -              dirty_tx++;
 -              tx_left--;
 -      }
 +      __rtl8169_set_features(dev, dev->features);
  
 -      if (tp->dirty_tx != dirty_tx) {
 -              tp->dirty_tx = dirty_tx;
 -              smp_wmb();
 -              if (netif_queue_stopped(dev) &&
 -                  (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) {
 -                      netif_wake_queue(dev);
 -              }
 -              /*
 -               * 8168 hack: TxPoll requests are lost when the Tx packets are
 -               * too close. Let's kick an extra TxPoll request when a burst
 -               * of start_xmit activity is detected (if it is not detected,
 -               * it is slow enough). -- FR
 -               */
 -              smp_rmb();
 -              if (tp->cur_tx != dirty_tx)
 -                      RTL_W8(TxPoll, NPQ);
 -      }
 -}
 +      rtl_pll_power_up(tp);
  
 -static inline int rtl8169_fragmented_frame(u32 status)
 -{
 -      return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag);
 -}
 +      rtl_hw_start(dev);
  
 -static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1)
 -{
 -      u32 status = opts1 & RxProtoMask;
 +      netif_start_queue(dev);
  
 -      if (((status == RxProtoTCP) && !(opts1 & TCPFail)) ||
 -          ((status == RxProtoUDP) && !(opts1 & UDPFail)))
 -              skb->ip_summed = CHECKSUM_UNNECESSARY;
 -      else
 -              skb_checksum_none_assert(skb);
 -}
 +      rtl_unlock_work(tp);
  
 -static struct sk_buff *rtl8169_try_rx_copy(void *data,
 -                                         struct rtl8169_private *tp,
 -                                         int pkt_size,
 -                                         dma_addr_t addr)
 -{
 -      struct sk_buff *skb;
 -      struct device *d = &tp->pci_dev->dev;
 +      tp->saved_wolopts = 0;
 +      pm_runtime_put_noidle(&pdev->dev);
  
 -      data = rtl8169_align(data);
 -      dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE);
 -      prefetch(data);
 -      skb = netdev_alloc_skb_ip_align(tp->dev, pkt_size);
 -      if (skb)
 -              memcpy(skb->data, data, pkt_size);
 -      dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
 +      rtl8169_check_link_status(dev, tp, ioaddr);
 +out:
 +      return retval;
  
 -      return skb;
 +err_release_fw_2:
 +      rtl_release_firmware(tp);
 +      rtl8169_rx_clear(tp);
 +err_free_rx_1:
 +      dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
 +                        tp->RxPhyAddr);
 +      tp->RxDescArray = NULL;
 +err_free_tx_0:
 +      dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray,
 +                        tp->TxPhyAddr);
 +      tp->TxDescArray = NULL;
 +err_pm_runtime_put:
 +      pm_runtime_put_noidle(&pdev->dev);
 +      goto out;
  }
  
 -static int rtl8169_rx_interrupt(struct net_device *dev,
 -                              struct rtl8169_private *tp,
 -                              void __iomem *ioaddr, u32 budget)
 +static struct rtnl_link_stats64 *
 +rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
  {
 -      unsigned int cur_rx, rx_left;
 -      unsigned int count;
 +      struct rtl8169_private *tp = netdev_priv(dev);
 +      void __iomem *ioaddr = tp->mmio_addr;
 +      unsigned int start;
  
 -      cur_rx = tp->cur_rx;
 -      rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
 -      rx_left = min(rx_left, budget);
 +      if (netif_running(dev))
 +              rtl8169_rx_missed(dev, ioaddr);
  
 -      for (; rx_left > 0; rx_left--, cur_rx++) {
 -              unsigned int entry = cur_rx % NUM_RX_DESC;
 -              struct RxDesc *desc = tp->RxDescArray + entry;
 -              u32 status;
 +      do {
 +              start = u64_stats_fetch_begin_bh(&tp->rx_stats.syncp);
 +              stats->rx_packets = tp->rx_stats.packets;
 +              stats->rx_bytes = tp->rx_stats.bytes;
 +      } while (u64_stats_fetch_retry_bh(&tp->rx_stats.syncp, start));
  
 -              rmb();
 -              status = le32_to_cpu(desc->opts1) & tp->opts1_mask;
  
 -              if (status & DescOwn)
 -                      break;
 -              if (unlikely(status & RxRES)) {
 -                      netif_info(tp, rx_err, dev, "Rx ERROR. status = %08x\n",
 -                                 status);
 -                      dev->stats.rx_errors++;
 -                      if (status & (RxRWT | RxRUNT))
 -                              dev->stats.rx_length_errors++;
 -                      if (status & RxCRC)
 -                              dev->stats.rx_crc_errors++;
 -                      if (status & RxFOVF) {
 -                              rtl8169_schedule_work(dev, rtl8169_reset_task);
 -                              dev->stats.rx_fifo_errors++;
 -                      }
 -                      rtl8169_mark_to_asic(desc, rx_buf_sz);
 -              } else {
 -                      struct sk_buff *skb;
 -                      dma_addr_t addr = le64_to_cpu(desc->addr);
 -                      int pkt_size = (status & 0x00003fff) - 4;
 +      do {
 +              start = u64_stats_fetch_begin_bh(&tp->tx_stats.syncp);
 +              stats->tx_packets = tp->tx_stats.packets;
 +              stats->tx_bytes = tp->tx_stats.bytes;
 +      } while (u64_stats_fetch_retry_bh(&tp->tx_stats.syncp, start));
  
 -                      /*
 -                       * The driver does not support incoming fragmented
 -                       * frames. They are seen as a symptom of over-mtu
 -                       * sized frames.
 -                       */
 -                      if (unlikely(rtl8169_fragmented_frame(status))) {
 -                              dev->stats.rx_dropped++;
 -                              dev->stats.rx_length_errors++;
 -                              rtl8169_mark_to_asic(desc, rx_buf_sz);
 -                              continue;
 -                      }
 +      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;
  
 -                      skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry],
 -                                                tp, pkt_size, addr);
 -                      rtl8169_mark_to_asic(desc, rx_buf_sz);
 -                      if (!skb) {
 -                              dev->stats.rx_dropped++;
 -                              continue;
 -                      }
 +      return stats;
 +}
  
 -                      rtl8169_rx_csum(skb, status);
 -                      skb_put(skb, pkt_size);
 -                      skb->protocol = eth_type_trans(skb, dev);
 +static void rtl8169_net_suspend(struct net_device *dev)
 +{
 +      struct rtl8169_private *tp = netdev_priv(dev);
  
 -                      rtl8169_rx_vlan_tag(desc, skb);
 +      if (!netif_running(dev))
 +              return;
  
 -                      napi_gro_receive(&tp->napi, skb);
 +      netif_device_detach(dev);
 +      netif_stop_queue(dev);
  
 -                      dev->stats.rx_bytes += pkt_size;
 -                      dev->stats.rx_packets++;
 -              }
 +      rtl_lock_work(tp);
 +      napi_disable(&tp->napi);
 +      clear_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
 +      rtl_unlock_work(tp);
  
 -              /* Work around for AMD plateform. */
 -              if ((desc->opts2 & cpu_to_le32(0xfffe000)) &&
 -                  (tp->mac_version == RTL_GIGA_MAC_VER_05)) {
 -                      desc->opts2 = 0;
 -                      cur_rx++;
 -              }
 -      }
 +      rtl_pll_power_down(tp);
 +}
  
 -      count = cur_rx - tp->cur_rx;
 -      tp->cur_rx = cur_rx;
 +#ifdef CONFIG_PM
  
 -      tp->dirty_rx += count;
 +static int rtl8169_suspend(struct device *device)
 +{
 +      struct pci_dev *pdev = to_pci_dev(device);
 +      struct net_device *dev = pci_get_drvdata(pdev);
  
 -      return count;
 +      rtl8169_net_suspend(dev);
 +
 +      return 0;
  }
  
 -static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
 +static void __rtl8169_resume(struct net_device *dev)
  {
 -      struct net_device *dev = dev_instance;
        struct rtl8169_private *tp = netdev_priv(dev);
 -      void __iomem *ioaddr = tp->mmio_addr;
 -      int handled = 0;
 -      int status;
  
 -      /* loop handling interrupts until we have no new ones or
 -       * we hit a invalid/hotplug case.
 -       */
 -      status = RTL_R16(IntrStatus);
 -      while (status && status != 0xffff) {
 -              status &= tp->intr_event;
 -              if (!status)
 -                      break;
 -
 -              handled = 1;
 +      netif_device_attach(dev);
  
 -              /* Handle all of the error cases first. These will reset
 -               * the chip, so just exit the loop.
 -               */
 -              if (unlikely(!netif_running(dev))) {
 -                      rtl8169_hw_reset(tp);
 -                      break;
 -              }
 +      rtl_pll_power_up(tp);
  
 -              if (unlikely(status & RxFIFOOver)) {
 -                      switch (tp->mac_version) {
 -                      /* Work around for rx fifo overflow */
 -                      case RTL_GIGA_MAC_VER_11:
 -                              netif_stop_queue(dev);
 -                              rtl8169_tx_timeout(dev);
 -                              goto done;
 -                      default:
 -                              break;
 -                      }
 -              }
 +      set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
  
 -              if (unlikely(status & SYSErr)) {
 -                      rtl8169_pcierr_interrupt(dev);
 -                      break;
 -              }
 +      rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
 +}
  
 -              if (status & LinkChg)
 -                      __rtl8169_check_link_status(dev, tp, ioaddr, true);
 +static int rtl8169_resume(struct device *device)
 +{
 +      struct pci_dev *pdev = to_pci_dev(device);
 +      struct net_device *dev = pci_get_drvdata(pdev);
 +      struct rtl8169_private *tp = netdev_priv(dev);
  
 -              /* We need to see the lastest version of tp->intr_mask to
 -               * avoid ignoring an MSI interrupt and having to wait for
 -               * another event which may never come.
 -               */
 -              smp_rmb();
 -              if (status & tp->intr_mask & tp->napi_event) {
 -                      RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
 -                      tp->intr_mask = ~tp->napi_event;
 +      rtl8169_init_phy(dev, tp);
  
 -                      if (likely(napi_schedule_prep(&tp->napi)))
 -                              __napi_schedule(&tp->napi);
 -                      else
 -                              netif_info(tp, intr, dev,
 -                                         "interrupt %04x in poll\n", status);
 -              }
 +      if (netif_running(dev))
 +              __rtl8169_resume(dev);
  
 -              /* We only get a new MSI interrupt when all active irq
 -               * sources on the chip have been acknowledged. So, ack
 -               * everything we've seen and check if new sources have become
 -               * active to avoid blocking all interrupts from the chip.
 -               */
 -              RTL_W16(IntrStatus,
 -                      (status & RxFIFOOver) ? (status | RxOverflow) : status);
 -              status = RTL_R16(IntrStatus);
 -      }
 -done:
 -      return IRQ_RETVAL(handled);
 +      return 0;
  }
  
 -static int rtl8169_poll(struct napi_struct *napi, int budget)
 +static int rtl8169_runtime_suspend(struct device *device)
  {
 -      struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi);
 -      struct net_device *dev = tp->dev;
 -      void __iomem *ioaddr = tp->mmio_addr;
 -      int work_done;
 +      struct pci_dev *pdev = to_pci_dev(device);
 +      struct net_device *dev = pci_get_drvdata(pdev);
 +      struct rtl8169_private *tp = netdev_priv(dev);
  
 -      work_done = rtl8169_rx_interrupt(dev, tp, ioaddr, (u32) budget);
 -      rtl8169_tx_interrupt(dev, tp, ioaddr);
 +      if (!tp->TxDescArray)
 +              return 0;
  
 -      if (work_done < budget) {
 -              napi_complete(napi);
 +      rtl_lock_work(tp);
 +      tp->saved_wolopts = __rtl8169_get_wol(tp);
 +      __rtl8169_set_wol(tp, WAKE_ANY);
 +      rtl_unlock_work(tp);
  
 -              /* We need for force the visibility of tp->intr_mask
 -               * for other CPUs, as we can loose an MSI interrupt
 -               * and potentially wait for a retransmit timeout if we don't.
 -               * The posted write to IntrMask is safe, as it will
 -               * eventually make it to the chip and we won't loose anything
 -               * until it does.
 -               */
 -              tp->intr_mask = 0xffff;
 -              wmb();
 -              RTL_W16(IntrMask, tp->intr_event);
 -      }
 +      rtl8169_net_suspend(dev);
  
 -      return work_done;
 +      return 0;
  }
  
 -static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr)
 +static int rtl8169_runtime_resume(struct device *device)
  {
 +      struct pci_dev *pdev = to_pci_dev(device);
 +      struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
  
 -      if (tp->mac_version > RTL_GIGA_MAC_VER_06)
 -              return;
 +      if (!tp->TxDescArray)
 +              return 0;
  
 -      dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff);
 -      RTL_W32(RxMissed, 0);
 +      rtl_lock_work(tp);
 +      __rtl8169_set_wol(tp, tp->saved_wolopts);
 +      tp->saved_wolopts = 0;
 +      rtl_unlock_work(tp);
 +
 +      rtl8169_init_phy(dev, tp);
 +
 +      __rtl8169_resume(dev);
 +
 +      return 0;
  }
  
 -static void rtl8169_down(struct net_device *dev)
 +static int rtl8169_runtime_idle(struct device *device)
  {
 +      struct pci_dev *pdev = to_pci_dev(device);
 +      struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
 -      void __iomem *ioaddr = tp->mmio_addr;
 -
 -      del_timer_sync(&tp->timer);
  
 -      netif_stop_queue(dev);
 -
 -      napi_disable(&tp->napi);
 +      return tp->TxDescArray ? -EBUSY : 0;
 +}
  
 -      spin_lock_irq(&tp->lock);
 +static const struct dev_pm_ops rtl8169_pm_ops = {
 +      .suspend                = rtl8169_suspend,
 +      .resume                 = rtl8169_resume,
 +      .freeze                 = rtl8169_suspend,
 +      .thaw                   = rtl8169_resume,
 +      .poweroff               = rtl8169_suspend,
 +      .restore                = rtl8169_resume,
 +      .runtime_suspend        = rtl8169_runtime_suspend,
 +      .runtime_resume         = rtl8169_runtime_resume,
 +      .runtime_idle           = rtl8169_runtime_idle,
 +};
  
 -      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,
 -       * rtl8169_reinit_task) and napi is disabled (rtl8169_poll).
 -       */
 -      rtl8169_rx_missed(dev, ioaddr);
 +#define RTL8169_PM_OPS        (&rtl8169_pm_ops)
  
 -      spin_unlock_irq(&tp->lock);
 +#else /* !CONFIG_PM */
  
 -      synchronize_irq(dev->irq);
 +#define RTL8169_PM_OPS        NULL
  
 -      /* Give a racing hard_start_xmit a few cycles to complete. */
 -      synchronize_sched();  /* FIXME: should this be synchronize_irq()? */
 +#endif /* !CONFIG_PM */
  
 -      rtl8169_tx_clear(tp);
 +static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp)
 +{
 +      void __iomem *ioaddr = tp->mmio_addr;
  
 -      rtl8169_rx_clear(tp);
 +      /* WoL fails with 8168b when the receiver is disabled. */
 +      switch (tp->mac_version) {
 +      case RTL_GIGA_MAC_VER_11:
 +      case RTL_GIGA_MAC_VER_12:
 +      case RTL_GIGA_MAC_VER_17:
 +              pci_clear_master(tp->pci_dev);
  
 -      rtl_pll_power_down(tp);
 +              RTL_W8(ChipCmd, CmdRxEnb);
 +              /* PCI commit */
 +              RTL_R8(ChipCmd);
 +              break;
 +      default:
 +              break;
 +      }
  }
  
 -static int rtl8169_close(struct net_device *dev)
 +static void rtl_shutdown(struct pci_dev *pdev)
  {
 +      struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
 -      struct pci_dev *pdev = tp->pci_dev;
 +      struct device *d = &pdev->dev;
  
 -      pm_runtime_get_sync(&pdev->dev);
 +      pm_runtime_get_sync(d);
  
 -      /* Update counters before going down */
 -      rtl8169_update_counters(dev);
 +      rtl8169_net_suspend(dev);
  
 -      rtl8169_down(dev);
 +      /* Restore original MAC address */
 +      rtl_rar_set(tp, dev->perm_addr);
  
 -      free_irq(dev->irq, dev);
 +      rtl8169_hw_reset(tp);
  
 -      dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray,
 -                        tp->RxPhyAddr);
 -      dma_free_coherent(&pdev->dev, R8169_TX_RING_BYTES, tp->TxDescArray,
 -                        tp->TxPhyAddr);
 -      tp->TxDescArray = NULL;
 -      tp->RxDescArray = NULL;
 +      if (system_state == SYSTEM_POWER_OFF) {
 +              if (__rtl8169_get_wol(tp) & WAKE_ANY) {
 +                      rtl_wol_suspend_quirk(tp);
 +                      rtl_wol_shutdown_quirk(tp);
 +              }
  
 -      pm_runtime_put_sync(&pdev->dev);
 +              pci_wake_from_d3(pdev, true);
 +              pci_set_power_state(pdev, PCI_D3hot);
 +      }
  
 -      return 0;
 +      pm_runtime_put_noidle(d);
  }
  
 -static void rtl_set_rx_mode(struct net_device *dev)
 +static void __devexit rtl_remove_one(struct pci_dev *pdev)
  {
 +      struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
 -      void __iomem *ioaddr = tp->mmio_addr;
 -      unsigned long flags;
 -      u32 mc_filter[2];       /* Multicast hash filter */
 -      int rx_mode;
 -      u32 tmp = 0;
 -
 -      if (dev->flags & IFF_PROMISC) {
 -              /* Unconditionally log net taps. */
 -              netif_notice(tp, link, dev, "Promiscuous mode enabled\n");
 -              rx_mode =
 -                  AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
 -                  AcceptAllPhys;
 -              mc_filter[1] = mc_filter[0] = 0xffffffff;
 -      } else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
 -                 (dev->flags & IFF_ALLMULTI)) {
 -              /* Too many to filter perfectly -- accept all multicasts. */
 -              rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 -              mc_filter[1] = mc_filter[0] = 0xffffffff;
 -      } else {
 -              struct netdev_hw_addr *ha;
  
 -              rx_mode = AcceptBroadcast | AcceptMyPhys;
 -              mc_filter[1] = mc_filter[0] = 0;
 -              netdev_for_each_mc_addr(ha, dev) {
 -                      int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
 -                      mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
 -                      rx_mode |= AcceptMulticast;
 -              }
 +      if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
 +          tp->mac_version == RTL_GIGA_MAC_VER_28 ||
 +          tp->mac_version == RTL_GIGA_MAC_VER_31) {
 +              rtl8168_driver_stop(tp);
        }
  
 -      spin_lock_irqsave(&tp->lock, flags);
 -
 -      tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode;
 +      cancel_work_sync(&tp->wk.work);
  
 -      if (tp->mac_version > RTL_GIGA_MAC_VER_06) {
 -              u32 data = mc_filter[0];
 +      unregister_netdev(dev);
  
 -              mc_filter[0] = swab32(mc_filter[1]);
 -              mc_filter[1] = swab32(data);
 -      }
 +      rtl_release_firmware(tp);
  
 -      RTL_W32(MAR0 + 4, mc_filter[1]);
 -      RTL_W32(MAR0 + 0, mc_filter[0]);
 +      if (pci_dev_run_wake(pdev))
 +              pm_runtime_get_noresume(&pdev->dev);
  
 -      RTL_W32(RxConfig, tmp);
 +      /* restore original MAC address */
 +      rtl_rar_set(tp, dev->perm_addr);
  
 -      spin_unlock_irqrestore(&tp->lock, flags);
 +      rtl_disable_msi(pdev, tp);
 +      rtl8169_release_board(pdev, dev, tp->mmio_addr);
 +      pci_set_drvdata(pdev, NULL);
  }
  
 -/**
 - *  rtl8169_get_stats - Get rtl8169 read/write statistics
 - *  @dev: The Ethernet Device to get statistics for
 - *
 - *  Get TX/RX statistics for rtl8169
 - */
 -static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
 +static const struct net_device_ops rtl_netdev_ops = {
 +      .ndo_open               = rtl_open,
 +      .ndo_stop               = rtl8169_close,
 +      .ndo_get_stats64        = rtl8169_get_stats64,
 +      .ndo_start_xmit         = rtl8169_start_xmit,
 +      .ndo_tx_timeout         = rtl8169_tx_timeout,
 +      .ndo_validate_addr      = eth_validate_addr,
 +      .ndo_change_mtu         = rtl8169_change_mtu,
 +      .ndo_fix_features       = rtl8169_fix_features,
 +      .ndo_set_features       = rtl8169_set_features,
 +      .ndo_set_mac_address    = rtl_set_mac_address,
 +      .ndo_do_ioctl           = rtl8169_ioctl,
 +      .ndo_set_rx_mode        = rtl_set_rx_mode,
 +#ifdef CONFIG_NET_POLL_CONTROLLER
 +      .ndo_poll_controller    = rtl8169_netpoll,
 +#endif
 +
 +};
 +
 +static const struct rtl_cfg_info {
 +      void (*hw_start)(struct net_device *);
 +      unsigned int region;
 +      unsigned int align;
 +      u16 event_slow;
 +      unsigned features;
 +      u8 default_ver;
 +} rtl_cfg_infos [] = {
 +      [RTL_CFG_0] = {
 +              .hw_start       = rtl_hw_start_8169,
 +              .region         = 1,
 +              .align          = 0,
 +              .event_slow     = SYSErr | LinkChg | RxOverflow | RxFIFOOver,
 +              .features       = RTL_FEATURE_GMII,
 +              .default_ver    = RTL_GIGA_MAC_VER_01,
 +      },
 +      [RTL_CFG_1] = {
 +              .hw_start       = rtl_hw_start_8168,
 +              .region         = 2,
 +              .align          = 8,
 +              .event_slow     = SYSErr | LinkChg | RxOverflow,
 +              .features       = RTL_FEATURE_GMII | RTL_FEATURE_MSI,
 +              .default_ver    = RTL_GIGA_MAC_VER_11,
 +      },
 +      [RTL_CFG_2] = {
 +              .hw_start       = rtl_hw_start_8101,
 +              .region         = 2,
 +              .align          = 8,
 +              .event_slow     = SYSErr | LinkChg | RxOverflow | RxFIFOOver |
 +                                PCSTimeout,
 +              .features       = RTL_FEATURE_MSI,
 +              .default_ver    = RTL_GIGA_MAC_VER_13,
 +      }
 +};
 +
 +/* Cfg9346_Unlock assumed. */
 +static unsigned rtl_try_msi(struct rtl8169_private *tp,
 +                          const struct rtl_cfg_info *cfg)
  {
 -      struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
 -      unsigned long flags;
 +      unsigned msi = 0;
 +      u8 cfg2;
  
 -      if (netif_running(dev)) {
 -              spin_lock_irqsave(&tp->lock, flags);
 -              rtl8169_rx_missed(dev, ioaddr);
 -              spin_unlock_irqrestore(&tp->lock, flags);
 +      cfg2 = RTL_R8(Config2) & ~MSIEnable;
 +      if (cfg->features & RTL_FEATURE_MSI) {
 +              if (pci_enable_msi(tp->pci_dev)) {
 +                      netif_info(tp, hw, tp->dev, "no MSI. Back to INTx.\n");
 +              } else {
 +                      cfg2 |= MSIEnable;
 +                      msi = RTL_FEATURE_MSI;
 +              }
        }
 -
 -      return &dev->stats;
 +      if (tp->mac_version <= RTL_GIGA_MAC_VER_06)
 +              RTL_W8(Config2, cfg2);
 +      return msi;
  }
  
 -static void rtl8169_net_suspend(struct net_device *dev)
 +static int __devinit
 +rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
  {
 -      struct rtl8169_private *tp = netdev_priv(dev);
 +      const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
 +      const unsigned int region = cfg->region;
 +      struct rtl8169_private *tp;
 +      struct mii_if_info *mii;
 +      struct net_device *dev;
 +      void __iomem *ioaddr;
 +      int chipset, i;
 +      int rc;
  
 -      if (!netif_running(dev))
 -              return;
 +      if (netif_msg_drv(&debug)) {
 +              printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
 +                     MODULENAME, RTL8169_VERSION);
 +      }
  
 -      rtl_pll_power_down(tp);
 +      dev = alloc_etherdev(sizeof (*tp));
 +      if (!dev) {
 +              rc = -ENOMEM;
 +              goto out;
 +      }
 +
 +      SET_NETDEV_DEV(dev, &pdev->dev);
 +      dev->netdev_ops = &rtl_netdev_ops;
 +      tp = netdev_priv(dev);
 +      tp->dev = dev;
 +      tp->pci_dev = pdev;
 +      tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
 +
 +      mii = &tp->mii;
 +      mii->dev = dev;
 +      mii->mdio_read = rtl_mdio_read;
 +      mii->mdio_write = rtl_mdio_write;
 +      mii->phy_id_mask = 0x1f;
 +      mii->reg_num_mask = 0x1f;
 +      mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII);
 +
 +      /* disable ASPM completely as that cause random device stop working
 +       * problems as well as full system hangs for some PCIe devices users */
 +      pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
 +                                   PCIE_LINK_STATE_CLKPM);
  
 -      netif_device_detach(dev);
 -      netif_stop_queue(dev);
 -}
 +      /* enable device (incl. PCI PM wakeup and hotplug setup) */
 +      rc = pci_enable_device(pdev);
 +      if (rc < 0) {
 +              netif_err(tp, probe, dev, "enable failure\n");
 +              goto err_out_free_dev_1;
 +      }
  
 -#ifdef CONFIG_PM
 +      if (pci_set_mwi(pdev) < 0)
 +              netif_info(tp, probe, dev, "Mem-Wr-Inval unavailable\n");
  
 -static int rtl8169_suspend(struct device *device)
 -{
 -      struct pci_dev *pdev = to_pci_dev(device);
 -      struct net_device *dev = pci_get_drvdata(pdev);
 +      /* make sure PCI base addr 1 is MMIO */
 +      if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
 +              netif_err(tp, probe, dev,
 +                        "region #%d not an MMIO resource, aborting\n",
 +                        region);
 +              rc = -ENODEV;
 +              goto err_out_mwi_2;
 +      }
  
 -      rtl8169_net_suspend(dev);
 +      /* check for weird/broken PCI region reporting */
 +      if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) {
 +              netif_err(tp, probe, dev,
 +                        "Invalid PCI region size(s), aborting\n");
 +              rc = -ENODEV;
 +              goto err_out_mwi_2;
 +      }
  
 -      return 0;
 -}
 +      rc = pci_request_regions(pdev, MODULENAME);
 +      if (rc < 0) {
 +              netif_err(tp, probe, dev, "could not request regions\n");
 +              goto err_out_mwi_2;
 +      }
  
 -static void __rtl8169_resume(struct net_device *dev)
 -{
 -      struct rtl8169_private *tp = netdev_priv(dev);
 +      tp->cp_cmd = RxChkSum;
  
 -      netif_device_attach(dev);
 +      if ((sizeof(dma_addr_t) > 4) &&
 +          !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) {
 +              tp->cp_cmd |= PCIDAC;
 +              dev->features |= NETIF_F_HIGHDMA;
 +      } else {
 +              rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 +              if (rc < 0) {
 +                      netif_err(tp, probe, dev, "DMA configuration failed\n");
 +                      goto err_out_free_res_3;
 +              }
 +      }
  
 -      rtl_pll_power_up(tp);
 +      /* ioremap MMIO region */
 +      ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE);
 +      if (!ioaddr) {
 +              netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n");
 +              rc = -EIO;
 +              goto err_out_free_res_3;
 +      }
 +      tp->mmio_addr = ioaddr;
  
 -      rtl8169_schedule_work(dev, rtl8169_reset_task);
 -}
 +      if (!pci_is_pcie(pdev))
 +              netif_info(tp, probe, dev, "not PCI Express\n");
  
 -static int rtl8169_resume(struct device *device)
 -{
 -      struct pci_dev *pdev = to_pci_dev(device);
 -      struct net_device *dev = pci_get_drvdata(pdev);
 -      struct rtl8169_private *tp = netdev_priv(dev);
 +      /* Identify chip attached to board */
 +      rtl8169_get_mac_version(tp, dev, cfg->default_ver);
  
 -      rtl8169_init_phy(dev, tp);
 +      rtl_init_rxcfg(tp);
  
 -      if (netif_running(dev))
 -              __rtl8169_resume(dev);
 +      rtl_irq_disable(tp);
  
 -      return 0;
 -}
 +      rtl_hw_reset(tp);
  
 -static int rtl8169_runtime_suspend(struct device *device)
 -{
 -      struct pci_dev *pdev = to_pci_dev(device);
 -      struct net_device *dev = pci_get_drvdata(pdev);
 -      struct rtl8169_private *tp = netdev_priv(dev);
 +      rtl_ack_events(tp, 0xffff);
  
 -      if (!tp->TxDescArray)
 -              return 0;
 +      pci_set_master(pdev);
  
 -      spin_lock_irq(&tp->lock);
 -      tp->saved_wolopts = __rtl8169_get_wol(tp);
 -      __rtl8169_set_wol(tp, WAKE_ANY);
 -      spin_unlock_irq(&tp->lock);
 +      /*
 +       * Pretend we are using VLANs; This bypasses a nasty bug where
 +       * Interrupts stop flowing on high load on 8110SCd controllers.
 +       */
 +      if (tp->mac_version == RTL_GIGA_MAC_VER_05)
 +              tp->cp_cmd |= RxVlan;
  
 -      rtl8169_net_suspend(dev);
 +      rtl_init_mdio_ops(tp);
 +      rtl_init_pll_power_ops(tp);
 +      rtl_init_jumbo_ops(tp);
  
 -      return 0;
 -}
 +      rtl8169_print_mac_version(tp);
  
 -static int rtl8169_runtime_resume(struct device *device)
 -{
 -      struct pci_dev *pdev = to_pci_dev(device);
 -      struct net_device *dev = pci_get_drvdata(pdev);
 -      struct rtl8169_private *tp = netdev_priv(dev);
 +      chipset = tp->mac_version;
 +      tp->txd_version = rtl_chip_infos[chipset].txd_version;
  
 -      if (!tp->TxDescArray)
 -              return 0;
 +      RTL_W8(Cfg9346, Cfg9346_Unlock);
 +      RTL_W8(Config1, RTL_R8(Config1) | PMEnable);
 +      RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
 +      if ((RTL_R8(Config3) & (LinkUp | MagicPacket)) != 0)
 +              tp->features |= RTL_FEATURE_WOL;
 +      if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0)
 +              tp->features |= RTL_FEATURE_WOL;
 +      tp->features |= rtl_try_msi(tp, cfg);
 +      RTL_W8(Cfg9346, Cfg9346_Lock);
  
 -      spin_lock_irq(&tp->lock);
 -      __rtl8169_set_wol(tp, tp->saved_wolopts);
 -      tp->saved_wolopts = 0;
 -      spin_unlock_irq(&tp->lock);
 +      if (rtl_tbi_enabled(tp)) {
 +              tp->set_speed = rtl8169_set_speed_tbi;
 +              tp->get_settings = rtl8169_gset_tbi;
 +              tp->phy_reset_enable = rtl8169_tbi_reset_enable;
 +              tp->phy_reset_pending = rtl8169_tbi_reset_pending;
 +              tp->link_ok = rtl8169_tbi_link_ok;
 +              tp->do_ioctl = rtl_tbi_ioctl;
 +      } else {
 +              tp->set_speed = rtl8169_set_speed_xmii;
 +              tp->get_settings = rtl8169_gset_xmii;
 +              tp->phy_reset_enable = rtl8169_xmii_reset_enable;
 +              tp->phy_reset_pending = rtl8169_xmii_reset_pending;
 +              tp->link_ok = rtl8169_xmii_link_ok;
 +              tp->do_ioctl = rtl_xmii_ioctl;
 +      }
  
 -      rtl8169_init_phy(dev, tp);
 +      mutex_init(&tp->wk.mutex);
  
 -      __rtl8169_resume(dev);
 +      /* Get MAC address */
 +      for (i = 0; i < ETH_ALEN; i++)
 +              dev->dev_addr[i] = RTL_R8(MAC0 + i);
 +      memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
  
 -      return 0;
 -}
 +      SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
 +      dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
  
 -static int rtl8169_runtime_idle(struct device *device)
 -{
 -      struct pci_dev *pdev = to_pci_dev(device);
 -      struct net_device *dev = pci_get_drvdata(pdev);
 -      struct rtl8169_private *tp = netdev_priv(dev);
 +      netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
  
 -      return tp->TxDescArray ? -EBUSY : 0;
 -}
 +      /* don't enable SG, IP_CSUM and TSO by default - it might not work
 +       * properly for all devices */
 +      dev->features |= NETIF_F_RXCSUM |
 +              NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
  
 -static const struct dev_pm_ops rtl8169_pm_ops = {
 -      .suspend                = rtl8169_suspend,
 -      .resume                 = rtl8169_resume,
 -      .freeze                 = rtl8169_suspend,
 -      .thaw                   = rtl8169_resume,
 -      .poweroff               = rtl8169_suspend,
 -      .restore                = rtl8169_resume,
 -      .runtime_suspend        = rtl8169_runtime_suspend,
 -      .runtime_resume         = rtl8169_runtime_resume,
 -      .runtime_idle           = rtl8169_runtime_idle,
 -};
 +      dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
 +              NETIF_F_RXCSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 +      dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
 +              NETIF_F_HIGHDMA;
  
 -#define RTL8169_PM_OPS        (&rtl8169_pm_ops)
 +      if (tp->mac_version == RTL_GIGA_MAC_VER_05)
 +              /* 8110SCd requires hardware Rx VLAN - disallow toggling */
 +              dev->hw_features &= ~NETIF_F_HW_VLAN_RX;
  
 -#else /* !CONFIG_PM */
 +      dev->hw_features |= NETIF_F_RXALL;
 +      dev->hw_features |= NETIF_F_RXFCS;
  
 -#define RTL8169_PM_OPS        NULL
 +      tp->hw_start = cfg->hw_start;
 +      tp->event_slow = cfg->event_slow;
  
 -#endif /* !CONFIG_PM */
 +      tp->opts1_mask = (tp->mac_version != RTL_GIGA_MAC_VER_01) ?
 +              ~(RxBOVF | RxFOVF) : ~0;
  
 -static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp)
 -{
 -      void __iomem *ioaddr = tp->mmio_addr;
 +      init_timer(&tp->timer);
 +      tp->timer.data = (unsigned long) dev;
 +      tp->timer.function = rtl8169_phy_timer;
  
 -      /* WoL fails with 8168b when the receiver is disabled. */
 -      switch (tp->mac_version) {
 -      case RTL_GIGA_MAC_VER_11:
 -      case RTL_GIGA_MAC_VER_12:
 -      case RTL_GIGA_MAC_VER_17:
 -              pci_clear_master(tp->pci_dev);
 +      tp->rtl_fw = RTL_FIRMWARE_UNKNOWN;
  
 -              RTL_W8(ChipCmd, CmdRxEnb);
 -              /* PCI commit */
 -              RTL_R8(ChipCmd);
 -              break;
 -      default:
 -              break;
 -      }
 -}
 +      rc = register_netdev(dev);
 +      if (rc < 0)
 +              goto err_out_msi_4;
  
 -static void rtl_shutdown(struct pci_dev *pdev)
 -{
 -      struct net_device *dev = pci_get_drvdata(pdev);
 -      struct rtl8169_private *tp = netdev_priv(dev);
 +      pci_set_drvdata(pdev, dev);
  
 -      rtl8169_net_suspend(dev);
 +      netif_info(tp, probe, dev, "%s at 0x%p, %pM, XID %08x IRQ %d\n",
 +                 rtl_chip_infos[chipset].name, ioaddr, dev->dev_addr,
 +                 (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), pdev->irq);
 +      if (rtl_chip_infos[chipset].jumbo_max != JUMBO_1K) {
 +              netif_info(tp, probe, dev, "jumbo features [frames: %d bytes, "
 +                         "tx checksumming: %s]\n",
 +                         rtl_chip_infos[chipset].jumbo_max,
 +                         rtl_chip_infos[chipset].jumbo_tx_csum ? "ok" : "ko");
 +      }
  
 -      /* Restore original MAC address */
 -      rtl_rar_set(tp, dev->perm_addr);
 +      if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
 +          tp->mac_version == RTL_GIGA_MAC_VER_28 ||
 +          tp->mac_version == RTL_GIGA_MAC_VER_31) {
 +              rtl8168_driver_start(tp);
 +      }
  
 -      spin_lock_irq(&tp->lock);
 +      device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL);
  
 -      rtl8169_hw_reset(tp);
 +      if (pci_dev_run_wake(pdev))
 +              pm_runtime_put_noidle(&pdev->dev);
  
 -      spin_unlock_irq(&tp->lock);
 +      netif_carrier_off(dev);
  
 -      if (system_state == SYSTEM_POWER_OFF) {
 -              if (__rtl8169_get_wol(tp) & WAKE_ANY) {
 -                      rtl_wol_suspend_quirk(tp);
 -                      rtl_wol_shutdown_quirk(tp);
 -              }
 +out:
 +      return rc;
  
 -              pci_wake_from_d3(pdev, true);
 -              pci_set_power_state(pdev, PCI_D3hot);
 -      }
 +err_out_msi_4:
 +      rtl_disable_msi(pdev, tp);
 +      iounmap(ioaddr);
 +err_out_free_res_3:
 +      pci_release_regions(pdev);
 +err_out_mwi_2:
 +      pci_clear_mwi(pdev);
 +      pci_disable_device(pdev);
 +err_out_free_dev_1:
 +      free_netdev(dev);
 +      goto out;
  }
  
  static struct pci_driver rtl8169_pci_driver = {
Simple merge