igb: fix last_rx_timestamp usage
[cascardo/linux.git] / drivers / net / ethernet / intel / igb / igb_main.c
index d6b1152..fb98d46 100644 (file)
@@ -751,6 +751,28 @@ static void igb_cache_ring_register(struct igb_adapter *adapter)
        }
 }
 
+u32 igb_rd32(struct e1000_hw *hw, u32 reg)
+{
+       struct igb_adapter *igb = container_of(hw, struct igb_adapter, hw);
+       u8 __iomem *hw_addr = ACCESS_ONCE(hw->hw_addr);
+       u32 value = 0;
+
+       if (E1000_REMOVED(hw_addr))
+               return ~value;
+
+       value = readl(&hw_addr[reg]);
+
+       /* reads should not return all F's */
+       if (!(~value) && (!reg || !(~readl(hw_addr)))) {
+               struct net_device *netdev = igb->netdev;
+               hw->hw_addr = NULL;
+               netif_device_detach(netdev);
+               netdev_err(netdev, "PCIe link lost, device now detached\n");
+       }
+
+       return value;
+}
+
 /**
  *  igb_write_ivar - configure ivar for given MSI-X vector
  *  @hw: pointer to the HW structure
@@ -1013,6 +1035,12 @@ static void igb_reset_q_vector(struct igb_adapter *adapter, int v_idx)
 {
        struct igb_q_vector *q_vector = adapter->q_vector[v_idx];
 
+       /* Coming from igb_set_interrupt_capability, the vectors are not yet
+        * allocated. So, q_vector is NULL so we should stop here.
+        */
+       if (!q_vector)
+               return;
+
        if (q_vector->tx.ring)
                adapter->tx_ring[q_vector->tx.ring->queue_index] = NULL;
 
@@ -1121,6 +1149,7 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter, bool msix)
 
        /* If we can't do MSI-X, try MSI */
 msi_only:
+       adapter->flags &= ~IGB_FLAG_HAS_MSIX;
 #ifdef CONFIG_PCI_IOV
        /* disable SR-IOV for non MSI-X configurations */
        if (adapter->vf_data) {
@@ -2623,7 +2652,7 @@ err_eeprom:
                iounmap(hw->flash_address);
 err_sw_init:
        igb_clear_interrupt_scheme(adapter);
-       iounmap(hw->hw_addr);
+       pci_iounmap(pdev, hw->hw_addr);
 err_ioremap:
        free_netdev(netdev);
 err_alloc_etherdev:
@@ -2790,7 +2819,7 @@ static void igb_remove(struct pci_dev *pdev)
        igb_disable_sriov(pdev);
 #endif
 
-       iounmap(hw->hw_addr);
+       pci_iounmap(pdev, hw->hw_addr);
        if (hw->flash_address)
                iounmap(hw->flash_address);
        pci_release_selected_regions(pdev,
@@ -3542,6 +3571,13 @@ static inline void igb_set_vmolr(struct igb_adapter *adapter,
 
        vmolr = rd32(E1000_VMOLR(vfn));
        vmolr |= E1000_VMOLR_STRVLAN; /* Strip vlan tags */
+       if (hw->mac.type == e1000_i350) {
+               u32 dvmolr;
+
+               dvmolr = rd32(E1000_DVMOLR(vfn));
+               dvmolr |= E1000_DVMOLR_STRVLAN;
+               wr32(E1000_DVMOLR(vfn), dvmolr);
+       }
        if (aupe)
                vmolr |= E1000_VMOLR_AUPE; /* Accept untagged packets */
        else
@@ -4347,8 +4383,7 @@ enum latency_range {
  *  were determined based on theoretical maximum wire speed and testing
  *  data, in order to minimize response time while increasing bulk
  *  throughput.
- *  This functionality is controlled by the InterruptThrottleRate module
- *  parameter (see igb_param.c)
+ *  This functionality is controlled by ethtool's coalescing settings.
  *  NOTE:  This function is called only when operating in a multiqueue
  *         receive environment.
  **/
@@ -4422,8 +4457,7 @@ clear_counts:
  *  based on theoretical maximum wire speed and thresholds were set based
  *  on testing data as well as attempting to minimize response time
  *  while increasing bulk throughput.
- *  this functionality is controlled by the InterruptThrottleRate module
- *  parameter (see igb_param.c)
+ *  This functionality is controlled by ethtool's coalescing settings.
  *  NOTE:  These calculations are only valid when operating in a single-
  *         queue environment.
  **/
@@ -4571,6 +4605,7 @@ static int igb_tso(struct igb_ring *tx_ring,
        struct sk_buff *skb = first->skb;
        u32 vlan_macip_lens, type_tucmd;
        u32 mss_l4len_idx, l4len;
+       int err;
 
        if (skb->ip_summed != CHECKSUM_PARTIAL)
                return 0;
@@ -4578,16 +4613,14 @@ static int igb_tso(struct igb_ring *tx_ring,
        if (!skb_is_gso(skb))
                return 0;
 
-       if (skb_header_cloned(skb)) {
-               int err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-               if (err)
-                       return err;
-       }
+       err = skb_cow_head(skb, 0);
+       if (err < 0)
+               return err;
 
        /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
        type_tucmd = E1000_ADVTXD_TUCMD_L4T_TCP;
 
-       if (first->protocol == __constant_htons(ETH_P_IP)) {
+       if (first->protocol == htons(ETH_P_IP)) {
                struct iphdr *iph = ip_hdr(skb);
                iph->tot_len = 0;
                iph->check = 0;
@@ -4643,12 +4676,12 @@ static void igb_tx_csum(struct igb_ring *tx_ring, struct igb_tx_buffer *first)
        } else {
                u8 l4_hdr = 0;
                switch (first->protocol) {
-               case __constant_htons(ETH_P_IP):
+               case htons(ETH_P_IP):
                        vlan_macip_lens |= skb_network_header_len(skb);
                        type_tucmd |= E1000_ADVTXD_TUCMD_IPV4;
                        l4_hdr = ip_hdr(skb)->protocol;
                        break;
-               case __constant_htons(ETH_P_IPV6):
+               case htons(ETH_P_IPV6):
                        vlan_macip_lens |= skb_network_header_len(skb);
                        l4_hdr = ipv6_hdr(skb)->nexthdr;
                        break;
@@ -4946,12 +4979,11 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
        first->bytecount = skb->len;
        first->gso_segs = 1;
 
-       skb_tx_timestamp(skb);
-
        if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
                struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
 
-               if (!(adapter->ptp_tx_skb)) {
+               if (!test_and_set_bit_lock(__IGB_PTP_TX_IN_PROGRESS,
+                                          &adapter->state)) {
                        skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
                        tx_flags |= IGB_TX_FLAGS_TSTAMP;
 
@@ -4962,6 +4994,8 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
                }
        }
 
+       skb_tx_timestamp(skb);
+
        if (vlan_tx_tag_present(skb)) {
                tx_flags |= IGB_TX_FLAGS_VLAN;
                tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT);
@@ -6733,7 +6767,7 @@ static unsigned int igb_get_headlen(unsigned char *data,
        hdr.network += ETH_HLEN;
 
        /* handle any vlan tag if present */
-       if (protocol == __constant_htons(ETH_P_8021Q)) {
+       if (protocol == htons(ETH_P_8021Q)) {
                if ((hdr.network - data) > (max_len - VLAN_HLEN))
                        return max_len;
 
@@ -6742,7 +6776,7 @@ static unsigned int igb_get_headlen(unsigned char *data,
        }
 
        /* handle L3 protocols */
-       if (protocol == __constant_htons(ETH_P_IP)) {
+       if (protocol == htons(ETH_P_IP)) {
                if ((hdr.network - data) > (max_len - sizeof(struct iphdr)))
                        return max_len;
 
@@ -6756,7 +6790,7 @@ static unsigned int igb_get_headlen(unsigned char *data,
                /* record next protocol if header is present */
                if (!(hdr.ipv4->frag_off & htons(IP_OFFSET)))
                        nexthdr = hdr.ipv4->protocol;
-       } else if (protocol == __constant_htons(ETH_P_IPV6)) {
+       } else if (protocol == htons(ETH_P_IPV6)) {
                if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr)))
                        return max_len;
 
@@ -6920,7 +6954,9 @@ static void igb_process_skb_fields(struct igb_ring *rx_ring,
 
        igb_rx_checksum(rx_ring, rx_desc, skb);
 
-       igb_ptp_rx_hwtstamp(rx_ring, rx_desc, skb);
+       if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TS) &&
+           !igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP))
+               igb_ptp_rx_rgtstamp(rx_ring->q_vector, skb);
 
        if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
            igb_test_staterr(rx_desc, E1000_RXD_STAT_VP)) {
@@ -7157,8 +7193,10 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
        case SIOCGMIIREG:
        case SIOCSMIIREG:
                return igb_mii_ioctl(netdev, ifr, cmd);
+       case SIOCGHWTSTAMP:
+               return igb_ptp_get_ts_config(netdev, ifr);
        case SIOCSHWTSTAMP:
-               return igb_ptp_hwtstamp_ioctl(netdev, ifr, cmd);
+               return igb_ptp_set_ts_config(netdev, ifr);
        default:
                return -EOPNOTSUPP;
        }