Skip to content

Commit

Permalink
amd-xgbe: Simplify the Rx desciptor ring tracking
Browse files Browse the repository at this point in the history
Make the Rx descriptor ring processing similar to the Tx descriptor
ring processing.  Remove the realloc_index and realloc_threshold
variables and base everything on the current index counter and the
dirty index counter.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Lendacky, Thomas authored and David S. Miller committed Jan 17, 2015
1 parent 916102c commit 270894e
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 43 deletions.
32 changes: 1 addition & 31 deletions drivers/net/ethernet/amd/xgbe/xgbe-desc.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,6 @@ static void xgbe_wrapper_rx_descriptor_init(struct xgbe_prv_data *pdata)

ring->cur = 0;
ring->dirty = 0;
memset(&ring->rx, 0, sizeof(ring->rx));

hw_if->rx_desc_init(channel);
}
Expand Down Expand Up @@ -621,43 +620,14 @@ static int xgbe_map_tx_skb(struct xgbe_channel *channel, struct sk_buff *skb)
return 0;
}

static void xgbe_realloc_rx_buffer(struct xgbe_channel *channel)
{
struct xgbe_prv_data *pdata = channel->pdata;
struct xgbe_hw_if *hw_if = &pdata->hw_if;
struct xgbe_ring *ring = channel->rx_ring;
struct xgbe_ring_data *rdata;
int i;

DBGPR("-->xgbe_realloc_rx_buffer: rx_ring->rx.realloc_index = %u\n",
ring->rx.realloc_index);

for (i = 0; i < ring->dirty; i++) {
rdata = XGBE_GET_DESC_DATA(ring, ring->rx.realloc_index);

/* Reset rdata values */
xgbe_unmap_rdata(pdata, rdata);

if (xgbe_map_rx_buffer(pdata, ring, rdata))
break;

hw_if->rx_desc_reset(rdata);

ring->rx.realloc_index++;
}
ring->dirty = 0;

DBGPR("<--xgbe_realloc_rx_buffer\n");
}

void xgbe_init_function_ptrs_desc(struct xgbe_desc_if *desc_if)
{
DBGPR("-->xgbe_init_function_ptrs_desc\n");

desc_if->alloc_ring_resources = xgbe_alloc_ring_resources;
desc_if->free_ring_resources = xgbe_free_ring_resources;
desc_if->map_tx_skb = xgbe_map_tx_skb;
desc_if->realloc_rx_buffer = xgbe_realloc_rx_buffer;
desc_if->map_rx_buffer = xgbe_map_rx_buffer;
desc_if->unmap_rdata = xgbe_unmap_rdata;
desc_if->wrapper_tx_desc_init = xgbe_wrapper_tx_descriptor_init;
desc_if->wrapper_rx_desc_init = xgbe_wrapper_rx_descriptor_init;
Expand Down
25 changes: 21 additions & 4 deletions drivers/net/ethernet/amd/xgbe/xgbe-drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ static inline unsigned int xgbe_tx_avail_desc(struct xgbe_ring *ring)
return (ring->rdesc_count - (ring->cur - ring->dirty));
}

static inline unsigned int xgbe_rx_dirty_desc(struct xgbe_ring *ring)
{
return (ring->cur - ring->dirty);
}

static int xgbe_maybe_stop_tx_queue(struct xgbe_channel *channel,
struct xgbe_ring *ring, unsigned int count)
{
Expand Down Expand Up @@ -1775,15 +1780,28 @@ struct net_device_ops *xgbe_get_netdev_ops(void)
static void xgbe_rx_refresh(struct xgbe_channel *channel)
{
struct xgbe_prv_data *pdata = channel->pdata;
struct xgbe_hw_if *hw_if = &pdata->hw_if;
struct xgbe_desc_if *desc_if = &pdata->desc_if;
struct xgbe_ring *ring = channel->rx_ring;
struct xgbe_ring_data *rdata;

desc_if->realloc_rx_buffer(channel);
while (ring->dirty != ring->cur) {
rdata = XGBE_GET_DESC_DATA(ring, ring->dirty);

/* Reset rdata values */
desc_if->unmap_rdata(pdata, rdata);

if (desc_if->map_rx_buffer(pdata, ring, rdata))
break;

hw_if->rx_desc_reset(rdata);

ring->dirty++;
}

/* Update the Rx Tail Pointer Register with address of
* the last cleaned entry */
rdata = XGBE_GET_DESC_DATA(ring, ring->rx.realloc_index - 1);
rdata = XGBE_GET_DESC_DATA(ring, ring->dirty - 1);
XGMAC_DMA_IOWRITE(channel, DMA_CH_RDTR_LO,
lower_32_bits(rdata->rdesc_dma));
}
Expand Down Expand Up @@ -1933,15 +1951,14 @@ static int xgbe_rx_poll(struct xgbe_channel *channel, int budget)
read_again:
rdata = XGBE_GET_DESC_DATA(ring, ring->cur);

if (ring->dirty > (XGBE_RX_DESC_CNT >> 3))
if (xgbe_rx_dirty_desc(ring) > (XGBE_RX_DESC_CNT >> 3))
xgbe_rx_refresh(channel);

if (hw_if->dev_read(channel))
break;

received++;
ring->cur++;
ring->dirty++;

incomplete = XGMAC_GET_BITS(packet->attributes,
RX_PACKET_ATTRIBUTES,
Expand Down
11 changes: 3 additions & 8 deletions drivers/net/ethernet/amd/xgbe/xgbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,7 @@ struct xgbe_ring {
* cur - Tx: index of descriptor to be used for current transfer
* Rx: index of descriptor to check for packet availability
* dirty - Tx: index of descriptor to check for transfer complete
* Rx: count of descriptors in which a packet has been received
* (used with skb_realloc_index to refresh the ring)
* Rx: index of descriptor to check for buffer reallocation
*/
unsigned int cur;
unsigned int dirty;
Expand All @@ -377,11 +376,6 @@ struct xgbe_ring {
unsigned short cur_mss;
unsigned short cur_vlan_ctag;
} tx;

struct {
unsigned int realloc_index;
unsigned int realloc_threshold;
} rx;
};
} ____cacheline_aligned;

Expand Down Expand Up @@ -596,7 +590,8 @@ struct xgbe_desc_if {
int (*alloc_ring_resources)(struct xgbe_prv_data *);
void (*free_ring_resources)(struct xgbe_prv_data *);
int (*map_tx_skb)(struct xgbe_channel *, struct sk_buff *);
void (*realloc_rx_buffer)(struct xgbe_channel *);
int (*map_rx_buffer)(struct xgbe_prv_data *, struct xgbe_ring *,
struct xgbe_ring_data *);
void (*unmap_rdata)(struct xgbe_prv_data *, struct xgbe_ring_data *);
void (*wrapper_tx_desc_init)(struct xgbe_prv_data *);
void (*wrapper_rx_desc_init)(struct xgbe_prv_data *);
Expand Down

0 comments on commit 270894e

Please sign in to comment.