return j;
 }
 
-#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
+#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
 static void enetc_get_rx_tstamp(struct net_device *ndev,
                                union enetc_rx_bd *rxbd,
                                struct sk_buff *skb)
        if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_TSTMP) {
                lo = enetc_rd(hw, ENETC_SICTR0);
                hi = enetc_rd(hw, ENETC_SICTR1);
-               tstamp_lo = le32_to_cpu(rxbd->r.tstamp);
+               rxbd = enetc_rxbd_ext(rxbd);
+               tstamp_lo = le32_to_cpu(rxbd->ext.tstamp);
                if (lo <= tstamp_lo)
                        hi -= 1;
 
 static void enetc_get_offloads(struct enetc_bdr *rx_ring,
                               union enetc_rx_bd *rxbd, struct sk_buff *skb)
 {
-#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
+#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
        struct enetc_ndev_priv *priv = netdev_priv(rx_ring->ndev);
 #endif
        /* TODO: hashing */
        if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_VLAN)
                __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
                                       le16_to_cpu(rxbd->r.vlan_opt));
-#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
+#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
        if (priv->active_offloads & ENETC_F_RX_TSTAMP)
                enetc_get_rx_tstamp(rx_ring->ndev, rxbd, skb);
 #endif
                enetc_free_txbdr(priv->tx_ring[i]);
 }
 
-static int enetc_alloc_rxbdr(struct enetc_bdr *rxr)
+static int enetc_alloc_rxbdr(struct enetc_bdr *rxr, bool extended)
 {
+       size_t size = sizeof(union enetc_rx_bd);
        int err;
 
        rxr->rx_swbd = vzalloc(rxr->bd_count * sizeof(struct enetc_rx_swbd));
        if (!rxr->rx_swbd)
                return -ENOMEM;
 
-       err = enetc_dma_alloc_bdr(rxr, sizeof(union enetc_rx_bd));
+       if (extended)
+               size *= 2;
+
+       err = enetc_dma_alloc_bdr(rxr, size);
        if (err) {
                vfree(rxr->rx_swbd);
                return err;
        rxr->next_to_clean = 0;
        rxr->next_to_use = 0;
        rxr->next_to_alloc = 0;
+       rxr->ext_en = extended;
 
        return 0;
 }
 
 static int enetc_alloc_rx_resources(struct enetc_ndev_priv *priv)
 {
+       bool extended = !!(priv->active_offloads & ENETC_F_RX_TSTAMP);
        int i, err;
 
        for (i = 0; i < priv->num_rx_rings; i++) {
-               err = enetc_alloc_rxbdr(priv->rx_ring[i]);
+               err = enetc_alloc_rxbdr(priv->rx_ring[i], extended);
 
                if (err)
                        goto fail;
        enetc_rxbdr_wr(hw, idx, ENETC_RBICIR0, ENETC_RBICIR0_ICEN | 0x1);
 
        rbmr = ENETC_RBMR_EN;
-#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
-       rbmr |= ENETC_RBMR_BDS;
-#endif
+
+       if (rx_ring->ext_en)
+               rbmr |= ENETC_RBMR_BDS;
+
        if (rx_ring->ndev->features & NETIF_F_HW_VLAN_CTAG_RX)
                rbmr |= ENETC_RBMR_VTE;
 
        return 0;
 }
 
-#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
+#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
 static int enetc_hwtstamp_set(struct net_device *ndev, struct ifreq *ifr)
 {
        struct enetc_ndev_priv *priv = netdev_priv(ndev);
        struct hwtstamp_config config;
+       int ao;
 
        if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
                return -EFAULT;
                return -ERANGE;
        }
 
+       ao = priv->active_offloads;
        switch (config.rx_filter) {
        case HWTSTAMP_FILTER_NONE:
                priv->active_offloads &= ~ENETC_F_RX_TSTAMP;
                config.rx_filter = HWTSTAMP_FILTER_ALL;
        }
 
+       if (netif_running(ndev) && ao != priv->active_offloads) {
+               enetc_close(ndev);
+               enetc_open(ndev);
+       }
+
        return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
               -EFAULT : 0;
 }
 
 int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 {
-#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
+#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
        if (cmd == SIOCSHWTSTAMP)
                return enetc_hwtstamp_set(ndev, rq);
        if (cmd == SIOCGHWTSTAMP)
 
 
        dma_addr_t bd_dma_base;
        u8 tsd_enable; /* Time specific departure */
+       bool ext_en; /* enable h/w descriptor extensions */
 } ____cacheline_aligned_in_smp;
 
 static inline void enetc_bdr_idx_inc(struct enetc_bdr *bdr, int *i)
 
 static inline union enetc_rx_bd *enetc_rxbd(struct enetc_bdr *rx_ring, int i)
 {
-       return &(((union enetc_rx_bd *)rx_ring->bd_base)[i]);
+       int hw_idx = i;
+
+#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
+       if (rx_ring->ext_en)
+               hw_idx = 2 * i;
+#endif
+       return &(((union enetc_rx_bd *)rx_ring->bd_base)[hw_idx]);
 }
 
 static inline union enetc_rx_bd *enetc_rxbd_next(struct enetc_bdr *rx_ring,
                                                 int i)
 {
        rxbd++;
+#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
+       if (rx_ring->ext_en)
+               rxbd++;
+#endif
        if (unlikely(++i == rx_ring->bd_count))
                rxbd = rx_ring->bd_base;
 
        return rxbd;
 }
 
+static inline union enetc_rx_bd *enetc_rxbd_ext(union enetc_rx_bd *rxbd)
+{
+       return ++rxbd;
+}
+
 struct enetc_msg_swbd {
        void *vaddr;
        dma_addr_t dma;