WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: "Santos, Jose Renato G" <joserenato.santos@xxxxxx>
Subject: RE: [Xen-devel] [PATCH 2/2] Add VMDq support to ixgbe
From: "Williams, Mitch A" <mitch.a.williams@xxxxxxxxx>
Date: Tue, 27 Jan 2009 16:10:26 -0700
Accept-language: en-US
Acceptlanguage: en-US
Cc: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Delivery-date: Tue, 27 Jan 2009 15:11:31 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <EF547E542C520A4D858CFEF5B404D0533DC3AD4FE3@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <b04b26320901271055l34f81e3bpb59dbfb7ad85794b@xxxxxxxxxxxxxx> <EF547E542C520A4D858CFEF5B404D0533DC3AD4FE3@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: AcmAsPFGTqYqqLEBS5e5OHCF3wiYIQAHscqwAAEk5cA=
Thread-topic: [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

<Prev in Thread] Current Thread [Next in Thread>