/* Allocate a netvsc packet based on # of frags. */
packet = kzalloc(sizeof(struct hv_netvsc_packet) +
(num_pages * sizeof(struct hv_page_buffer)) +
- sizeof(struct rndis_filter_packet), GFP_ATOMIC);
+ sizeof(struct rndis_filter_packet) +
+ NDIS_VLAN_PPI_SIZE, GFP_ATOMIC);
if (!packet) {
/* out of memory, drop packet */
netdev_err(net, "unable to allocate hv_netvsc_packet\n");
return NETDEV_TX_OK;
}
+ packet->vlan_tci = skb->vlan_tci;
+
packet->extension = (void *)(unsigned long)packet +
sizeof(struct hv_netvsc_packet) +
(num_pages * sizeof(struct hv_page_buffer));
int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet)
{
- struct net_device *net = dev_get_drvdata(&device_obj->device);
+ struct net_device *net;
struct sk_buff *skb;
- struct netvsc_device *net_device;
-
- net_device = hv_get_drvdata(device_obj);
- net = net_device->ndev;
+ net = ((struct netvsc_device *)hv_get_drvdata(device_obj))->ndev;
if (!net) {
netdev_err(net, "got receive callback but net device"
" not initialized yet\n");
skb->protocol = eth_type_trans(skb, net);
skb->ip_summed = CHECKSUM_NONE;
+ skb->vlan_tci = packet->vlan_tci;
net->stats.rx_packets++;
net->stats.rx_bytes += packet->total_data_buflen;
/* TODO: Add GSO and Checksum offload */
net->hw_features = NETIF_F_SG;
- net->features = NETIF_F_SG;
+ net->features = NETIF_F_SG | NETIF_F_HW_VLAN_TX;
SET_ETHTOOL_OPS(net, ðtool_ops);
SET_NETDEV_DEV(net, &dev->device);