[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |