Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 66902
b: refs/heads/master
c: ad5da10
h: refs/heads/master
v: v3
  • Loading branch information
Olof Johansson authored and David S. Miller committed Oct 10, 2007
1 parent 2a0d8eb commit 69c902b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 46 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8dc121a4b620090e594945fd36f878836fc5a14a
refs/heads/master: ad5da10a64bdca1ed39b25946727a1ce2659f3d4
92 changes: 47 additions & 45 deletions trunk/drivers/net/pasemi_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@


/* Must be a power of two */
#define RX_RING_SIZE 512
#define TX_RING_SIZE 512
#define RX_RING_SIZE 4096
#define TX_RING_SIZE 4096

#define DEFAULT_MSG_ENABLE \
(NETIF_MSG_DRV | \
Expand Down Expand Up @@ -336,8 +336,16 @@ static void pasemi_mac_free_tx_resources(struct net_device *dev)
struct pasemi_mac_buffer *info;
dma_addr_t dmas[MAX_SKB_FRAGS+1];
int freed;
int start, limit;

for (i = 0; i < TX_RING_SIZE; i += freed) {
start = mac->tx->next_to_clean;
limit = mac->tx->next_to_fill;

/* Compensate for when fill has wrapped and clean has not */
if (start > limit)
limit += TX_RING_SIZE;

for (i = start; i < limit; i += freed) {
info = &TX_RING_INFO(mac, i+1);
if (info->dma && info->skb) {
for (j = 0; j <= skb_shinfo(info->skb)->nr_frags; j++)
Expand Down Expand Up @@ -520,9 +528,6 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
n = mac->rx->next_to_clean;

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

rmb();

macrx = RX_RING(mac, n);

if ((macrx & XCT_MACRX_E) ||
Expand Down Expand Up @@ -550,14 +555,10 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
break;
}

prefetchw(info);

skb = info->skb;
prefetchw(skb);
info->dma = 0;

pci_unmap_single(mac->dma_pdev, dma, skb->len,
PCI_DMA_FROMDEVICE);
prefetch(skb);
prefetch(&skb->data_len);

len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;

Expand All @@ -576,10 +577,9 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
} else
info->skb = NULL;

/* Need to zero it out since hardware doesn't, since the
* replenish loop uses it to tell when it's done.
*/
RX_BUFF(mac, i) = 0;
pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE);

info->dma = 0;

skb_put(skb, len);

Expand All @@ -599,6 +599,11 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
RX_RING(mac, n) = 0;
RX_RING(mac, n+1) = 0;

/* Need to zero it out since hardware doesn't, since the
* replenish loop uses it to tell when it's done.
*/
RX_BUFF(mac, i) = 0;

n += 2;
}

Expand All @@ -621,27 +626,33 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
{
int i, j;
struct pasemi_mac_buffer *info;
unsigned int start, descr_count, buf_count, limit;
unsigned int start, descr_count, buf_count, batch_limit;
unsigned int ring_limit;
unsigned int total_count;
unsigned long flags;
struct sk_buff *skbs[TX_CLEAN_BATCHSIZE];
dma_addr_t dmas[TX_CLEAN_BATCHSIZE][MAX_SKB_FRAGS+1];

total_count = 0;
limit = TX_CLEAN_BATCHSIZE;
batch_limit = TX_CLEAN_BATCHSIZE;
restart:
spin_lock_irqsave(&mac->tx->lock, flags);

start = mac->tx->next_to_clean;
ring_limit = mac->tx->next_to_fill;

/* Compensate for when fill has wrapped but clean has not */
if (start > ring_limit)
ring_limit += TX_RING_SIZE;

buf_count = 0;
descr_count = 0;

for (i = start;
descr_count < limit && i < mac->tx->next_to_fill;
descr_count < batch_limit && i < ring_limit;
i += buf_count) {
u64 mactx = TX_RING(mac, i);
struct sk_buff *skb;

if ((mactx & XCT_MACTX_E) ||
(*mac->tx_status & PAS_STATUS_ERROR))
Expand All @@ -651,19 +662,15 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
/* Not yet transmitted */
break;

info = &TX_RING_INFO(mac, i+1);
skbs[descr_count] = info->skb;
skb = TX_RING_INFO(mac, i+1).skb;
skbs[descr_count] = skb;

buf_count = 2 + skb_shinfo(info->skb)->nr_frags;
for (j = 0; j <= skb_shinfo(info->skb)->nr_frags; j++)
buf_count = 2 + skb_shinfo(skb)->nr_frags;
for (j = 0; j <= skb_shinfo(skb)->nr_frags; j++)
dmas[descr_count][j] = TX_RING_INFO(mac, i+1+j).dma;


info->dma = 0;
TX_RING(mac, i) = 0;
TX_RING(mac, i+1) = 0;
TX_RING_INFO(mac, i+1).skb = 0;
TX_RING_INFO(mac, i+1).dma = 0;

/* Since we always fill with an even number of entries, make
* sure we skip any unused one at the end as well.
Expand All @@ -672,7 +679,7 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
buf_count++;
descr_count++;
}
mac->tx->next_to_clean = i;
mac->tx->next_to_clean = i & (TX_RING_SIZE-1);

spin_unlock_irqrestore(&mac->tx->lock, flags);
netif_wake_queue(mac->netdev);
Expand All @@ -683,7 +690,7 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
total_count += descr_count;

/* If the batch was full, try to clean more */
if (descr_count == limit)
if (descr_count == batch_limit)
goto restart;

return total_count;
Expand Down Expand Up @@ -1106,19 +1113,14 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)

spin_lock_irqsave(&txring->lock, flags);

if (RING_AVAIL(txring) <= nfrags+3) {
spin_unlock_irqrestore(&txring->lock, flags);
pasemi_mac_clean_tx(mac);
pasemi_mac_restart_tx_intr(mac);
spin_lock_irqsave(&txring->lock, flags);

if (RING_AVAIL(txring) <= nfrags+3) {
/* Still no room -- stop the queue and wait for tx
* intr when there's room.
*/
netif_stop_queue(dev);
goto out_err;
}
/* Avoid stepping on the same cache line that the DMA controller
* is currently about to send, so leave at least 8 words available.
* Total free space needed is mactx + fragments + 8
*/
if (RING_AVAIL(txring) < nfrags + 10) {
/* no room -- stop the queue and wait for tx intr */
netif_stop_queue(dev);
goto out_err;
}

TX_RING(mac, txring->next_to_fill) = mactx;
Expand All @@ -1137,8 +1139,8 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
if (nfrags & 1)
nfrags++;

txring->next_to_fill += nfrags + 1;

txring->next_to_fill = (txring->next_to_fill + nfrags + 1) &
(TX_RING_SIZE-1);

dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
Expand Down

0 comments on commit 69c902b

Please sign in to comment.