Commit 01dd70b5 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by David S. Miller

ftgmac100: Simplify rx pointer handling in the rx path

We don't handle fragmented RX packets, so the "looping"
helpers to locate the first segment of a packet or to
drop a packet aren't actually helping.

Take them out and simplify ftgmac100_rx_packet() further
as a result.
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eb50af20
...@@ -431,34 +431,6 @@ static int ftgmac100_next_rx_pointer(int pointer) ...@@ -431,34 +431,6 @@ static int ftgmac100_next_rx_pointer(int pointer)
return (pointer + 1) & (RX_QUEUE_ENTRIES - 1); return (pointer + 1) & (RX_QUEUE_ENTRIES - 1);
} }
static void ftgmac100_rx_pointer_advance(struct ftgmac100 *priv)
{
priv->rx_pointer = ftgmac100_next_rx_pointer(priv->rx_pointer);
}
static struct ftgmac100_rxdes *ftgmac100_current_rxdes(struct ftgmac100 *priv)
{
return &priv->descs->rxdes[priv->rx_pointer];
}
static struct ftgmac100_rxdes *
ftgmac100_rx_locate_first_segment(struct ftgmac100 *priv)
{
struct ftgmac100_rxdes *rxdes = ftgmac100_current_rxdes(priv);
while (ftgmac100_rxdes_packet_ready(rxdes)) {
if (ftgmac100_rxdes_first_segment(rxdes))
return rxdes;
ftgmac100_rxdes_set_dma_own(priv, rxdes);
ftgmac100_rx_pointer_advance(priv);
rxdes = ftgmac100_current_rxdes(priv);
}
return NULL;
}
static void ftgmac100_rx_packet_error(struct ftgmac100 *priv, static void ftgmac100_rx_packet_error(struct ftgmac100 *priv,
struct ftgmac100_rxdes *rxdes) struct ftgmac100_rxdes *rxdes)
{ {
...@@ -476,51 +448,32 @@ static void ftgmac100_rx_packet_error(struct ftgmac100 *priv, ...@@ -476,51 +448,32 @@ static void ftgmac100_rx_packet_error(struct ftgmac100 *priv,
netdev->stats.rx_length_errors++; netdev->stats.rx_length_errors++;
} }
static void ftgmac100_rx_drop_packet(struct ftgmac100 *priv)
{
struct net_device *netdev = priv->netdev;
struct ftgmac100_rxdes *rxdes = ftgmac100_current_rxdes(priv);
bool done = false;
if (net_ratelimit())
netdev_dbg(netdev, "drop packet %p\n", rxdes);
do {
if (ftgmac100_rxdes_last_segment(rxdes))
done = true;
ftgmac100_rxdes_set_dma_own(priv, rxdes);
ftgmac100_rx_pointer_advance(priv);
rxdes = ftgmac100_current_rxdes(priv);
} while (!done && ftgmac100_rxdes_packet_ready(rxdes));
netdev->stats.rx_dropped++;
}
static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed) static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
{ {
struct net_device *netdev = priv->netdev; struct net_device *netdev = priv->netdev;
struct ftgmac100_rxdes *rxdes; struct ftgmac100_rxdes *rxdes;
struct sk_buff *skb; struct sk_buff *skb;
struct page *page; struct page *page;
unsigned int size; unsigned int pointer, size;
dma_addr_t map; dma_addr_t map;
rxdes = ftgmac100_rx_locate_first_segment(priv); /* Grab next RX descriptor */
if (!rxdes) pointer = priv->rx_pointer;
rxdes = &priv->descs->rxdes[pointer];
/* Do we have a packet ? */
if (!ftgmac100_rxdes_packet_ready(rxdes))
return false; return false;
/* We don't support segmented rx frames, so drop these /* We don't cope with fragmented RX packets */
* along with packets with errors. if (unlikely(!ftgmac100_rxdes_first_segment(rxdes) ||
*/ !ftgmac100_rxdes_last_segment(rxdes)))
if (unlikely(!ftgmac100_rxdes_last_segment(rxdes))) { goto drop;
ftgmac100_rx_drop_packet(priv);
return true; /* Any error (other than csum offload) flagged ? */
}
if (unlikely(ftgmac100_rxdes_any_error(rxdes))) { if (unlikely(ftgmac100_rxdes_any_error(rxdes))) {
ftgmac100_rx_packet_error(priv, rxdes); ftgmac100_rx_packet_error(priv, rxdes);
ftgmac100_rx_drop_packet(priv); goto drop;
return true;
} }
/* If the packet had no buffer (failed to allocate earlier) /* If the packet had no buffer (failed to allocate earlier)
...@@ -529,8 +482,7 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed) ...@@ -529,8 +482,7 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
page = ftgmac100_rxdes_get_page(priv, rxdes); page = ftgmac100_rxdes_get_page(priv, rxdes);
if (!page) { if (!page) {
ftgmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC); ftgmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC);
ftgmac100_rx_pointer_advance(priv); goto drop;
return true;
} }
/* start processing */ /* start processing */
...@@ -538,9 +490,7 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed) ...@@ -538,9 +490,7 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
if (unlikely(!skb)) { if (unlikely(!skb)) {
if (net_ratelimit()) if (net_ratelimit())
netdev_err(netdev, "rx skb alloc failed\n"); netdev_err(netdev, "rx skb alloc failed\n");
goto drop;
ftgmac100_rx_drop_packet(priv);
return true;
} }
if (unlikely(ftgmac100_rxdes_multicast(rxdes))) if (unlikely(ftgmac100_rxdes_multicast(rxdes)))
...@@ -577,8 +527,7 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed) ...@@ -577,8 +527,7 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
ftgmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC); ftgmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC);
ftgmac100_rx_pointer_advance(priv); priv->rx_pointer = ftgmac100_next_rx_pointer(pointer);
rxdes = ftgmac100_current_rxdes(priv);
/* Small frames are copied into linear part of skb to free one page */ /* Small frames are copied into linear part of skb to free one page */
if (skb->len <= 128) { if (skb->len <= 128) {
...@@ -601,6 +550,13 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed) ...@@ -601,6 +550,13 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
(*processed)++; (*processed)++;
return true; return true;
drop:
/* Clean rxdes0 (which resets own bit) */
rxdes->rxdes0 &= cpu_to_le32(priv->rxdes0_edorr_mask);
priv->rx_pointer = ftgmac100_next_rx_pointer(pointer);
netdev->stats.rx_dropped++;
return true;
} }
static void ftgmac100_txdes_reset(const struct ftgmac100 *priv, static void ftgmac100_txdes_reset(const struct ftgmac100 *priv,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment