aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/gianfar.c27
-rw-r--r--drivers/net/gianfar.h6
2 files changed, 15 insertions, 18 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 40756dc68a1..e7e8201283a 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1215,7 +1215,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
1215{ 1215{
1216 struct gfar_private *priv = netdev_priv(dev); 1216 struct gfar_private *priv = netdev_priv(dev);
1217 struct txfcb *fcb = NULL; 1217 struct txfcb *fcb = NULL;
1218 struct txbd8 *txbdp; 1218 struct txbd8 *txbdp, *base;
1219 u16 status; 1219 u16 status;
1220 unsigned long flags; 1220 unsigned long flags;
1221 1221
@@ -1227,6 +1227,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
1227 1227
1228 /* Point at the first free tx descriptor */ 1228 /* Point at the first free tx descriptor */
1229 txbdp = priv->cur_tx; 1229 txbdp = priv->cur_tx;
1230 base = priv->tx_bd_base;
1230 1231
1231 /* Clear all but the WRAP status flags */ 1232 /* Clear all but the WRAP status flags */
1232 status = txbdp->status & TXBD_WRAP; 1233 status = txbdp->status & TXBD_WRAP;
@@ -1279,12 +1280,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
1279 eieio(); 1280 eieio();
1280 txbdp->status = status; 1281 txbdp->status = status;
1281 1282
1282 /* If this was the last BD in the ring, the next one */ 1283 txbdp = next_bd(txbdp, base, priv->tx_ring_size);
1283 /* is at the beginning of the ring */
1284 if (txbdp->status & TXBD_WRAP)
1285 txbdp = priv->tx_bd_base;
1286 else
1287 txbdp++;
1288 1284
1289 /* If the next BD still needs to be cleaned up, then the bds 1285 /* If the next BD still needs to be cleaned up, then the bds
1290 are full. We need to tell the kernel to stop sending us stuff. */ 1286 are full. We need to tell the kernel to stop sending us stuff. */
@@ -1470,11 +1466,12 @@ static void gfar_timeout(struct net_device *dev)
1470/* Interrupt Handler for Transmit complete */ 1466/* Interrupt Handler for Transmit complete */
1471static int gfar_clean_tx_ring(struct net_device *dev) 1467static int gfar_clean_tx_ring(struct net_device *dev)
1472{ 1468{
1473 struct txbd8 *bdp; 1469 struct txbd8 *bdp, *base;
1474 struct gfar_private *priv = netdev_priv(dev); 1470 struct gfar_private *priv = netdev_priv(dev);
1475 int howmany = 0; 1471 int howmany = 0;
1476 1472
1477 bdp = priv->dirty_tx; 1473 bdp = priv->dirty_tx;
1474 base = priv->tx_bd_base;
1478 while ((bdp->status & TXBD_READY) == 0) { 1475 while ((bdp->status & TXBD_READY) == 0) {
1479 /* If dirty_tx and cur_tx are the same, then either the */ 1476 /* If dirty_tx and cur_tx are the same, then either the */
1480 /* ring is empty or full now (it could only be full in the beginning, */ 1477 /* ring is empty or full now (it could only be full in the beginning, */
@@ -1504,11 +1501,7 @@ static int gfar_clean_tx_ring(struct net_device *dev)
1504 /* Clean BD length for empty detection */ 1501 /* Clean BD length for empty detection */
1505 bdp->length = 0; 1502 bdp->length = 0;
1506 1503
1507 /* update bdp to point at next bd in the ring (wrapping if necessary) */ 1504 bdp = next_bd(bdp, base, priv->tx_ring_size);
1508 if (bdp->status & TXBD_WRAP)
1509 bdp = priv->tx_bd_base;
1510 else
1511 bdp++;
1512 1505
1513 /* Move dirty_tx to be the next bd */ 1506 /* Move dirty_tx to be the next bd */
1514 priv->dirty_tx = bdp; 1507 priv->dirty_tx = bdp;
@@ -1712,7 +1705,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
1712 */ 1705 */
1713int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) 1706int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
1714{ 1707{
1715 struct rxbd8 *bdp; 1708 struct rxbd8 *bdp, *base;
1716 struct sk_buff *skb; 1709 struct sk_buff *skb;
1717 int pkt_len; 1710 int pkt_len;
1718 int amount_pull; 1711 int amount_pull;
@@ -1721,6 +1714,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
1721 1714
1722 /* Get the first full descriptor */ 1715 /* Get the first full descriptor */
1723 bdp = priv->cur_rx; 1716 bdp = priv->cur_rx;
1717 base = priv->rx_bd_base;
1724 1718
1725 amount_pull = (gfar_uses_fcb(priv) ? GMAC_FCB_LEN : 0) + 1719 amount_pull = (gfar_uses_fcb(priv) ? GMAC_FCB_LEN : 0) +
1726 priv->padding; 1720 priv->padding;
@@ -1776,10 +1770,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
1776 gfar_new_rxbdp(dev, bdp, newskb); 1770 gfar_new_rxbdp(dev, bdp, newskb);
1777 1771
1778 /* Update to the next pointer */ 1772 /* Update to the next pointer */
1779 if (bdp->status & RXBD_WRAP) 1773 bdp = next_bd(bdp, base, priv->rx_ring_size);
1780 bdp = priv->rx_bd_base;
1781 else
1782 bdp++;
1783 1774
1784 /* update to point at the next skb */ 1775 /* update to point at the next skb */
1785 priv->skb_currx = 1776 priv->skb_currx =
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 1bdb50c7936..1ebf7ac27a3 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -196,6 +196,12 @@ extern const char gfar_driver_version[];
196#define DEFAULT_TXIC mk_ic_value(DEFAULT_TXCOUNT, DEFAULT_TXTIME) 196#define DEFAULT_TXIC mk_ic_value(DEFAULT_TXCOUNT, DEFAULT_TXTIME)
197#define DEFAULT_RXIC mk_ic_value(DEFAULT_RXCOUNT, DEFAULT_RXTIME) 197#define DEFAULT_RXIC mk_ic_value(DEFAULT_RXCOUNT, DEFAULT_RXTIME)
198 198
199#define skip_bd(bdp, stride, base, ring_size) ({ \
200 typeof(bdp) new_bd = (bdp) + (stride); \
201 (new_bd >= (base) + (ring_size)) ? (new_bd - (ring_size)) : new_bd; })
202
203#define next_bd(bdp, base, ring_size) skip_bd(bdp, 1, base, ring_size)
204
199#define RCTRL_PAL_MASK 0x001f0000 205#define RCTRL_PAL_MASK 0x001f0000
200#define RCTRL_VLEX 0x00002000 206#define RCTRL_VLEX 0x00002000
201#define RCTRL_FILREN 0x00001000 207#define RCTRL_FILREN 0x00001000