[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] RE: [Xen-devel] [PATCH 2/2] Add VMDq support to ixgbe
Mitch, I think we are missing the first patch on this series. Did you send patch 1/2? Renato > -----Original Message----- > From: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx > [mailto:xen-devel-bounces@xxxxxxxxxxxxxxxxxxx] On Behalf Of > Mitch Williams > Sent: Tuesday, January 27, 2009 10:56 AM > To: xen-devel@xxxxxxxxxxxxxxxxxxx > Subject: [Xen-devel] [PATCH 2/2] Add VMDq support to ixgbe > > This patch adds experimental VMDq support (AKA Netchannel2 > vmq) to the ixgbe driver. This applies to the Netchannel2 > tree, and should NOT be applied to the "normal" development tree. > > To enable VMDq functionality, load the driver with the > command-line parameter VMDQ=<num queues>, as in: > > $ modprobe ixgbe VMDQ=8 > > You can then set up PV domains to use the device by modifying > your VM configuration file from > vif = [ '<whatever>' ] > to > vif2 = [ 'pdev=<netdev>' ] > where <netdev> is the interface name for your 82598 board, > e.g peth0 in dom0. > > The Netchannel2 code is VERY experimental at this stage and > should not be used in production environments. This patch is > intended to support further development and testing efforts. > > Signed-off-by: Mitch Williams <mitch.a.williams@xxxxxxxxx> > > diff -urpN -X dontdiff a/drivers/net/ixgbe/ixgbe.h > b/drivers/net/ixgbe/ixgbe.h > --- a/drivers/net/ixgbe/ixgbe.h 2009-01-23 > 11:27:18.000000000 -0800 > +++ b/drivers/net/ixgbe/ixgbe.h 2009-01-23 > 11:27:34.000000000 -0800 > @@ -35,6 +35,9 @@ > #include <linux/pci.h> > #include <linux/netdevice.h> > #include <linux/vmalloc.h> > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > +#include <linux/netvmq.h> > +#endif > > #ifdef SIOCETHTOOL > #include <linux/ethtool.h> > @@ -224,6 +227,9 @@ struct ixgbe_ring { > #endif > u16 work_limit; /* max work per interrupt */ > u16 rx_buf_len; > + u8 mac_addr[ETH_ALEN]; > + u8 active; > + u8 allocated; > }; > > #define RING_F_DCB 0 > @@ -417,6 +423,10 @@ struct ixgbe_adapter { > unsigned int lro_flushed; > unsigned int lro_no_desc; > #endif > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + struct net_vmq *vmq; > + u32 rx_queues_allocated; > +#endif > unsigned int tx_ring_count; > unsigned int rx_ring_count; > > diff -urpN -X dontdiff a/drivers/net/ixgbe/ixgbe_main.c > b/drivers/net/ixgbe/ixgbe_main.c > --- a/drivers/net/ixgbe/ixgbe_main.c 2009-01-23 > 11:27:18.000000000 -0800 > +++ b/drivers/net/ixgbe/ixgbe_main.c 2009-01-26 > 11:24:10.000000000 -0800 > @@ -66,7 +66,7 @@ static const char ixgbe_driver_string[] > #define DRIVERNAPI "-NAPI" > #endif > > -#define DRV_VERSION "1.3.56.5" DRIVERNAPI DRV_HW_PERF > +#define DRV_VERSION "1.3.56.5-vmq" DRIVERNAPI DRV_HW_PERF > const char ixgbe_driver_version[] = DRV_VERSION; static > char ixgbe_copyright[] = "Copyright (c) 1999-2008 Intel Corporation."; > /* ixgbe_pci_tbl - PCI Device ID Table > @@ -431,6 +431,17 @@ static void ixgbe_receive_skb(struct ixg > bool is_vlan = (status & IXGBE_RXD_STAT_VP); > u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); > > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + if(ring->queue_index) { > + /* This is a VMDq packet destined for a VM. */ > + vmq_netif_rx(skb, ring->queue_index); > + return; > + } > + else { > + netif_rx(skb); > + return; > + } > +#endif > #ifndef IXGBE_NO_INET_LRO > if (adapter->netdev->features & NETIF_F_LRO && > skb->ip_summed == CHECKSUM_UNNECESSARY) { @@ -511,6 > +522,10 @@ static inline void ixgbe_rx_checksum(str > /* It must be a TCP or UDP packet with a valid checksum */ > skb->ip_summed = CHECKSUM_UNNECESSARY; > adapter->hw_csum_rx_good++; > + > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + skb->proto_data_valid = 1; > +#endif > } > > /** > @@ -554,13 +569,33 @@ static void ixgbe_alloc_rx_buffers(struc > } > > if (!bi->skb) { > - struct sk_buff *skb = > netdev_alloc_skb(adapter->netdev, > - bufsz); > + struct sk_buff *skb; > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + if ((adapter->flags & > IXGBE_FLAG_VMDQ_ENABLED) && > + rx_ring->queue_index) { > + skb = vmq_alloc_skb(adapter->netdev, > + > rx_ring->queue_index, > + bufsz); > + if (!skb) { > + adapter->alloc_rx_buff_failed++; > + goto no_buffers; > + } > + bi->skb = skb; > + bi->dma = pci_map_page(pdev, > + > skb_shinfo(skb)->frags[0].page, > + > skb_shinfo(skb)->frags[0].page_offset, > + > skb_shinfo(skb)->frags[0].size, > + PCI_DMA_FROMDEVICE); > + } else { > +#endif > + skb = > netdev_alloc_skb(adapter->netdev, bufsz); > > - if (!skb) { > - adapter->alloc_rx_buff_failed++; > - goto no_buffers; > - } > + if (!skb) { > + adapter->alloc_rx_buff_failed++; > + goto no_buffers; > + } > + > + skb->dev = adapter->netdev; > > /* > * Make buffer alignment 2 beyond a 16 > byte boundary @@ -572,7 +607,11 @@ static void > ixgbe_alloc_rx_buffers(struc > bi->skb = skb; > bi->dma = pci_map_single(pdev, skb->data, bufsz, > PCI_DMA_FROMDEVICE); > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + } > +#endif > } > + > /* Refresh the desc even if buffer_addrs didn't > change because > * each write-back erases this info. */ > if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) > { @@ -1019,9 +1058,23 @@ static bool ixgbe_clean_rx_irq(struct ix > > cleaned = true; > skb = rx_buffer_info->skb; > - prefetch(skb->data - NET_IP_ALIGN); > rx_buffer_info->skb = NULL; > - > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + if(!rx_ring->queue_index || > !skb_shinfo(skb)->nr_frags) { > + prefetch(skb->data - NET_IP_ALIGN); > + } else { > + /* for Xen VMDq, packet data goes in > first page of > + * skb, instead of data. > + */ > + // TODO this is broke for jumbos > 4k > + pci_unmap_page(pdev, rx_buffer_info->dma, > + PAGE_SIZE, PCI_DMA_FROMDEVICE); > + skb->len += len; > + skb_shinfo(skb)->frags[0].size = len; > + } > +#else > + prefetch(skb->data - NET_IP_ALIGN); > +#endif > if (len && !skb_shinfo(skb)->nr_frags) { > pci_unmap_single(pdev, rx_buffer_info->dma, > rx_ring->rx_buf_len + > NET_IP_ALIGN, @@ -1081,8 +1134,11 @@ static bool > ixgbe_clean_rx_irq(struct ix > /* probably a little skewed due to removing CRC */ > total_rx_bytes += skb->len; > total_rx_packets++; > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + if(!rx_ring->queue_index) > +#endif > + skb->protocol = eth_type_trans(skb, > adapter->netdev); > > - skb->protocol = eth_type_trans(skb, adapter->netdev); > #ifndef IXGBE_NO_LRO > if (ixgbe_lro_ring_queue(rx_ring->lrolist, > adapter, skb, staterr, rx_ring, > rx_desc) == 0) { @@ -1475,6 +1531,8 @@ static irqreturn_t > ixgbe_msix_clean_rx(i > r_idx = find_first_bit(q_vector->rxr_idx, > adapter->num_rx_queues); > for (i = 0; i < q_vector->rxr_count; i++) { > rx_ring = &(adapter->rx_ring[r_idx]); > + if (!rx_ring->active) > + continue; > rx_ring->total_bytes = 0; > rx_ring->total_packets = 0; > #ifndef CONFIG_IXGBE_NAPI > @@ -1501,6 +1559,8 @@ static irqreturn_t ixgbe_msix_clean_rx(i > > r_idx = find_first_bit(q_vector->rxr_idx, > adapter->num_rx_queues); > rx_ring = &(adapter->rx_ring[r_idx]); > + if (!rx_ring->active) > + return IRQ_HANDLED; > /* disable interrupts on this vector only */ > IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx); > netif_rx_schedule(adapter->netdev, &q_vector->napi); @@ > -2217,6 +2277,8 @@ static void ixgbe_configure_rx(struct ix > IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0); > adapter->rx_ring[i].head = IXGBE_RDH(j); > adapter->rx_ring[i].tail = IXGBE_RDT(j); > + > +#ifndef CONFIG_XEN_NETDEV2_BACKEND > if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) { > /* Reserve VMDq set 1 for FCoE, using > 3k buffers */ > if ((i & > adapter->ring_feature[RING_F_VMDQ].mask) == 1) @@ -2226,6 > +2288,10 @@ static void ixgbe_configure_rx(struct ix > } else { > adapter->rx_ring[i].rx_buf_len = rx_buf_len; > } > +#else > + adapter->rx_ring[i].rx_buf_len = > rx_buf_len; #endif /* > +CONFIG_XEN_NETDEV2_BACKEND */ > + > #ifndef IXGBE_NO_INET_LRO > /* Intitial LRO Settings */ > adapter->rx_ring[i].lro_mgr.max_aggr = > adapter->lro_max_aggr; @@ -2398,6 +2464,7 @@ static void > ixgbe_restore_vlan(struct ix } > > #endif > +#ifndef CONFIG_XEN_NETDEV2_BACKEND > /** > * compare_ether_oui - Compare two OUIs > * @addr1: pointer to a 6 byte array containing an Ethernet > address @@ -2426,10 +2493,13 @@ static inline int > is_fcoe_ether_addr(con > static const u8 fcoe_oui[] = { 0x0e, 0xfc, 0x00 }; > return compare_ether_oui(addr, fcoe_oui) == 0; } > +#endif /* CONFIG_XEN_NETDEV2_BACKEND */ > > static u8 *ixgbe_addr_list_itr(struct ixgbe_hw *hw, u8 **mc_addr_ptr, > u32 *vmdq) > { > +#ifndef CONFIG_XEN_NETDEV2_BACKEND > struct ixgbe_adapter *adapter = hw->back; > +#endif > struct dev_mc_list *mc_ptr; > u8 *addr = *mc_addr_ptr; > *vmdq = 0; > @@ -2439,7 +2509,7 @@ static u8 *ixgbe_addr_list_itr(struct ix > *mc_addr_ptr = mc_ptr->next->dmi_addr; > else > *mc_addr_ptr = NULL; > - > +#ifndef CONFIG_XEN_NETDEV2_BACKEND > if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) { > /* VMDQ set 1 is used for FCoE */ > if (adapter->ring_feature[RING_F_VMDQ].indices) > @@ -2459,6 +2529,7 @@ static u8 *ixgbe_addr_list_itr(struct ix > IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); > } > } > +#endif > return addr; > } > > @@ -2665,8 +2736,9 @@ static void ixgbe_configure(struct ixgbe > ixgbe_configure_tx(adapter); > ixgbe_configure_rx(adapter); > for (i = 0; i < adapter->num_rx_queues; i++) > - ixgbe_alloc_rx_buffers(adapter, &adapter->rx_ring[i], > - > IXGBE_DESC_UNUSED(&adapter->rx_ring[i])); > + if (adapter->rx_ring[i].active) > + ixgbe_alloc_rx_buffers(adapter, > &adapter->rx_ring[i], > + > IXGBE_DESC_UNUSED(&adapter->rx_ring[i])); > } > > static int ixgbe_up_complete(struct ixgbe_adapter *adapter) > @@ -2751,7 +2823,8 @@ static int ixgbe_up_complete(struct ixgb > * and HTHRESH=0 descriptors (to minimize > latency on fetch), > * this also removes a pesky rx_no_buffer_count > increment */ > rxdctl |= 0x0020; > - rxdctl |= IXGBE_RXDCTL_ENABLE; > + if (adapter->rx_ring[i].active) > + rxdctl |= IXGBE_RXDCTL_ENABLE; > IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), rxdctl); > } > /* enable all receives */ > @@ -2832,16 +2905,27 @@ static void ixgbe_clean_rx_ring(struct i > struct ixgbe_rx_buffer *rx_buffer_info; > > rx_buffer_info = &rx_ring->rx_buffer_info[i]; > + if (rx_buffer_info->skb) { > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + if (rx_ring->queue_index) { > + pci_unmap_page(pdev, > rx_buffer_info->dma, > + PAGE_SIZE, > + PCI_DMA_FROMDEVICE); > + vmq_free_skb(rx_buffer_info->skb, > + rx_ring->queue_index); > + rx_buffer_info->dma = 0; > + } else > +#endif > + dev_kfree_skb(rx_buffer_info->skb); > + rx_buffer_info->skb = NULL; > + } > + > if (rx_buffer_info->dma) { > pci_unmap_single(pdev, rx_buffer_info->dma, > rx_ring->rx_buf_len + > NET_IP_ALIGN, > PCI_DMA_FROMDEVICE); > rx_buffer_info->dma = 0; > } > - if (rx_buffer_info->skb) { > - dev_kfree_skb(rx_buffer_info->skb); > - rx_buffer_info->skb = NULL; > - } > if (!rx_buffer_info->page) > continue; > pci_unmap_page(pdev, rx_buffer_info->page_dma, > PAGE_SIZE / 2, @@ -3787,6 +3871,19 @@ int > ixgbe_setup_rx_resources(struct ixgb > rx_ring->work_limit = rx_ring->count / 2; #endif > > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + if ((adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) && > + rx_ring->queue_index) { > + rx_ring->active = 0; > + rx_ring->allocated = 0; > + } else { > +#endif > + rx_ring->active = 1; > + rx_ring->allocated = 1; > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + } > +#endif > + > #ifndef IXGBE_NO_LRO > ixgbe_lro_ring_init(rx_ring->lrolist, adapter); #endif > @@ -3906,6 +4003,9 @@ static int ixgbe_setup_all_rx_resources( > DPRINTK(PROBE, ERR, "Allocation for Rx Queue %u > failed\n", i); > break; > } > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + adapter->rx_queues_allocated = 0; > +#endif > return err; > } > > @@ -3949,6 +4049,12 @@ static int ixgbe_change_mtu(struct net_d > if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) > return -EINVAL; > > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + /* Jumbo frames not currently supported in VMDq mode > under Xen */ > + if ((adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) && > + (max_frame > ETH_FRAME_LEN)) > + return -EINVAL; > +#endif > DPRINTK(PROBE, INFO, "changing MTU from %d to %d\n", > netdev->mtu, new_mtu); > /* must set new MTU before calling down or up */ @@ > -4854,6 +4960,191 @@ static int ixgbe_ioctl(struct net_device } > > #endif > + > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > +int ixgbe_get_avail_queues(struct net_device *netdev, unsigned int > +queue_type) { > + struct ixgbe_adapter *adapter = netdev_priv(netdev); > + if (queue_type == VMQ_TYPE_RX) > + return (adapter->num_rx_queues - > adapter->rx_queues_allocated) - 1; > + else if (queue_type == VMQ_TYPE_TX) > + return 0; > + else return 0; > +} > +int ixgbe_get_vmq_maxsize(struct net_device *netdev) { > + return IXGBE_MAX_TXD; > +} > + > +int ixgbe_alloc_vmq_queue(struct net_device *netdev, unsigned int > +queue_type) { > + struct ixgbe_adapter *adapter = netdev_priv(netdev); > + > + if (queue_type == VMQ_TYPE_TX) { > + return -EINVAL; > + } > + > + if (adapter->rx_queues_allocated >= adapter->num_rx_queues) { > + return -EINVAL; > + } > + else { > + int i; > + for (i = 1; i < adapter->num_rx_queues; i++) { > + if (!adapter->rx_ring[i].allocated) { > + adapter->rx_ring[i].allocated = TRUE; > + adapter->rx_queues_allocated++; > + return i; > + } > + } > + return -EINVAL; > + } > +} > + > +int ixgbe_free_vmq_queue(struct net_device *netdev, int queue) { > + struct ixgbe_adapter *adapter = netdev_priv(netdev); > + > + if (queue >= adapter->num_rx_queues) > + return -EINVAL; > + > + if (!adapter->rx_ring[queue].allocated) { > + return -EINVAL; > + } > + > + adapter->rx_ring[queue].allocated = FALSE; > + adapter->rx_queues_allocated--; > + ixgbe_clean_rx_ring(adapter, &adapter->rx_ring[queue]); > + > + return 0; > +} > + > +int ixgbe_set_rxqueue_macfilter(struct net_device *netdev, int queue, > + u8 *mac_addr) > +{ > + int err = 0; > + u32 rah; > + struct ixgbe_adapter *adapter = netdev_priv(netdev); > + struct ixgbe_hw *hw = &adapter->hw; > + struct ixgbe_ring *rx_ring = &adapter->rx_ring[queue]; > + > + if ((queue < 0) || (queue > adapter->num_rx_queues)) { > + return -EADDRNOTAVAIL; > + } > + > + /* Note: Broadcast address is used to disable the MAC filter*/ > + if (!is_valid_ether_addr(mac_addr)) { > + > + memset(rx_ring->mac_addr, 0xFF, ETH_ALEN); > + > + /* Clear RAR */ > + IXGBE_WRITE_REG(hw, IXGBE_RAL(queue), 0); > + IXGBE_WRITE_FLUSH(hw); > + IXGBE_WRITE_REG(hw, IXGBE_RAH(queue), 0); > + IXGBE_WRITE_FLUSH(hw); > + > + return -EADDRNOTAVAIL; > + } > + > + /* Store in ring */ > + memcpy(rx_ring->mac_addr, mac_addr, ETH_ALEN); > + > + err = ixgbe_set_rar(&adapter->hw, queue, rx_ring->mac_addr, 1, > +IXGBE_RAH_AV); > + > + if (!err) { > + /* Set the VIND for the indicated queue's RAR Entry */ > + rah = IXGBE_READ_REG(hw, IXGBE_RAH(queue)); > + rah &= ~IXGBE_RAH_VIND_MASK; > + rah |= (queue << IXGBE_RAH_VIND_SHIFT); > + IXGBE_WRITE_REG(hw, IXGBE_RAH(queue), rah); > + IXGBE_WRITE_FLUSH(hw); > + } > + > + return err; > +} > + > +int ixgbe_get_vmq_size(struct net_device *netdev, int queue) { > + struct ixgbe_adapter *adapter = netdev_priv(netdev); > + > + if (queue >= adapter->num_rx_queues) > + return -EINVAL; > + return adapter->rx_ring[queue].count; > +} > + > +int ixgbe_set_vmq_size(struct net_device *netdev, int queue, > int size) > +{ > + struct ixgbe_adapter *adapter = netdev_priv(netdev); > + /* Not implemented yet, so just return count. */ > + return adapter->rx_ring[queue].count; > +} > + > +int ixgbe_set_vmq_vlan(struct net_device *netdev, int queue, int > +vlan_id) { > + return 0; /* not implemented */ > +} > + > +int ixgbe_vmq_enable(struct net_device *netdev, int queue) { > + struct ixgbe_adapter *adapter = netdev_priv(netdev); > + struct ixgbe_hw *hw = &adapter->hw; > + u32 rxdctl; > + > + if (queue >= adapter->num_rx_queues) > + return -EINVAL; > + > + if (!adapter->rx_ring[queue].allocated) { > + return -EINVAL; > + } > + adapter->rx_ring[queue].active = 1; > + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(queue)); > + rxdctl |= IXGBE_RXDCTL_ENABLE; > + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(queue), rxdctl); > + IXGBE_WRITE_FLUSH(hw); > + ixgbe_alloc_rx_buffers(adapter, > + &adapter->rx_ring[queue], > + > IXGBE_DESC_UNUSED(&adapter->rx_ring[queue])); > + return 0; > +} > +int ixgbe_vmq_disable(struct net_device *netdev, int queue) { > + struct ixgbe_adapter *adapter = netdev_priv(netdev); > + struct ixgbe_hw *hw = &adapter->hw; > + u32 rxdctl; > + > + if (queue >= adapter->num_rx_queues) > + return -EINVAL; > + > + if (!adapter->rx_ring[queue].allocated) { > + return -EINVAL; > + } > + > + adapter->rx_ring[queue].active = 0; > + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(queue)); > + rxdctl &= ~IXGBE_RXDCTL_ENABLE; > + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(queue), rxdctl); > + return 0; > +} > + > +static void ixgbe_setup_vmq(struct ixgbe_adapter *adapter) { > + net_vmq_t *vmq; > + > + vmq = alloc_vmq(adapter->num_rx_queues); > + if (vmq) { > + vmq->avail_queues = ixgbe_get_avail_queues; > + vmq->alloc_queue = ixgbe_alloc_vmq_queue; > + vmq->free_queue = ixgbe_free_vmq_queue; > + vmq->get_maxsize = ixgbe_get_vmq_maxsize; > + vmq->get_size = ixgbe_get_vmq_size; > + vmq->set_size = ixgbe_set_vmq_size; > + vmq->set_mac = ixgbe_set_rxqueue_macfilter; > + vmq->set_vlan = ixgbe_set_vmq_vlan; > + vmq->enable = ixgbe_vmq_enable; > + vmq->disable = ixgbe_vmq_disable; > + vmq->nvmq = adapter->num_rx_queues; > + adapter->netdev->vmq = vmq; > + } > +} > +#endif /* CONFIG_XEN_NETDEV2_BACKEND */ > + > #ifdef CONFIG_NET_POLL_CONTROLLER > /* > * Polling 'interrupt' - used by things like netconsole to > send skbs @@ -5152,12 +5443,18 @@ static int __devinit > ixgbe_probe(struct > > #endif > strcpy(netdev->name, "eth%d"); > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) > + ixgbe_setup_vmq(adapter); > +#endif > err = register_netdev(netdev); > if (err) > goto err_register; > > +#ifndef CONFIG_XEN_NETDEV2_BACKEND > if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) > ixgbe_sysfs_create(adapter); > +#endif > > #if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) > if (adapter->flags & IXGBE_FLAG_DCA_CAPABLE) { @@ > -5267,8 +5564,17 @@ static void __devexit ixgbe_remove(struc > } > > #endif > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + if (netdev->vmq) { > + free_vmq(netdev->vmq); > + netdev->vmq = 0; > + } > +#endif > + > +#ifndef CONFIG_XEN_NETDEV2_BACKEND > if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) > ixgbe_sysfs_remove(adapter); > +#endif > if (netdev->reg_state == NETREG_REGISTERED) > unregister_netdev(netdev); > > diff -urpN -X dontdiff a/drivers/net/ixgbe/ixgbe_param.c > b/drivers/net/ixgbe/ixgbe_param.c > --- a/drivers/net/ixgbe/ixgbe_param.c 2009-01-23 > 11:27:18.000000000 -0800 > +++ b/drivers/net/ixgbe/ixgbe_param.c 2009-01-23 > 11:27:40.000000000 -0800 > @@ -723,6 +723,13 @@ void __devinit ixgbe_check_options(struc > adapter->flags |= IXGBE_FLAG_RX_PS_CAPABLE; > } > #endif > +#ifdef CONFIG_XEN_NETDEV2_BACKEND > + if (adapter->flags & > + (IXGBE_FLAG_RX_PS_CAPABLE | IXGBE_FLAG_VMDQ_ENABLED)) { > + printk(KERN_INFO "ixgbe: packet split disabled > for Xen VMDQ\n"); > + adapter->flags &= ~IXGBE_FLAG_RX_PS_CAPABLE; > + } > +#endif > } > } > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxxxxxxxx > http://lists.xensource.com/xen-devel > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |