Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 103503
b: refs/heads/master
c: bf36c1a
h: refs/heads/master
i:
  103501: 50aafb9
  103499: 02d7b1d
  103495: eb6f2c8
  103487: 010bb8e
v: v3
  • Loading branch information
Alexander Duyck authored and Jeff Garzik committed Jul 11, 2008
1 parent a8e9703 commit 3387b22
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 80 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: 7dfc16fab1186769d7d0086830ab3fbc8fddfcba
refs/heads/master: bf36c1a0040cc6ccd63cdd1cec25d2085f2df964
4 changes: 1 addition & 3 deletions trunk/drivers/net/igb/igb.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ struct igb_buffer {
struct {
struct page *page;
u64 page_dma;
unsigned int page_offset;
};
};
};
Expand Down Expand Up @@ -163,9 +164,6 @@ struct igb_ring {
};
/* RX */
struct {
/* arrays of page information for packet split */
struct sk_buff *pending_skb;
int pending_skb_page;
int no_itr_adjust;
struct igb_queue_stats rx_stats;
struct napi_struct napi;
Expand Down
138 changes: 62 additions & 76 deletions trunk/drivers/net/igb/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1725,7 +1725,6 @@ int igb_setup_rx_resources(struct igb_adapter *adapter,

rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
rx_ring->pending_skb = NULL;

rx_ring->adapter = adapter;

Expand Down Expand Up @@ -1817,15 +1816,6 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
rctl |= E1000_RCTL_SZ_2048;
rctl &= ~E1000_RCTL_BSEX;
break;
case IGB_RXBUFFER_4096:
rctl |= E1000_RCTL_SZ_4096;
break;
case IGB_RXBUFFER_8192:
rctl |= E1000_RCTL_SZ_8192;
break;
case IGB_RXBUFFER_16384:
rctl |= E1000_RCTL_SZ_16384;
break;
}
} else {
rctl &= ~E1000_RCTL_BSEX;
Expand All @@ -1843,10 +1833,8 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
* so only enable packet split for jumbo frames */
if (rctl & E1000_RCTL_LPE) {
adapter->rx_ps_hdr_size = IGB_RXBUFFER_128;
srrctl = adapter->rx_ps_hdr_size <<
srrctl |= adapter->rx_ps_hdr_size <<
E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
/* buffer size is ALWAYS one page */
srrctl |= PAGE_SIZE >> E1000_SRRCTL_BSIZEPKT_SHIFT;
srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
} else {
adapter->rx_ps_hdr_size = 0;
Expand Down Expand Up @@ -2151,20 +2139,17 @@ static void igb_clean_rx_ring(struct igb_ring *rx_ring)
buffer_info->skb = NULL;
}
if (buffer_info->page) {
pci_unmap_page(pdev, buffer_info->page_dma,
PAGE_SIZE, PCI_DMA_FROMDEVICE);
if (buffer_info->page_dma)
pci_unmap_page(pdev, buffer_info->page_dma,
PAGE_SIZE / 2,
PCI_DMA_FROMDEVICE);
put_page(buffer_info->page);
buffer_info->page = NULL;
buffer_info->page_dma = 0;
buffer_info->page_offset = 0;
}
}

/* there also may be some cached data from a chained receive */
if (rx_ring->pending_skb) {
dev_kfree_skb(rx_ring->pending_skb);
rx_ring->pending_skb = NULL;
}

size = sizeof(struct igb_buffer) * rx_ring->count;
memset(rx_ring->buffer_info, 0, size);

Expand Down Expand Up @@ -3091,7 +3076,11 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
else if (max_frame <= IGB_RXBUFFER_2048)
adapter->rx_buffer_len = IGB_RXBUFFER_2048;
else
adapter->rx_buffer_len = IGB_RXBUFFER_4096;
#if (PAGE_SIZE / 2) > IGB_RXBUFFER_16384
adapter->rx_buffer_len = IGB_RXBUFFER_16384;
#else
adapter->rx_buffer_len = PAGE_SIZE / 2;
#endif
/* adjust allocation if LPE protects us, and we aren't using SBP */
if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
(max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))
Expand Down Expand Up @@ -3796,7 +3785,7 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
union e1000_adv_rx_desc *rx_desc , *next_rxd;
struct igb_buffer *buffer_info , *next_buffer;
struct sk_buff *skb;
unsigned int i, j;
unsigned int i;
u32 length, hlen, staterr;
bool cleaned = false;
int cleaned_count = 0;
Expand Down Expand Up @@ -3826,61 +3815,46 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
cleaned = true;
cleaned_count++;

