Merge branches 'arm/rockchip', 'arm/exynos', 'arm/smmu', 'x86/vt-d', 'x86/amd', ...
[sfrench/cifs-2.6.git] / drivers / net / ethernet / amd / xgbe / xgbe-drv.c
index 885b02b5be07f6732fc0540684cb7875aeec1140..9fd6c69a8bac3c77d1c0c6e99eb4f3644561f78a 100644 (file)
 
 static int xgbe_one_poll(struct napi_struct *, int);
 static int xgbe_all_poll(struct napi_struct *, int);
-static void xgbe_set_rx_mode(struct net_device *);
 
 static int xgbe_alloc_channels(struct xgbe_prv_data *pdata)
 {
@@ -411,11 +410,9 @@ static irqreturn_t xgbe_dma_isr(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
+static void xgbe_tx_timer(unsigned long data)
 {
-       struct xgbe_channel *channel = container_of(timer,
-                                                   struct xgbe_channel,
-                                                   tx_timer);
+       struct xgbe_channel *channel = (struct xgbe_channel *)data;
        struct xgbe_prv_data *pdata = channel->pdata;
        struct napi_struct *napi;
 
@@ -426,7 +423,7 @@ static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
        if (napi_schedule_prep(napi)) {
                /* Disable Tx and Rx interrupts */
                if (pdata->per_channel_irq)
-                       disable_irq(channel->dma_irq);
+                       disable_irq_nosync(channel->dma_irq);
                else
                        xgbe_disable_rx_tx_ints(pdata);
 
@@ -437,8 +434,6 @@ static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
        channel->tx_timer_active = 0;
 
        DBGPR("<--xgbe_tx_timer\n");
-
-       return HRTIMER_NORESTART;
 }
 
 static void xgbe_init_tx_timers(struct xgbe_prv_data *pdata)
@@ -454,9 +449,8 @@ static void xgbe_init_tx_timers(struct xgbe_prv_data *pdata)
                        break;
 
                DBGPR("  %s adding tx timer\n", channel->name);
-               hrtimer_init(&channel->tx_timer, CLOCK_MONOTONIC,
-                            HRTIMER_MODE_REL);
-               channel->tx_timer.function = xgbe_tx_timer;
+               setup_timer(&channel->tx_timer, xgbe_tx_timer,
+                           (unsigned long)channel);
        }
 
        DBGPR("<--xgbe_init_tx_timers\n");
@@ -475,8 +469,7 @@ static void xgbe_stop_tx_timers(struct xgbe_prv_data *pdata)
                        break;
 
                DBGPR("  %s deleting tx timer\n", channel->name);
-               channel->tx_timer_active = 0;
-               hrtimer_cancel(&channel->tx_timer);
+               del_timer_sync(&channel->tx_timer);
        }
 
        DBGPR("<--xgbe_stop_tx_timers\n");
@@ -519,6 +512,7 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
                                                RXFIFOSIZE);
        hw_feat->tx_fifo_size  = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
                                                TXFIFOSIZE);
+       hw_feat->dma_width     = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, ADDR64);
        hw_feat->dcb           = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DCBEN);
        hw_feat->sph           = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN);
        hw_feat->tso           = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN);
@@ -553,6 +547,21 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
                break;
        }
 
+       /* Translate the address width setting into actual number */
+       switch (hw_feat->dma_width) {
+       case 0:
+               hw_feat->dma_width = 32;
+               break;
+       case 1:
+               hw_feat->dma_width = 40;
+               break;
+       case 2:
+               hw_feat->dma_width = 48;
+               break;
+       default:
+               hw_feat->dma_width = 32;
+       }
+
        /* The Queue, Channel and TC counts are zero based so increment them
         * to get the actual number
         */
@@ -692,6 +701,7 @@ void xgbe_init_rx_coalesce(struct xgbe_prv_data *pdata)
        DBGPR("-->xgbe_init_rx_coalesce\n");
 
        pdata->rx_riwt = hw_if->usec_to_riwt(pdata, XGMAC_INIT_DMA_RX_USECS);
+       pdata->rx_usecs = XGMAC_INIT_DMA_RX_USECS;
        pdata->rx_frames = XGMAC_INIT_DMA_RX_FRAMES;
 
        hw_if->config_rx_coalesce(pdata);
