diff options
-rw-r--r-- | drivers/net/gianfar.c | 27 | ||||
-rw-r--r-- | drivers/net/gianfar.h | 6 |
2 files changed, 15 insertions, 18 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 40756dc68a10..e7e8201283a3 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 */ |
1471 | static int gfar_clean_tx_ring(struct net_device *dev) | 1467 | static 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 | */ |
1713 | int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) | 1706 | int 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 1bdb50c7936e..1ebf7ac27a3d 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 |