Skip to content

Commit 9dc7a11

Browse files
Matt Carlsondavem330
authored andcommitted
tg3: Re-inline VLAN tags when appropriate
The tg3 driver is written so that VLAN tagged packets can be accepted, even if CONFIG_VLAN_8021Q or CONFIG_VLAN_8021Q_MODULE is not defined. (Think raw interfaces.) If the device has ASF support enabled, the firmware requires the driver to enable VLAN tag stripping. If VLAN tagging is not explicitly supported by the kernel and ASF is enabled, the driver will have to reinject the VLAN tag back into the packet stream. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent d2757fc commit 9dc7a11

File tree

1 file changed

+33
-11
lines changed

1 file changed

+33
-11
lines changed

drivers/net/tg3.c

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@
126126
TG3_TX_RING_SIZE)
127127
#define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1))
128128

129+
#define TG3_RX_DMA_ALIGN 16
130+
#define TG3_RX_HEADROOM ALIGN(VLAN_HLEN, TG3_RX_DMA_ALIGN)
131+
129132
#define TG3_DMA_BYTE_ENAB 64
130133

131134
#define TG3_RX_STD_DMA_SZ 1536
@@ -4624,6 +4627,8 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
46244627
struct sk_buff *skb;
46254628
dma_addr_t dma_addr;
46264629
u32 opaque_key, desc_idx, *post_ptr;
4630+
bool hw_vlan __maybe_unused = false;
4631+
u16 vtag __maybe_unused = 0;
46274632

46284633
desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
46294634
opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
@@ -4682,12 +4687,12 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
46824687
tg3_recycle_rx(tnapi, tpr, opaque_key,
46834688
desc_idx, *post_ptr);
46844689

4685-
copy_skb = netdev_alloc_skb(tp->dev,
4686-
len + TG3_RAW_IP_ALIGN);
4690+
copy_skb = netdev_alloc_skb(tp->dev, len + VLAN_HLEN +
4691+
TG3_RAW_IP_ALIGN);
46874692
if (copy_skb == NULL)
46884693
goto drop_it_no_recycle;
46894694

4690-
skb_reserve(copy_skb, TG3_RAW_IP_ALIGN);
4695+
skb_reserve(copy_skb, TG3_RAW_IP_ALIGN + VLAN_HLEN);
46914696
skb_put(copy_skb, len);
46924697
pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
46934698
skb_copy_from_linear_data(skb, copy_skb->data, len);
@@ -4713,12 +4718,29 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
47134718
goto next_pkt;
47144719
}
47154720

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;
47164724
#if TG3_VLAN_TAG_USED
4717-
if (tp->vlgrp != NULL &&
4718-
desc->type_flags & RXD_FLAG_VLAN) {
4719-
vlan_gro_receive(&tnapi->napi, tp->vlgrp,
4720-
desc->err_vlan & RXD_VLAN_MASK, skb);
4721-
} else
4725+
if (tp->vlgrp)
4726+
hw_vlan = true;
4727+
else
4728+
#endif
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
47224744
#endif
47234745
napi_gro_receive(&tnapi->napi, skb);
47244746

@@ -13481,13 +13503,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
1348113503
else
1348213504
tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
1348313505

13484-
tp->rx_offset = NET_IP_ALIGN;
13506+
tp->rx_offset = NET_IP_ALIGN + TG3_RX_HEADROOM;
1348513507
tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD;
1348613508
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
1348713509
(tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) {
13488-
tp->rx_offset = 0;
13510+
tp->rx_offset -= NET_IP_ALIGN;
1348913511
#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
13490-
tp->rx_copy_thresh = ~0;
13512+
tp->rx_copy_thresh = ~(u16)0;
1349113513
#endif
1349213514
}
1349313515

0 commit comments

Comments
 (0)