Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd4ceb24 authored by Olof Johansson's avatar Olof Johansson Committed by Jeff Garzik
Browse files

pasemi_mac: Logic cleanup / rx performance improvements



Logic cleanup and some performance enhancements to the RX path.

Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent cfa8007d
Loading
Loading
Loading
Loading
+37 −38
Original line number Diff line number Diff line
@@ -305,19 +305,20 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
	struct pasemi_mac *mac = netdev_priv(dev);
	unsigned int i;
	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);

	/* Check to see if we're doing first-time setup */
	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;

	for (i = start; i < start + count; i++) {
	i = start;
	for (count = limit; count; count--) {
		struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i);
		u64 *buff = &RX_BUFF(mac, i);
		struct sk_buff *skb;
@@ -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,
				     PCI_DMA_FROMDEVICE);

		if (dma_mapping_error(dma)) {
		if (unlikely(dma_mapping_error(dma))) {
			dev_kfree_skb_irq(info->skb);
			count = i - start;
			break;
		}

		info->skb = skb;
		info->dma = dma;
		*buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma);
		i++;
	}

	wmb();

	pci_write_config_dword(mac->dma_pdev,
			       PAS_DMA_RXCHAN_INCR(mac->dma_rxch),
			       count);
			       limit - count);
	pci_write_config_dword(mac->dma_pdev,
			       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)
@@ -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)
{
	unsigned int i;
	int start, count;

	spin_lock(&mac->rx->lock);

	start = mac->rx->next_to_clean;
	count = 0;

	for (i = start; i < (start + RX_RING_SIZE) && count < limit; i++) {
	unsigned int n;
	int count;
	struct pas_dma_xct_descr *dp;
	struct pasemi_mac_buffer *info;
	struct sk_buff *skb;
		unsigned int j, len;
	unsigned int i, len;
	u64 macrx;
	dma_addr_t dma;

	spin_lock(&mac->rx->lock);

	n = mac->rx->next_to_clean;

	for (count = limit; count; count--) {

		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;

		count++;

		info = NULL;

@@ -430,22 +430,20 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
		 */

		dma = (dp->ptr & XCT_PTR_ADDR_M);
		for (j = start; j < (start + RX_RING_SIZE); j++) {
			info = &RX_DESC_INFO(mac, j);
		for (i = n; i < (n + RX_RING_SIZE); i++) {
			info = &RX_DESC_INFO(mac, i);
			if (info->dma == dma)
				break;
		}

		BUG_ON(!info);
		BUG_ON(info->dma != dma);
		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);
		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) {
			struct sk_buff *new_skb =
			    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)

		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->csum = (dp->macrx & XCT_MACRX_CSUM_M) >>
			skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
					   XCT_MACRX_CSUM_S;
		} else
			skb->ip_summed = CHECKSUM_NONE;
@@ -477,13 +475,13 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)

		netif_receive_skb(skb);

		info->dma = 0;
		info->skb = NULL;
		dp->ptr = 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);

	spin_unlock(&mac->rx->lock);
@@ -899,6 +897,9 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget)

	pkts = pasemi_mac_clean_rx(mac, limit);

	dev->quota -= pkts;
	*budget -= pkts;

	if (pkts < limit) {
		/* all done, no more packets present */
		netif_rx_complete(dev);
@@ -907,8 +908,6 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget)
		return 0;
	} else {
		/* used up our quantum, so reschedule */
		dev->quota -= pkts;
		*budget -= pkts;
		return 1;
	}
}