ftgmac100: Remove rx descriptor accessors
Directly access the fields when needed. The accessors add clutter not clarity and in some cases cause unnecessary read-modify-write type access on the slow (uncached) descriptor memory. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
027f426d54
commit
4ca24152d8
|
@ -278,92 +278,6 @@ static void ftgmac100_stop_hw(struct ftgmac100 *priv)
|
|||
iowrite32(0, priv->base + FTGMAC100_OFFSET_MACCR);
|
||||
}
|
||||
|
||||
static bool ftgmac100_rxdes_first_segment(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_FRS);
|
||||
}
|
||||
|
||||
static bool ftgmac100_rxdes_last_segment(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_LRS);
|
||||
}
|
||||
|
||||
static bool ftgmac100_rxdes_packet_ready(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RXPKT_RDY);
|
||||
}
|
||||
|
||||
#define RXDES0_ANY_ERROR ( \
|
||||
FTGMAC100_RXDES0_RX_ERR | \
|
||||
FTGMAC100_RXDES0_CRC_ERR | \
|
||||
FTGMAC100_RXDES0_FTL | \
|
||||
FTGMAC100_RXDES0_RUNT | \
|
||||
FTGMAC100_RXDES0_RX_ODD_NB)
|
||||
|
||||
static inline bool ftgmac100_rxdes_any_error(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return rxdes->rxdes0 & cpu_to_le32(RXDES0_ANY_ERROR);
|
||||
}
|
||||
|
||||
static bool ftgmac100_rxdes_rx_error(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RX_ERR);
|
||||
}
|
||||
|
||||
static bool ftgmac100_rxdes_crc_error(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_CRC_ERR);
|
||||
}
|
||||
|
||||
static bool ftgmac100_rxdes_frame_too_long(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_FTL);
|
||||
}
|
||||
|
||||
static bool ftgmac100_rxdes_runt(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RUNT);
|
||||
}
|
||||
|
||||
static bool ftgmac100_rxdes_odd_nibble(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RX_ODD_NB);
|
||||
}
|
||||
|
||||
static unsigned int ftgmac100_rxdes_data_length(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return le32_to_cpu(rxdes->rxdes0) & FTGMAC100_RXDES0_VDBC;
|
||||
}
|
||||
|
||||
static bool ftgmac100_rxdes_multicast(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_MULTICAST);
|
||||
}
|
||||
|
||||
static void ftgmac100_rxdes_set_end_of_ring(const struct ftgmac100 *priv,
|
||||
struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
rxdes->rxdes0 |= cpu_to_le32(priv->rxdes0_edorr_mask);
|
||||
}
|
||||
|
||||
static void ftgmac100_rxdes_set_dma_addr(struct ftgmac100_rxdes *rxdes,
|
||||
dma_addr_t addr)
|
||||
{
|
||||
rxdes->rxdes3 = cpu_to_le32(addr);
|
||||
}
|
||||
|
||||
static dma_addr_t ftgmac100_rxdes_get_dma_addr(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return le32_to_cpu(rxdes->rxdes3);
|
||||
}
|
||||
|
||||
static inline bool ftgmac100_rxdes_csum_err(struct ftgmac100_rxdes *rxdes)
|
||||
{
|
||||
return !!(rxdes->rxdes1 & cpu_to_le32(FTGMAC100_RXDES1_TCP_CHKSUM_ERR |
|
||||
FTGMAC100_RXDES1_UDP_CHKSUM_ERR |
|
||||
FTGMAC100_RXDES1_IP_CHKSUM_ERR));
|
||||
}
|
||||
|
||||
static int ftgmac100_alloc_rx_buf(struct ftgmac100 *priv, unsigned int entry,
|
||||
struct ftgmac100_rxdes *rxdes, gfp_t gfp)
|
||||
{
|
||||
|
@ -395,13 +309,16 @@ static int ftgmac100_alloc_rx_buf(struct ftgmac100 *priv, unsigned int entry,
|
|||
priv->rx_skbs[entry] = skb;
|
||||
|
||||
/* Store DMA address into RX desc */
|
||||
ftgmac100_rxdes_set_dma_addr(rxdes, map);
|
||||
rxdes->rxdes3 = cpu_to_le32(map);
|
||||
|
||||
/* Ensure the above is ordered vs clearing the OWN bit */
|
||||
dma_wmb();
|
||||
|
||||
/* Clean rxdes0 (which resets own bit) */
|
||||
rxdes->rxdes0 &= cpu_to_le32(priv->rxdes0_edorr_mask);
|
||||
/* Clean status (which resets own bit) */
|
||||
if (entry == (RX_QUEUE_ENTRIES - 1))
|
||||
rxdes->rxdes0 = cpu_to_le32(priv->rxdes0_edorr_mask);
|
||||
else
|
||||
rxdes->rxdes0 = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -411,20 +328,19 @@ static int ftgmac100_next_rx_pointer(int pointer)
|
|||
return (pointer + 1) & (RX_QUEUE_ENTRIES - 1);
|
||||
}
|
||||
|
||||
static void ftgmac100_rx_packet_error(struct ftgmac100 *priv,
|
||||
struct ftgmac100_rxdes *rxdes)
|
||||
static void ftgmac100_rx_packet_error(struct ftgmac100 *priv, u32 status)
|
||||
{
|
||||
struct net_device *netdev = priv->netdev;
|
||||
|
||||
if (ftgmac100_rxdes_rx_error(rxdes))
|
||||
if (status & FTGMAC100_RXDES0_RX_ERR)
|
||||
netdev->stats.rx_errors++;
|
||||
|
||||
if (ftgmac100_rxdes_crc_error(rxdes))
|
||||
if (status & FTGMAC100_RXDES0_CRC_ERR)
|
||||
netdev->stats.rx_crc_errors++;
|
||||
|
||||
if (ftgmac100_rxdes_frame_too_long(rxdes) ||
|
||||
ftgmac100_rxdes_runt(rxdes) ||
|
||||
ftgmac100_rxdes_odd_nibble(rxdes))
|
||||
if (status & (FTGMAC100_RXDES0_FTL |
|
||||
FTGMAC100_RXDES0_RUNT |
|
||||
FTGMAC100_RXDES0_RX_ODD_NB))
|
||||
netdev->stats.rx_length_errors++;
|
||||
}
|
||||
|
||||
|
@ -434,27 +350,31 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
|
|||
struct ftgmac100_rxdes *rxdes;
|
||||
struct sk_buff *skb;
|
||||
unsigned int pointer, size;
|
||||
u32 status;
|
||||
dma_addr_t map;
|
||||
|
||||
/* Grab next RX descriptor */
|
||||
pointer = priv->rx_pointer;
|
||||
rxdes = &priv->descs->rxdes[pointer];
|
||||
|
||||
/* Grab descriptor status */
|
||||
status = le32_to_cpu(rxdes->rxdes0);
|
||||
|
||||
/* Do we have a packet ? */
|
||||
if (!ftgmac100_rxdes_packet_ready(rxdes))
|
||||
if (!(status & FTGMAC100_RXDES0_RXPKT_RDY))
|
||||
return false;
|
||||
|
||||
/* Order subsequent reads with the test for the ready bit */
|
||||
dma_rmb();
|
||||
|
||||
/* We don't cope with fragmented RX packets */
|
||||
if (unlikely(!ftgmac100_rxdes_first_segment(rxdes) ||
|
||||
!ftgmac100_rxdes_last_segment(rxdes)))
|
||||
if (unlikely(!(status & FTGMAC100_RXDES0_FRS) ||
|
||||
!(status & FTGMAC100_RXDES0_LRS)))
|
||||
goto drop;
|
||||
|
||||
/* Any error (other than csum offload) flagged ? */
|
||||
if (unlikely(ftgmac100_rxdes_any_error(rxdes))) {
|
||||
ftgmac100_rx_packet_error(priv, rxdes);
|
||||
if (unlikely(status & RXDES0_ANY_ERROR)) {
|
||||
ftgmac100_rx_packet_error(priv, status);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
|
@ -467,7 +387,7 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
|
|||
goto drop;
|
||||
}
|
||||
|
||||
if (unlikely(ftgmac100_rxdes_multicast(rxdes)))
|
||||
if (unlikely(status & FTGMAC100_RXDES0_MULTICAST))
|
||||
netdev->stats.multicast++;
|
||||
|
||||
/* If the HW found checksum errors, bounce it to software.
|
||||
|
@ -489,11 +409,12 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
|
|||
}
|
||||
|
||||
/* Grab received size annd transfer to skb */
|
||||
size = ftgmac100_rxdes_data_length(rxdes);
|
||||
size = status & FTGMAC100_RXDES0_VDBC;
|
||||
skb_put(skb, size);
|
||||
|
||||
/* Tear down DMA mapping, do necessary cache management */
|
||||
map = ftgmac100_rxdes_get_dma_addr(rxdes);
|
||||
map = le32_to_cpu(rxdes->rxdes3);
|
||||
|
||||
#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_DMA_USE_IOMMU)
|
||||
/* When we don't have an iommu, we can save cycles by not
|
||||
* invalidating the cache for the part of the packet that
|
||||
|
@ -525,7 +446,7 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
|
|||
|
||||
drop:
|
||||
/* Clean rxdes0 (which resets own bit) */
|
||||
rxdes->rxdes0 &= cpu_to_le32(priv->rxdes0_edorr_mask);
|
||||
rxdes->rxdes0 = cpu_to_le32(status & priv->rxdes0_edorr_mask);
|
||||
priv->rx_pointer = ftgmac100_next_rx_pointer(pointer);
|
||||
netdev->stats.rx_dropped++;
|
||||
return true;
|
||||
|
@ -747,7 +668,7 @@ static void ftgmac100_free_buffers(struct ftgmac100 *priv)
|
|||
for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
|
||||
struct ftgmac100_rxdes *rxdes = &priv->descs->rxdes[i];
|
||||
struct sk_buff *skb = priv->rx_skbs[i];
|
||||
dma_addr_t map = ftgmac100_rxdes_get_dma_addr(rxdes);
|
||||
dma_addr_t map = le32_to_cpu(rxdes->rxdes3);
|
||||
|
||||
if (!skb)
|
||||
continue;
|
||||
|
@ -806,15 +727,17 @@ static int ftgmac100_alloc_rings(struct ftgmac100 *priv)
|
|||
|
||||
static void ftgmac100_init_rings(struct ftgmac100 *priv)
|
||||
{
|
||||
struct ftgmac100_rxdes *rxdes;
|
||||
int i;
|
||||
|
||||
/* Initialize RX ring */
|
||||
for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
|
||||
struct ftgmac100_rxdes *rxdes = &priv->descs->rxdes[i];
|
||||
ftgmac100_rxdes_set_dma_addr(rxdes, priv->rx_scratch_dma);
|
||||
rxdes = &priv->descs->rxdes[i];
|
||||
rxdes->rxdes0 = 0;
|
||||
rxdes->rxdes3 = cpu_to_le32(priv->rx_scratch_dma);
|
||||
}
|
||||
ftgmac100_rxdes_set_end_of_ring(priv, &priv->descs->rxdes[i - 1]);
|
||||
/* Mark the end of the ring */
|
||||
rxdes->rxdes0 |= cpu_to_le32(priv->rxdes0_edorr_mask);
|
||||
|
||||
/* Initialize TX ring */
|
||||
for (i = 0; i < TX_QUEUE_ENTRIES; i++)
|
||||
|
@ -1030,6 +953,14 @@ static irqreturn_t ftgmac100_interrupt(int irq, void *dev_id)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static bool ftgmac100_check_rx(struct ftgmac100 *priv)
|
||||
{
|
||||
struct ftgmac100_rxdes *rxdes = &priv->descs->rxdes[priv->rx_pointer];
|
||||
|
||||
/* Do we have a packet ? */
|
||||
return !!(rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RXPKT_RDY));
|
||||
}
|
||||
|
||||
static int ftgmac100_poll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct ftgmac100 *priv = container_of(napi, struct ftgmac100, napi);
|
||||
|
@ -1069,8 +1000,7 @@ static int ftgmac100_poll(struct napi_struct *napi, int budget)
|
|||
*/
|
||||
iowrite32(FTGMAC100_INT_RXTX,
|
||||
priv->base + FTGMAC100_OFFSET_ISR);
|
||||
if (ftgmac100_rxdes_packet_ready
|
||||
(ftgmac100_current_rxdes(priv)) || priv->tx_pending)
|
||||
if (ftgmac100_check_rx(priv) || priv->tx_pending)
|
||||
return budget;
|
||||
|
||||
/* deschedule NAPI */
|
||||
|
|
|
@ -227,10 +227,10 @@ struct ftgmac100_txdes {
|
|||
* Receive descriptor, aligned to 16 bytes
|
||||
*/
|
||||
struct ftgmac100_rxdes {
|
||||
unsigned int rxdes0;
|
||||
unsigned int rxdes1;
|
||||
unsigned int rxdes2; /* not used by HW */
|
||||
unsigned int rxdes3; /* RXBUF_BADR */
|
||||
__le32 rxdes0; /* Control & status bits */
|
||||
__le32 rxdes1; /* Checksum and vlan status */
|
||||
__le32 rxdes2; /* length/type on AST2500 */
|
||||
__le32 rxdes3; /* DMA buffer address */
|
||||
} __attribute__ ((aligned(16)));
|
||||
|
||||
#define FTGMAC100_RXDES0_VDBC 0x3fff
|
||||
|
@ -248,6 +248,14 @@ struct ftgmac100_rxdes {
|
|||
#define FTGMAC100_RXDES0_FRS (1 << 29)
|
||||
#define FTGMAC100_RXDES0_RXPKT_RDY (1 << 31)
|
||||
|
||||
/* Errors we care about for dropping packets */
|
||||
#define RXDES0_ANY_ERROR ( \
|
||||
FTGMAC100_RXDES0_RX_ERR | \
|
||||
FTGMAC100_RXDES0_CRC_ERR | \
|
||||
FTGMAC100_RXDES0_FTL | \
|
||||
FTGMAC100_RXDES0_RUNT | \
|
||||
FTGMAC100_RXDES0_RX_ODD_NB)
|
||||
|
||||
#define FTGMAC100_RXDES1_VLANTAG_CI 0xffff
|
||||
#define FTGMAC100_RXDES1_PROT_MASK (0x3 << 20)
|
||||
#define FTGMAC100_RXDES1_PROT_NONIP (0x0 << 20)
|
||||
|
|
Loading…
Reference in New Issue