if (rx_ring->pending_skb != NULL) {
skb = rx_ring->pending_skb;
rx_ring->pending_skb = NULL;
j = rx_ring->pending_skb_page;
} else {
skb = buffer_info->skb;
prefetch(skb->data - NET_IP_ALIGN);
buffer_info->skb = NULL;
if (hlen) {
pci_unmap_single(pdev, buffer_info->dma,
adapter->rx_ps_hdr_size +
NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
skb_put(skb, hlen);
} else {
pci_unmap_single(pdev, buffer_info->dma,
adapter->rx_buffer_len +
NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
skb_put(skb, length);
goto send_up;
}
j = 0;
skb = buffer_info->skb;
prefetch(skb->data - NET_IP_ALIGN);
buffer_info->skb = NULL;
if (!adapter->rx_ps_hdr_size) {
pci_unmap_single(pdev, buffer_info->dma,
adapter->rx_buffer_len +
NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
skb_put(skb, length);
goto send_up;
}

if (!skb_shinfo(skb)->nr_frags) {
pci_unmap_single(pdev, buffer_info->dma,
adapter->rx_ps_hdr_size +
NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
skb_put(skb, hlen);
}

while (length) {
if (length) {
pci_unmap_page(pdev, buffer_info->page_dma,
PAGE_SIZE, PCI_DMA_FROMDEVICE);
PAGE_SIZE / 2, PCI_DMA_FROMDEVICE);
buffer_info->page_dma = 0;
skb_fill_page_desc(skb, j, buffer_info->page,
0, length);
buffer_info->page = NULL;

skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags++,
buffer_info->page,
buffer_info->page_offset,
length);

if ((adapter->rx_buffer_len > (PAGE_SIZE / 2)) ||
(page_count(buffer_info->page) != 1))
buffer_info->page = NULL;
else
get_page(buffer_info->page);

skb->len += length;
skb->data_len += length;
skb->truesize += length;
rx_desc->wb.upper.status_error = 0;
if (staterr & E1000_RXD_STAT_EOP)
break;

j++;
cleaned_count++;
i++;
if (i == rx_ring->count)
i = 0;

buffer_info = &rx_ring->buffer_info[i];
rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
length = le16_to_cpu(rx_desc->wb.upper.length);
if (!(staterr & E1000_RXD_STAT_DD)) {
rx_ring->pending_skb = skb;
rx_ring->pending_skb_page = j;
goto out;
}
skb->truesize += length;
}
send_up:
i++;
Expand All @@ -3890,6 +3864,12 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
prefetch(next_rxd);
next_buffer = &rx_ring->buffer_info[i];

if (!(staterr & E1000_RXD_STAT_EOP)) {
buffer_info->skb = xchg(&next_buffer->skb, skb);
buffer_info->dma = xchg(&next_buffer->dma, 0);
goto next_desc;
}

if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
dev_kfree_skb_irq(skb);
goto next_desc;
Expand Down Expand Up @@ -3922,7 +3902,7 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,

staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
}
out:

rx_ring->next_to_clean = i;
cleaned_count = IGB_DESC_UNUSED(rx_ring);

Expand Down Expand Up @@ -3960,16 +3940,22 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
while (cleaned_count--) {
rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);

if (adapter->rx_ps_hdr_size && !buffer_info->page) {
buffer_info->page = alloc_page(GFP_ATOMIC);
if (adapter->rx_ps_hdr_size && !buffer_info->page_dma) {
if (!buffer_info->page) {
adapter->alloc_rx_buff_failed++;
goto no_buffers;
buffer_info->page = alloc_page(GFP_ATOMIC);
if (!buffer_info->page) {
adapter->alloc_rx_buff_failed++;
goto no_buffers;
}
buffer_info->page_offset = 0;
} else {
buffer_info->page_offset ^= PAGE_SIZE / 2;
}
buffer_info->page_dma =
pci_map_page(pdev,
buffer_info->page,
0, PAGE_SIZE,
buffer_info->page_offset,
PAGE_SIZE / 2,
PCI_DMA_FROMDEVICE);
}

Expand Down

0 comments on commit 3387b22

Please sign in to comment.