Yeah, I did, but I think it got eaten somewhere along the way. I'll resend in
a few minutes.
Is there a size limit on xen-devel? The patch is big (>500k) because it's a
whole new driver.
-Mitch
>-----Original Message-----
>From: Santos, Jose Renato G [mailto:joserenato.santos@xxxxxx]
>Sent: Tuesday, January 27, 2009 2:55 PM
>To: Williams, Mitch A
>Cc: xen-devel@xxxxxxxxxxxxxxxxxxx
>Subject: 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
|