diff options
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 57914050b098..3263f50bc52e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -126,6 +126,9 @@ | |||
126 | TG3_TX_RING_SIZE) | 126 | TG3_TX_RING_SIZE) |
127 | #define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) | 127 | #define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) |
128 | 128 | ||
129 | #define TG3_RX_DMA_ALIGN 16 | ||
130 | #define TG3_RX_HEADROOM ALIGN(VLAN_HLEN, TG3_RX_DMA_ALIGN) | ||
131 | |||
129 | #define TG3_DMA_BYTE_ENAB 64 | 132 | #define TG3_DMA_BYTE_ENAB 64 |
130 | 133 | ||
131 | #define TG3_RX_STD_DMA_SZ 1536 | 134 | #define TG3_RX_STD_DMA_SZ 1536 |
@@ -4624,6 +4627,8 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
4624 | struct sk_buff *skb; | 4627 | struct sk_buff *skb; |
4625 | dma_addr_t dma_addr; | 4628 | dma_addr_t dma_addr; |
4626 | u32 opaque_key, desc_idx, *post_ptr; | 4629 | u32 opaque_key, desc_idx, *post_ptr; |
4630 | bool hw_vlan __maybe_unused = false; | ||
4631 | u16 vtag __maybe_unused = 0; | ||
4627 | 4632 | ||
4628 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; | 4633 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; |
4629 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; | 4634 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; |
@@ -4682,12 +4687,12 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
4682 | tg3_recycle_rx(tnapi, tpr, opaque_key, | 4687 | tg3_recycle_rx(tnapi, tpr, opaque_key, |
4683 | desc_idx, *post_ptr); | 4688 | desc_idx, *post_ptr); |
4684 | 4689 | ||
4685 | copy_skb = netdev_alloc_skb(tp->dev, | 4690 | copy_skb = netdev_alloc_skb(tp->dev, len + VLAN_HLEN + |
4686 | len + TG3_RAW_IP_ALIGN); | 4691 | TG3_RAW_IP_ALIGN); |
4687 | if (copy_skb == NULL) | 4692 | if (copy_skb == NULL) |
4688 | goto drop_it_no_recycle; | 4693 | goto drop_it_no_recycle; |
4689 | 4694 | ||
4690 | skb_reserve(copy_skb, TG3_RAW_IP_ALIGN); | 4695 | skb_reserve(copy_skb, TG3_RAW_IP_ALIGN + VLAN_HLEN); |
4691 | skb_put(copy_skb, len); | 4696 | skb_put(copy_skb, len); |
4692 | pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); | 4697 | pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); |
4693 | skb_copy_from_linear_data(skb, copy_skb->data, len); | 4698 | skb_copy_from_linear_data(skb, copy_skb->data, len); |
@@ -4713,12 +4718,29 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
4713 | goto next_pkt; | 4718 | goto next_pkt; |
4714 | } | 4719 | } |
4715 | 4720 | ||
4721 | if (desc->type_flags & RXD_FLAG_VLAN && | ||
4722 | !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG)) { | ||
4723 | vtag = desc->err_vlan & RXD_VLAN_MASK; | ||
4716 | #if TG3_VLAN_TAG_USED | 4724 | #if TG3_VLAN_TAG_USED |
4717 | if (tp->vlgrp != NULL && | 4725 | if (tp->vlgrp) |
4718 | desc->type_flags & RXD_FLAG_VLAN) { | 4726 | hw_vlan = true; |
4719 | vlan_gro_receive(&tnapi->napi, tp->vlgrp, | 4727 | else |
4720 | desc->err_vlan & RXD_VLAN_MASK, skb); | 4728 | #endif |
4721 | } else | 4729 | { |
4730 | struct vlan_ethhdr *ve = (struct vlan_ethhdr *) | ||
4731 | __skb_push(skb, VLAN_HLEN); | ||
4732 | |||
4733 | memmove(ve, skb->data + VLAN_HLEN, | ||
4734 | ETH_ALEN * 2); | ||
4735 | ve->h_vlan_proto = htons(ETH_P_8021Q); | ||
4736 | ve->h_vlan_TCI = htons(vtag); | ||
4737 | } | ||
4738 | } | ||
4739 | |||
4740 | #if TG3_VLAN_TAG_USED | ||
4741 | if (hw_vlan) | ||
4742 | vlan_gro_receive(&tnapi->napi, tp->vlgrp, vtag, skb); | ||
4743 | else | ||
4722 | #endif | 4744 | #endif |
4723 | napi_gro_receive(&tnapi->napi, skb); | 4745 | napi_gro_receive(&tnapi->napi, skb); |
4724 | 4746 | ||
@@ -13481,13 +13503,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
13481 | else | 13503 | else |
13482 | tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; | 13504 | tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; |
13483 | 13505 | ||
13484 | tp->rx_offset = NET_IP_ALIGN; | 13506 | tp->rx_offset = NET_IP_ALIGN + TG3_RX_HEADROOM; |
13485 | tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD; | 13507 | tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD; |
13486 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && | 13508 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && |
13487 | (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) { | 13509 | (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) { |
13488 | tp->rx_offset = 0; | 13510 | tp->rx_offset -= NET_IP_ALIGN; |
13489 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS | 13511 | #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS |
13490 | tp->rx_copy_thresh = ~0; | 13512 | tp->rx_copy_thresh = ~(u16)0; |
13491 | #endif | 13513 | #endif |
13492 | } | 13514 | } |
13493 | 13515 | ||