Commit 5a5efed4 authored by Dai Haruki's avatar Dai Haruki Committed by David S. Miller

gianfar: Make all BD status writes 32-bit

Whenever we want to update the status field in a BD, we usually want to
update the length field, too.  By combining them into one 32-bit field, we
reduce the number of stores to memory shared with the controller, and we
eliminate the need for order-enforcement, as the length and "READY" bit are
now updated atomically at the same time.
Signed-off-by: default avatarDai Haruki <Dai.Haruki@freescale.com>
Signed-off-by: default avatarAndy Fleming <afleming@freescale.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 31de198b
...@@ -854,8 +854,7 @@ static void free_skb_resources(struct gfar_private *priv) ...@@ -854,8 +854,7 @@ static void free_skb_resources(struct gfar_private *priv)
priv->rx_skbuff[i] = NULL; priv->rx_skbuff[i] = NULL;
} }
rxbdp->status = 0; rxbdp->lstatus = 0;
rxbdp->length = 0;
rxbdp->bufPtr = 0; rxbdp->bufPtr = 0;
rxbdp++; rxbdp++;
...@@ -976,8 +975,7 @@ int startup_gfar(struct net_device *dev) ...@@ -976,8 +975,7 @@ int startup_gfar(struct net_device *dev)
/* Initialize Transmit Descriptor Ring */ /* Initialize Transmit Descriptor Ring */
txbdp = priv->tx_bd_base; txbdp = priv->tx_bd_base;
for (i = 0; i < priv->tx_ring_size; i++) { for (i = 0; i < priv->tx_ring_size; i++) {
txbdp->status = 0; txbdp->lstatus = 0;
txbdp->length = 0;
txbdp->bufPtr = 0; txbdp->bufPtr = 0;
txbdp++; txbdp++;
} }
...@@ -1216,7 +1214,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1216,7 +1214,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
struct txfcb *fcb = NULL; struct txfcb *fcb = NULL;
struct txbd8 *txbdp, *base; struct txbd8 *txbdp, *base;
u16 status; u32 lstatus;
unsigned long flags; unsigned long flags;
/* Update transmit stats */ /* Update transmit stats */
...@@ -1230,26 +1228,25 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1230,26 +1228,25 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
base = priv->tx_bd_base; base = priv->tx_bd_base;
/* Clear all but the WRAP status flags */ /* Clear all but the WRAP status flags */
status = txbdp->status & TXBD_WRAP; lstatus = txbdp->lstatus & BD_LFLAG(TXBD_WRAP);
/* Set up checksumming */ /* Set up checksumming */
if (CHECKSUM_PARTIAL == skb->ip_summed) { if (CHECKSUM_PARTIAL == skb->ip_summed) {
fcb = gfar_add_fcb(skb); fcb = gfar_add_fcb(skb);
status |= TXBD_TOE; lstatus |= BD_LFLAG(TXBD_TOE);
gfar_tx_checksum(skb, fcb); gfar_tx_checksum(skb, fcb);
} }
if (priv->vlgrp && vlan_tx_tag_present(skb)) { if (priv->vlgrp && vlan_tx_tag_present(skb)) {
if (unlikely(NULL == fcb)) { if (unlikely(NULL == fcb)) {
fcb = gfar_add_fcb(skb); fcb = gfar_add_fcb(skb);
status |= TXBD_TOE; lstatus |= BD_LFLAG(TXBD_TOE);
} }
gfar_tx_vlan(skb, fcb); gfar_tx_vlan(skb, fcb);
} }
/* Set buffer length and pointer */ /* Set buffer length and pointer */
txbdp->length = skb->len;
txbdp->bufPtr = dma_map_single(&dev->dev, skb->data, txbdp->bufPtr = dma_map_single(&dev->dev, skb->data,
skb->len, DMA_TO_DEVICE); skb->len, DMA_TO_DEVICE);
...@@ -1260,12 +1257,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1260,12 +1257,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
priv->skb_curtx = priv->skb_curtx =
(priv->skb_curtx + 1) & TX_RING_MOD_MASK(priv->tx_ring_size); (priv->skb_curtx + 1) & TX_RING_MOD_MASK(priv->tx_ring_size);
/* Flag the BD as interrupt-causing */ /* Flag the BD as ready, interrupt-causing, last, and in need of CRC */
status |= TXBD_INTERRUPT; lstatus |=
BD_LFLAG(TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT) |
/* Flag the BD as ready to go, last in frame, and */ skb->len;
/* in need of CRC */
status |= (TXBD_READY | TXBD_LAST | TXBD_CRC);
dev->trans_start = jiffies; dev->trans_start = jiffies;
...@@ -1278,7 +1273,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1278,7 +1273,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/ */
eieio(); eieio();
txbdp->status = status; txbdp->lstatus = lstatus;
txbdp = next_bd(txbdp, base, priv->tx_ring_size); txbdp = next_bd(txbdp, base, priv->tx_ring_size);
...@@ -1546,20 +1541,19 @@ static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp, ...@@ -1546,20 +1541,19 @@ static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
u32 * status_len = (u32 *)bdp; u32 lstatus;
u16 flags;
bdp->bufPtr = dma_map_single(&dev->dev, skb->data, bdp->bufPtr = dma_map_single(&dev->dev, skb->data,
priv->rx_buffer_size, DMA_FROM_DEVICE); priv->rx_buffer_size, DMA_FROM_DEVICE);
flags = RXBD_EMPTY | RXBD_INTERRUPT; lstatus = BD_LFLAG(RXBD_EMPTY | RXBD_INTERRUPT);
if (bdp == priv->rx_bd_base + priv->rx_ring_size - 1) if (bdp == priv->rx_bd_base + priv->rx_ring_size - 1)
flags |= RXBD_WRAP; lstatus |= BD_LFLAG(RXBD_WRAP);
eieio(); eieio();
*status_len = (u32)flags << 16; bdp->lstatus = lstatus;
} }
......
...@@ -311,6 +311,8 @@ extern const char gfar_driver_version[]; ...@@ -311,6 +311,8 @@ extern const char gfar_driver_version[];
#define ATTRELI_EI_MASK 0x00003fff #define ATTRELI_EI_MASK 0x00003fff
#define ATTRELI_EI(x) (x) #define ATTRELI_EI(x) (x)
#define BD_LFLAG(flags) ((flags) << 16)
#define BD_LENGTH_MASK 0x00ff
/* TxBD status field bits */ /* TxBD status field bits */
#define TXBD_READY 0x8000 #define TXBD_READY 0x8000
...@@ -374,8 +376,13 @@ extern const char gfar_driver_version[]; ...@@ -374,8 +376,13 @@ extern const char gfar_driver_version[];
struct txbd8 struct txbd8
{ {
u16 status; /* Status Fields */ union {
u16 length; /* Buffer length */ struct {
u16 status; /* Status Fields */
u16 length; /* Buffer length */
};
u32 lstatus;
};
u32 bufPtr; /* Buffer Pointer */ u32 bufPtr; /* Buffer Pointer */
}; };
...@@ -390,8 +397,13 @@ struct txfcb { ...@@ -390,8 +397,13 @@ struct txfcb {
struct rxbd8 struct rxbd8
{ {
u16 status; /* Status Fields */ union {
u16 length; /* Buffer Length */ struct {
u16 status; /* Status Fields */
u16 length; /* Buffer Length */
};
u32 lstatus;
};
u32 bufPtr; /* Buffer Pointer */ u32 bufPtr; /* Buffer Pointer */
}; };
......
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