[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2/2] Add VMDq support to ixgbe
I think there is a limit, you might have to put the patch up for download somewhere. -- Keir On 27/01/2009 23:10, "Williams, Mitch A" <mitch.a.williams@xxxxxxxxx> wrote: > 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 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |