提交 cd4ceb24 编写于 作者: O Olof Johansson 提交者: Jeff Garzik

pasemi_mac: Logic cleanup / rx performance improvements

Logic cleanup and some performance enhancements to the RX path.
Signed-off-by: NOlof Johansson <olof@lixom.net>
Signed-off-by: NJeff Garzik <jeff@garzik.org>
上级 cfa8007d
...@@ -305,19 +305,20 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev) ...@@ -305,19 +305,20 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
struct pasemi_mac *mac = netdev_priv(dev); struct pasemi_mac *mac = netdev_priv(dev);
unsigned int i; unsigned int i;
int start = mac->rx->next_to_fill; int start = mac->rx->next_to_fill;
unsigned int count; unsigned int limit, count;
count = (mac->rx->next_to_clean + RX_RING_SIZE - limit = (mac->rx->next_to_clean + RX_RING_SIZE -
mac->rx->next_to_fill) & (RX_RING_SIZE - 1); mac->rx->next_to_fill) & (RX_RING_SIZE - 1);
/* Check to see if we're doing first-time setup */ /* Check to see if we're doing first-time setup */
if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0)) if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0))
count = RX_RING_SIZE; limit = RX_RING_SIZE;
if (count <= 0) if (limit <= 0)
return; return;
for (i = start; i < start + count; i++) { i = start;
for (count = limit; count; count--) {
struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i); struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i);
u64 *buff = &RX_BUFF(mac, i); u64 *buff = &RX_BUFF(mac, i);
struct sk_buff *skb; struct sk_buff *skb;
...@@ -335,27 +336,27 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev) ...@@ -335,27 +336,27 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
dma = pci_map_single(mac->dma_pdev, skb->data, skb->len, dma = pci_map_single(mac->dma_pdev, skb->data, skb->len,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
if (dma_mapping_error(dma)) { if (unlikely(dma_mapping_error(dma))) {
dev_kfree_skb_irq(info->skb); dev_kfree_skb_irq(info->skb);
count = i - start;
break; break;
} }
info->skb = skb; info->skb = skb;
info->dma = dma; info->dma = dma;
*buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma); *buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma);
i++;
} }
wmb(); wmb();
pci_write_config_dword(mac->dma_pdev, pci_write_config_dword(mac->dma_pdev,
PAS_DMA_RXCHAN_INCR(mac->dma_rxch), PAS_DMA_RXCHAN_INCR(mac->dma_rxch),
count); limit - count);
pci_write_config_dword(mac->dma_pdev, pci_write_config_dword(mac->dma_pdev,
PAS_DMA_RXINT_INCR(mac->dma_if), PAS_DMA_RXINT_INCR(mac->dma_if),
count); limit - count);
mac->rx->next_to_fill += count; mac->rx->next_to_fill += limit - count;
} }
static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
...@@ -393,32 +394,31 @@ static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac) ...@@ -393,32 +394,31 @@ static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac)
} }
static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
{ {
unsigned int i; unsigned int n;
int start, count; int count;
struct pas_dma_xct_descr *dp;
struct pasemi_mac_buffer *info;
struct sk_buff *skb;
unsigned int i, len;
u64 macrx;
dma_addr_t dma;
spin_lock(&mac->rx->lock); spin_lock(&mac->rx->lock);
start = mac->rx->next_to_clean; n = mac->rx->next_to_clean;
count = 0;
for (i = start; i < (start + RX_RING_SIZE) && count < limit; i++) { for (count = limit; count; count--) {
struct pas_dma_xct_descr *dp;
struct pasemi_mac_buffer *info;
struct sk_buff *skb;
unsigned int j, len;
dma_addr_t dma;
rmb(); rmb();
dp = &RX_DESC(mac, i); dp = &RX_DESC(mac, n);
macrx = dp->macrx;
if (!(dp->macrx & XCT_MACRX_O)) if (!(macrx & XCT_MACRX_O))
break; break;
count++;
info = NULL; info = NULL;
...@@ -430,22 +430,20 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) ...@@ -430,22 +430,20 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
*/ */
dma = (dp->ptr & XCT_PTR_ADDR_M); dma = (dp->ptr & XCT_PTR_ADDR_M);
for (j = start; j < (start + RX_RING_SIZE); j++) { for (i = n; i < (n + RX_RING_SIZE); i++) {
info = &RX_DESC_INFO(mac, j); info = &RX_DESC_INFO(mac, i);
if (info->dma == dma) if (info->dma == dma)
break; break;
} }
BUG_ON(!info);
BUG_ON(info->dma != dma);
skb = info->skb; skb = info->skb;
info->dma = 0;
pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len, pci_unmap_single(mac->dma_pdev, dma, skb->len,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
info->dma = 0;
len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
if (len < 256) { if (len < 256) {
struct sk_buff *new_skb = struct sk_buff *new_skb =
netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN); netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN);
...@@ -465,9 +463,9 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) ...@@ -465,9 +463,9 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
skb->protocol = eth_type_trans(skb, mac->netdev); skb->protocol = eth_type_trans(skb, mac->netdev);
if ((dp->macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) { if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
skb->ip_summed = CHECKSUM_COMPLETE; skb->ip_summed = CHECKSUM_COMPLETE;
skb->csum = (dp->macrx & XCT_MACRX_CSUM_M) >> skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
XCT_MACRX_CSUM_S; XCT_MACRX_CSUM_S;
} else } else
skb->ip_summed = CHECKSUM_NONE; skb->ip_summed = CHECKSUM_NONE;
...@@ -477,13 +475,13 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) ...@@ -477,13 +475,13 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
netif_receive_skb(skb); netif_receive_skb(skb);
info->dma = 0;
info->skb = NULL;
dp->ptr = 0; dp->ptr = 0;
dp->macrx = 0; dp->macrx = 0;
n++;
} }
mac->rx->next_to_clean += count; mac->rx->next_to_clean += limit - count;
pasemi_mac_replenish_rx_ring(mac->netdev); pasemi_mac_replenish_rx_ring(mac->netdev);
spin_unlock(&mac->rx->lock); spin_unlock(&mac->rx->lock);
...@@ -899,6 +897,9 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget) ...@@ -899,6 +897,9 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget)
pkts = pasemi_mac_clean_rx(mac, limit); pkts = pasemi_mac_clean_rx(mac, limit);
dev->quota -= pkts;
*budget -= pkts;
if (pkts < limit) { if (pkts < limit) {
/* all done, no more packets present */ /* all done, no more packets present */
netif_rx_complete(dev); netif_rx_complete(dev);
...@@ -907,8 +908,6 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget) ...@@ -907,8 +908,6 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget)
return 0; return 0;
} else { } else {
/* used up our quantum, so reschedule */ /* used up our quantum, so reschedule */
dev->quota -= pkts;
*budget -= pkts;
return 1; return 1;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册