--- /dev/null
+From 96cc637235892a102fb829218adac048bd730ab7 Mon Sep 17 00:00:00 2001
+From: Alexander Duyck <alexander.h.duyck@intel.com>
+Date: Wed, 19 Jan 2011 18:33:05 +0000
+Subject: ixgbe: limit VF access to network traffic
+
+From: Alexander Duyck <alexander.h.duyck@intel.com>
+
+commit 96cc637235892a102fb829218adac048bd730ab7 upstream.
+
+This change fixes VM pool allocation issues based on MAC address filtering,
+as well as limits the scope of VF access to promiscuous mode.
+
+Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
+Acked-by: Greg Rose <gregory.v.rose@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/ixgbe/ixgbe_common.c | 3 +++
+ drivers/net/ixgbe/ixgbe_sriov.c | 2 --
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ixgbe/ixgbe_common.c
++++ b/drivers/net/ixgbe/ixgbe_common.c
+@@ -1292,6 +1292,9 @@ s32 ixgbe_init_rx_addrs_generic(struct i
+ hw_dbg(hw, " New MAC Addr =%pM\n", hw->mac.addr);
+
+ hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
++
++ /* clear VMDq pool/queue selection for RAR 0 */
++ hw->mac.ops.clear_vmdq(hw, 0, IXGBE_CLEAR_VMDQ_ALL);
+ }
+ hw->addr_ctrl.overflow_promisc = 0;
+
+--- a/drivers/net/ixgbe/ixgbe_sriov.c
++++ b/drivers/net/ixgbe/ixgbe_sriov.c
+@@ -110,12 +110,10 @@ static int ixgbe_set_vf_vlan(struct ixgb
+ return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add);
+ }
+
+-
+ static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe)
+ {
+ u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
+ vmolr |= (IXGBE_VMOLR_ROMPE |
+- IXGBE_VMOLR_ROPE |
+ IXGBE_VMOLR_BAM);
+ if (aupe)
+ vmolr |= IXGBE_VMOLR_AUPE;
--- /dev/null
+From c600636bd560b04973174caa5e349a72bce51637 Mon Sep 17 00:00:00 2001
+From: Amir Hanania <amir.hanania@intel.com>
+Date: Tue, 15 Feb 2011 09:11:31 +0000
+Subject: ixgbe: work around for DDP last buffer size
+
+From: Amir Hanania <amir.hanania@intel.com>
+
+commit c600636bd560b04973174caa5e349a72bce51637 upstream.
+
+A HW limitation was recently discovered where the last buffer in a DDP offload
+cannot be a full buffer size in length. Fix the issue with a work around by
+adding another buffer with size = 1.
+
+Signed-off-by: Amir Hanania <amir.hanania@intel.com>
+Tested-by: Ross Brattain <ross.b.brattain@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/ixgbe/ixgbe_fcoe.c | 51 ++++++++++++++++++++++++++++++++++++++++-
+ drivers/net/ixgbe/ixgbe_fcoe.h | 2 +
+ 2 files changed, 52 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ixgbe/ixgbe_fcoe.c
++++ b/drivers/net/ixgbe/ixgbe_fcoe.c
+@@ -151,7 +151,7 @@ int ixgbe_fcoe_ddp_get(struct net_device
+ struct scatterlist *sg;
+ unsigned int i, j, dmacount;
+ unsigned int len;
+- static const unsigned int bufflen = 4096;
++ static const unsigned int bufflen = IXGBE_FCBUFF_MIN;
+ unsigned int firstoff = 0;
+ unsigned int lastsize;
+ unsigned int thisoff = 0;
+@@ -241,6 +241,24 @@ int ixgbe_fcoe_ddp_get(struct net_device
+ /* only the last buffer may have non-full bufflen */
+ lastsize = thisoff + thislen;
+
++ /*
++ * lastsize can not be buffer len.
++ * If it is then adding another buffer with lastsize = 1.
++ */
++ if (lastsize == bufflen) {
++ if (j >= IXGBE_BUFFCNT_MAX) {
++ e_err(drv, "xid=%x:%d,%d,%d:addr=%llx "
++ "not enough user buffers. We need an extra "
++ "buffer because lastsize is bufflen.\n",
++ xid, i, j, dmacount, (u64)addr);
++ goto out_noddp_free;
++ }
++
++ ddp->udl[j] = (u64)(fcoe->extra_ddp_buffer_dma);
++ j++;
++ lastsize = 1;
++ }
++
+ fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);
+ fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT);
+ fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT);
+@@ -519,6 +537,24 @@ void ixgbe_configure_fcoe(struct ixgbe_a
+ e_err(drv, "failed to allocated FCoE DDP pool\n");
+
+ spin_lock_init(&fcoe->lock);
++
++ /* Extra buffer to be shared by all DDPs for HW work around */
++ fcoe->extra_ddp_buffer = kmalloc(IXGBE_FCBUFF_MIN, GFP_ATOMIC);
++ if (fcoe->extra_ddp_buffer == NULL) {
++ e_err(drv, "failed to allocated extra DDP buffer\n");
++ goto out_extra_ddp_buffer_alloc;
++ }
++
++ fcoe->extra_ddp_buffer_dma =
++ dma_map_single(&adapter->pdev->dev,
++ fcoe->extra_ddp_buffer,
++ IXGBE_FCBUFF_MIN,
++ DMA_FROM_DEVICE);
++ if (dma_mapping_error(&adapter->pdev->dev,
++ fcoe->extra_ddp_buffer_dma)) {
++ e_err(drv, "failed to map extra DDP buffer\n");
++ goto out_extra_ddp_buffer_dma;
++ }
+ }
+
+ /* Enable L2 eth type filter for FCoE */
+@@ -568,6 +604,14 @@ void ixgbe_configure_fcoe(struct ixgbe_a
+ }
+ }
+ #endif
++
++ return;
++
++out_extra_ddp_buffer_dma:
++ kfree(fcoe->extra_ddp_buffer);
++out_extra_ddp_buffer_alloc:
++ pci_pool_destroy(fcoe->pool);
++ fcoe->pool = NULL;
+ }
+
+ /**
+@@ -587,6 +631,11 @@ void ixgbe_cleanup_fcoe(struct ixgbe_ada
+ if (fcoe->pool) {
+ for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++)
+ ixgbe_fcoe_ddp_put(adapter->netdev, i);
++ dma_unmap_single(&adapter->pdev->dev,
++ fcoe->extra_ddp_buffer_dma,
++ IXGBE_FCBUFF_MIN,
++ DMA_FROM_DEVICE);
++ kfree(fcoe->extra_ddp_buffer);
+ pci_pool_destroy(fcoe->pool);
+ fcoe->pool = NULL;
+ }
+--- a/drivers/net/ixgbe/ixgbe_fcoe.h
++++ b/drivers/net/ixgbe/ixgbe_fcoe.h
+@@ -70,6 +70,8 @@ struct ixgbe_fcoe {
+ spinlock_t lock;
+ struct pci_pool *pool;
+ struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX];
++ unsigned char *extra_ddp_buffer;
++ dma_addr_t extra_ddp_buffer_dma;
+ };
+
+ #endif /* _IXGBE_FCOE_H */