@@ -941,8 +951,6 @@ static int xgbe_start(struct xgbe_prv_data *pdata)
 
        DBGPR("-->xgbe_start\n");
 
-       xgbe_set_rx_mode(netdev);
-
        hw_if->init(pdata);
 
        phy_start(pdata->phydev);
@@ -1522,17 +1530,10 @@ static void xgbe_set_rx_mode(struct net_device *netdev)
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
        struct xgbe_hw_if *hw_if = &pdata->hw_if;
-       unsigned int pr_mode, am_mode;
 
        DBGPR("-->xgbe_set_rx_mode\n");
 
-       pr_mode = ((netdev->flags & IFF_PROMISC) != 0);
-       am_mode = ((netdev->flags & IFF_ALLMULTI) != 0);
-
-       hw_if->set_promiscuous_mode(pdata, pr_mode);
-       hw_if->set_all_multicast_mode(pdata, am_mode);
-
-       hw_if->add_mac_addresses(pdata);
+       hw_if->config_rx_mode(pdata);
 
        DBGPR("<--xgbe_set_rx_mode\n");
 }
@@ -1599,6 +1600,14 @@ static int xgbe_change_mtu(struct net_device *netdev, int mtu)
        return 0;
 }
 
+static void xgbe_tx_timeout(struct net_device *netdev)
+{
+       struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+       netdev_warn(netdev, "tx timeout, device restarting\n");
+       schedule_work(&pdata->restart_work);
+}
+
 static struct rtnl_link_stats64 *xgbe_get_stats64(struct net_device *netdev,
                                                  struct rtnl_link_stats64 *s)
 {
@@ -1763,6 +1772,7 @@ static const struct net_device_ops xgbe_netdev_ops = {
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_do_ioctl           = xgbe_ioctl,
        .ndo_change_mtu         = xgbe_change_mtu,
+       .ndo_tx_timeout         = xgbe_tx_timeout,
        .ndo_get_stats64        = xgbe_get_stats64,
        .ndo_vlan_rx_add_vid    = xgbe_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = xgbe_vlan_rx_kill_vid,
@@ -1795,11 +1805,14 @@ static void xgbe_rx_refresh(struct xgbe_channel *channel)
                if (desc_if->map_rx_buffer(pdata, ring, rdata))
                        break;
 
-               hw_if->rx_desc_reset(rdata);
+               hw_if->rx_desc_reset(pdata, rdata, ring->dirty);
 
                ring->dirty++;
        }
 
+       /* Make sure everything is written before the register write */
+       wmb();
+
        /* Update the Rx Tail Pointer Register with address of
         * the last cleaned entry */
        rdata = XGBE_GET_DESC_DATA(ring, ring->dirty - 1);
@@ -1807,16 +1820,15 @@ static void xgbe_rx_refresh(struct xgbe_channel *channel)
                          lower_32_bits(rdata->rdesc_dma));
 }
 
-static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata,
+static struct sk_buff *xgbe_create_skb(struct napi_struct *napi,
                                       struct xgbe_ring_data *rdata,
                                       unsigned int *len)
 {
-       struct net_device *netdev = pdata->netdev;
        struct sk_buff *skb;
        u8 *packet;
        unsigned int copy_len;
 
-       skb = netdev_alloc_skb_ip_align(netdev, rdata->rx.hdr.dma_len);
+       skb = napi_alloc_skb(napi, rdata->rx.hdr.dma_len);
        if (!skb)
                return NULL;
 
@@ -1863,7 +1875,7 @@ static int xgbe_tx_poll(struct xgbe_channel *channel)
 
                /* Make sure descriptor fields are read after reading the OWN
                 * bit */
-               rmb();
+               dma_rmb();
 
 #ifdef XGMAC_ENABLE_TX_DESC_DUMP
                xgbe_dump_tx_desc(ring, ring->dirty, 1, 0);
@@ -1986,7 +1998,7 @@ read_again:
                                                        rdata->rx.hdr.dma_len,
                                                        DMA_FROM_DEVICE);
 
-                               skb = xgbe_create_skb(pdata, rdata, &put_len);
+                               skb = xgbe_create_skb(napi, rdata, &put_len);
                                if (!skb) {
                                        error = 1;
                                        goto skip_data;