amd-xgbe: Allow rx-frames coalescing to be changed anytime
authorLendacky, Thomas <Thomas.Lendacky@amd.com>
Thu, 9 Apr 2015 17:11:51 +0000 (12:11 -0500)
committerDavid S. Miller <davem@davemloft.net>
Thu, 9 Apr 2015 21:35:37 +0000 (17:35 -0400)
Currently the device must be down in order to update the rx-frames
coalescing setting because the interrupt indicator is set in the
descriptor data during initialization. Allow this setting to be changed
while the device is up by moving the interrupt decision into the
descriptor reset function and base the decision off of the supplied
descriptor index value.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/amd/xgbe/xgbe-dev.c
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
drivers/net/ethernet/amd/xgbe/xgbe.h

index 80dd7a92f3574b5d09f04d077def087016c136e0..96c5e4babbdf4b391a5c1c6f3241b087e1be364d 100644 (file)
@@ -1101,9 +1101,24 @@ static void xgbe_tx_desc_init(struct xgbe_channel *channel)
        DBGPR("<--tx_desc_init\n");
 }
 
-static void xgbe_rx_desc_reset(struct xgbe_ring_data *rdata)
+static void xgbe_rx_desc_reset(struct xgbe_prv_data *pdata,
+                              struct xgbe_ring_data *rdata, unsigned int index)
 {
        struct xgbe_ring_desc *rdesc = rdata->rdesc;
+       unsigned int rx_usecs = pdata->rx_usecs;
+       unsigned int rx_frames = pdata->rx_frames;
+       unsigned int inte;
+
+       if (!rx_usecs && !rx_frames) {
+               /* No coalescing, interrupt for every descriptor */
+               inte = 1;
+       } else {
+               /* Set interrupt based on Rx frame coalescing setting */
+               if (rx_frames && !((index + 1) % rx_frames))
+                       inte = 1;
+               else
+                       inte = 0;
+       }
 
        /* Reset the Rx descriptor
         *   Set buffer 1 (lo) address to header dma address (lo)
@@ -1117,8 +1132,7 @@ static void xgbe_rx_desc_reset(struct xgbe_ring_data *rdata)
        rdesc->desc2 = cpu_to_le32(lower_32_bits(rdata->rx.buf.dma));
        rdesc->desc3 = cpu_to_le32(upper_32_bits(rdata->rx.buf.dma));
 
-       XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, INTE,
-                         rdata->interrupt ? 1 : 0);
+       XGMAC_SET_BITS_LE(rdesc->desc3, RX_NORMAL_DESC3, INTE, inte);
 
        /* Since the Rx DMA engine is likely running, make sure everything
         * is written to the descriptor(s) before setting the OWN bit
@@ -1138,26 +1152,16 @@ static void xgbe_rx_desc_init(struct xgbe_channel *channel)
        struct xgbe_ring *ring = channel->rx_ring;
        struct xgbe_ring_data *rdata;
        unsigned int start_index = ring->cur;
-       unsigned int rx_coalesce, rx_frames;
        unsigned int i;
 
        DBGPR("-->rx_desc_init\n");
 
-       rx_coalesce = (pdata->rx_riwt || pdata->rx_frames) ? 1 : 0;
-       rx_frames = pdata->rx_frames;
-
        /* Initialize all descriptors */
        for (i = 0; i < ring->rdesc_count; i++) {
                rdata = XGBE_GET_DESC_DATA(ring, i);
 
-               /* Set interrupt on completion bit as appropriate */
-               if (rx_coalesce && (!rx_frames || ((i + 1) % rx_frames)))
-                       rdata->interrupt = 0;
-               else
-                       rdata->interrupt = 1;
-
                /* Initialize Rx descriptor */
-               xgbe_rx_desc_reset(rdata);
+               xgbe_rx_desc_reset(pdata, rdata, i);
        }
 
        /* Update the total number of Rx descriptors */
index 347fe2419a18a0514b7ea3f29350a0c1e33deae4..74b4698ea95834090257d75ee699943834f6cc3a 100644 (file)
@@ -1806,7 +1806,7 @@ 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++;
        }
index b4f6eaaa08f0732211435c011e87e518c63cfbad..5f149e8ee20f0fa1a0878c37f2d44427fbe75f7f 100644 (file)
@@ -424,16 +424,6 @@ static int xgbe_set_coalesce(struct net_device *netdev,
            (ec->rate_sample_interval))
                return -EOPNOTSUPP;
 
-       /* Can only change rx-frames when interface is down (see
-        * rx_descriptor_init in xgbe-dev.c)
-        */
-       rx_frames = pdata->rx_frames;
-       if (rx_frames != ec->rx_max_coalesced_frames && netif_running(netdev)) {
-               netdev_alert(netdev,
-                            "interface must be down to change rx-frames\n");
-               return -EINVAL;
-       }
-
        rx_riwt = hw_if->usec_to_riwt(pdata, ec->rx_coalesce_usecs);
        rx_usecs = ec->rx_coalesce_usecs;
        rx_frames = ec->rx_max_coalesced_frames;
index dd742426eb0425e9c4a7b041ee4cf3764694515e..a864eabe5cd0dc202befd6bfd1eb64fde5904a37 100644 (file)
@@ -325,8 +325,6 @@ struct xgbe_ring_data {
        struct xgbe_tx_ring_data tx;    /* Tx-related data */
        struct xgbe_rx_ring_data rx;    /* Rx-related data */
 
-       unsigned int interrupt;         /* Interrupt indicator */
-
        unsigned int mapped_as_page;
 
        /* Incomplete receive save location.  If the budget is exhausted
@@ -536,8 +534,9 @@ struct xgbe_hw_if {
        int (*dev_read)(struct xgbe_channel *);
        void (*tx_desc_init)(struct xgbe_channel *);
        void (*rx_desc_init)(struct xgbe_channel *);
-       void (*rx_desc_reset)(struct xgbe_ring_data *);
        void (*tx_desc_reset)(struct xgbe_ring_data *);
+       void (*rx_desc_reset)(struct xgbe_prv_data *, struct xgbe_ring_data *,
+                             unsigned int);
        int (*is_last_desc)(struct xgbe_ring_desc *);
        int (*is_context_desc)(struct xgbe_ring_desc *);
        void (*tx_start_xmit)(struct xgbe_channel *, struct xgbe_ring *);