|
@@ -142,7 +142,7 @@ static int max_required_rx_slots(struct xenvif *vif)
|
|
|
int max = DIV_ROUND_UP(vif->dev->mtu, PAGE_SIZE);
|
|
|
|
|
|
/* XXX FIXME: RX path dependent on MAX_SKB_FRAGS */
|
|
|
- if (vif->can_sg || vif->gso || vif->gso_prefix)
|
|
|
+ if (vif->can_sg || vif->gso_mask || vif->gso_prefix_mask)
|
|
|
max += MAX_SKB_FRAGS + 1; /* extra_info + frags */
|
|
|
|
|
|
return max;
|
|
@@ -314,6 +314,7 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif *vif,
|
|
|
req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++);
|
|
|
|
|
|
meta = npo->meta + npo->meta_prod++;
|
|
|
+ meta->gso_type = XEN_NETIF_GSO_TYPE_NONE;
|
|
|
meta->gso_size = 0;
|
|
|
meta->size = 0;
|
|
|
meta->id = req->id;
|
|
@@ -336,6 +337,7 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb,
|
|
|
struct gnttab_copy *copy_gop;
|
|
|
struct xenvif_rx_meta *meta;
|
|
|
unsigned long bytes;
|
|
|
+ int gso_type;
|
|
|
|
|
|
/* Data must not cross a page boundary. */
|
|
|
BUG_ON(size + offset > PAGE_SIZE<<compound_order(page));
|
|
@@ -394,7 +396,14 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb,
|
|
|
}
|
|
|
|
|
|
/* Leave a gap for the GSO descriptor. */
|
|
|
- if (*head && skb_shinfo(skb)->gso_size && !vif->gso_prefix)
|
|
|
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
|
|
|
+ gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
|
|
|
+ else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
|
|
|
+ gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
|
|
|
+ else
|
|
|
+ gso_type = XEN_NETIF_GSO_TYPE_NONE;
|
|
|
+
|
|
|
+ if (*head && ((1 << gso_type) & vif->gso_mask))
|
|
|
vif->rx.req_cons++;
|
|
|
|
|
|
*head = 0; /* There must be something in this buffer now. */
|
|
@@ -425,14 +434,28 @@ static int xenvif_gop_skb(struct sk_buff *skb,
|
|
|
unsigned char *data;
|
|
|
int head = 1;
|
|
|
int old_meta_prod;
|
|
|
+ int gso_type;
|
|
|
+ int gso_size;
|
|
|
|
|
|
old_meta_prod = npo->meta_prod;
|
|
|
|
|
|
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) {
|
|
|
+ gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
|
|
|
+ gso_size = skb_shinfo(skb)->gso_size;
|
|
|
+ } else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) {
|
|
|
+ gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
|
|
|
+ gso_size = skb_shinfo(skb)->gso_size;
|
|
|
+ } else {
|
|
|
+ gso_type = XEN_NETIF_GSO_TYPE_NONE;
|
|
|
+ gso_size = 0;
|
|
|
+ }
|
|
|
+
|
|
|
/* Set up a GSO prefix descriptor, if necessary */
|
|
|
- if (skb_shinfo(skb)->gso_size && vif->gso_prefix) {
|
|
|
+ if ((1 << skb_shinfo(skb)->gso_type) & vif->gso_prefix_mask) {
|
|
|
req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++);
|
|
|
meta = npo->meta + npo->meta_prod++;
|
|
|
- meta->gso_size = skb_shinfo(skb)->gso_size;
|
|
|
+ meta->gso_type = gso_type;
|
|
|
+ meta->gso_size = gso_size;
|
|
|
meta->size = 0;
|
|
|
meta->id = req->id;
|
|
|
}
|
|
@@ -440,10 +463,13 @@ static int xenvif_gop_skb(struct sk_buff *skb,
|
|
|
req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++);
|
|
|
meta = npo->meta + npo->meta_prod++;
|
|
|
|
|
|
- if (!vif->gso_prefix)
|
|
|
- meta->gso_size = skb_shinfo(skb)->gso_size;
|
|
|
- else
|
|
|
+ if ((1 << gso_type) & vif->gso_mask) {
|
|
|
+ meta->gso_type = gso_type;
|
|
|
+ meta->gso_size = gso_size;
|
|
|
+ } else {
|
|
|
+ meta->gso_type = XEN_NETIF_GSO_TYPE_NONE;
|
|
|
meta->gso_size = 0;
|
|
|
+ }
|
|
|
|
|
|
meta->size = 0;
|
|
|
meta->id = req->id;
|
|
@@ -589,7 +615,8 @@ void xenvif_rx_action(struct xenvif *vif)
|
|
|
|
|
|
vif = netdev_priv(skb->dev);
|
|
|
|
|
|
- if (vif->meta[npo.meta_cons].gso_size && vif->gso_prefix) {
|
|
|
+ if ((1 << vif->meta[npo.meta_cons].gso_type) &
|
|
|
+ vif->gso_prefix_mask) {
|
|
|
resp = RING_GET_RESPONSE(&vif->rx,
|
|
|
vif->rx.rsp_prod_pvt++);
|
|
|
|
|
@@ -626,7 +653,8 @@ void xenvif_rx_action(struct xenvif *vif)
|
|
|
vif->meta[npo.meta_cons].size,
|
|
|
flags);
|
|
|
|
|
|
- if (vif->meta[npo.meta_cons].gso_size && !vif->gso_prefix) {
|
|
|
+ if ((1 << vif->meta[npo.meta_cons].gso_type) &
|
|
|
+ vif->gso_mask) {
|
|
|
struct xen_netif_extra_info *gso =
|
|
|
(struct xen_netif_extra_info *)
|
|
|
RING_GET_RESPONSE(&vif->rx,
|
|
@@ -634,8 +662,8 @@ void xenvif_rx_action(struct xenvif *vif)
|
|
|
|
|
|
resp->flags |= XEN_NETRXF_extra_info;
|
|
|
|
|
|
+ gso->u.gso.type = vif->meta[npo.meta_cons].gso_type;
|
|
|
gso->u.gso.size = vif->meta[npo.meta_cons].gso_size;
|
|
|
- gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
|
|
|
gso->u.gso.pad = 0;
|
|
|
gso->u.gso.features = 0;
|
|
|
|