Commit c097cc92 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by David S. Miller

s390/qeth: consolidate skb RX processing in L3 driver

Use napi_gro_receive() to pass up all types of packets that a L3 device
may receive.
1) For proper L2 packets received by the IQD sniffer, this is the
   obvious thing to do.
2) For af_iucv (which doesn't provide a GRO assist), the GRO code will
   transparently fall back to netif_receive_skb(). So there's no need to
   special-case this traffic in our code.
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c4733c32
...@@ -1312,6 +1312,15 @@ static int qeth_l3_vlan_rx_kill_vid(struct net_device *dev, ...@@ -1312,6 +1312,15 @@ static int qeth_l3_vlan_rx_kill_vid(struct net_device *dev,
static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
struct qeth_hdr *hdr) struct qeth_hdr *hdr)
{ {
struct af_iucv_trans_hdr *iucv = (struct af_iucv_trans_hdr *) skb->data;
struct net_device *dev = skb->dev;
if (IS_IQD(card) && iucv->magic == ETH_P_AF_IUCV) {
dev_hard_header(skb, dev, ETH_P_AF_IUCV, dev->dev_addr,
"FAKELL", skb->len);
return;
}
if (!(hdr->hdr.l3.flags & QETH_HDR_PASSTHRU)) { if (!(hdr->hdr.l3.flags & QETH_HDR_PASSTHRU)) {
u16 prot = (hdr->hdr.l3.flags & QETH_HDR_IPV6) ? ETH_P_IPV6 : u16 prot = (hdr->hdr.l3.flags & QETH_HDR_IPV6) ? ETH_P_IPV6 :
ETH_P_IP; ETH_P_IP;
...@@ -1345,8 +1354,6 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, ...@@ -1345,8 +1354,6 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
tg_addr, "FAKELL", skb->len); tg_addr, "FAKELL", skb->len);
} }
skb->protocol = eth_type_trans(skb, card->dev);
/* copy VLAN tag from hdr into skb */ /* copy VLAN tag from hdr into skb */
if (!card->options.sniffer && if (!card->options.sniffer &&
(hdr->hdr.l3.ext_flags & (QETH_HDR_EXT_VLAN_FRAME | (hdr->hdr.l3.ext_flags & (QETH_HDR_EXT_VLAN_FRAME |
...@@ -1363,12 +1370,10 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, ...@@ -1363,12 +1370,10 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
static int qeth_l3_process_inbound_buffer(struct qeth_card *card, static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
int budget, int *done) int budget, int *done)
{ {
struct net_device *dev = card->dev;
int work_done = 0; int work_done = 0;
struct sk_buff *skb; struct sk_buff *skb;
struct qeth_hdr *hdr; struct qeth_hdr *hdr;
unsigned int len; unsigned int len;
__u16 magic;
*done = 0; *done = 0;
WARN_ON_ONCE(!budget); WARN_ON_ONCE(!budget);
...@@ -1382,23 +1387,12 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card, ...@@ -1382,23 +1387,12 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
} }
switch (hdr->hdr.l3.id) { switch (hdr->hdr.l3.id) {
case QETH_HEADER_TYPE_LAYER3: case QETH_HEADER_TYPE_LAYER3:
magic = *(__u16 *)skb->data; qeth_l3_rebuild_skb(card, skb, hdr);
if (IS_IQD(card) && magic == ETH_P_AF_IUCV) { /* fall through */
len = skb->len;
dev_hard_header(skb, dev, ETH_P_AF_IUCV,
dev->dev_addr, "FAKELL", len);
skb->protocol = eth_type_trans(skb, dev);
netif_receive_skb(skb);
} else {
qeth_l3_rebuild_skb(card, skb, hdr);
len = skb->len;
napi_gro_receive(&card->napi, skb);
}
break;
case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */ case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
skb->protocol = eth_type_trans(skb, skb->dev); skb->protocol = eth_type_trans(skb, skb->dev);
len = skb->len; len = skb->len;
netif_receive_skb(skb); napi_gro_receive(&card->napi, skb);
break; break;
default: default:
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment