[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Xen-devel] [PATCH 2/2] Add VMDq support to ixgbe



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.