}
 
                for (i = 0; i < vsi->num_queue_pairs; i++) {
+                       /* this is to allow wr32 to have something to write to
+                        * during early allocation of Rx buffers
+                        */
+                       u32 __iomem faketail = 0;
+                       struct i40e_ring *ring;
+                       u16 unused;
+
                        /* clone ring and setup updated count */
                        rx_rings[i] = *vsi->rx_rings[i];
                        rx_rings[i].count = new_rx_count;
                         */
                        rx_rings[i].desc = NULL;
                        rx_rings[i].rx_bi = NULL;
+                       rx_rings[i].tail = (u8 __iomem *)&faketail;
                        err = i40e_setup_rx_descriptors(&rx_rings[i]);
+                       if (err)
+                               goto rx_unwind;
+
+                       /* now allocate the Rx buffers to make sure the OS
+                        * has enough memory, any failure here means abort
+                        */
+                       ring = &rx_rings[i];
+                       unused = I40E_DESC_UNUSED(ring);
+                       err = i40e_alloc_rx_buffers(ring, unused);
+rx_unwind:
                        if (err) {
-                               while (i) {
-                                       i--;
+                               do {
                                        i40e_free_rx_resources(&rx_rings[i]);
-                               }
+                               } while (i--);
                                kfree(rx_rings);
                                rx_rings = NULL;
 
        if (rx_rings) {
                for (i = 0; i < vsi->num_queue_pairs; i++) {
                        i40e_free_rx_resources(vsi->rx_rings[i]);
+                       /* get the real tail offset */
+                       rx_rings[i].tail = vsi->rx_rings[i]->tail;
+                       /* this is to fake out the allocation routine
+                        * into thinking it has to realloc everything
+                        * but the recycling logic will let us re-use
+                        * the buffers allocated above
+                        */
+                       rx_rings[i].next_to_use = 0;
+                       rx_rings[i].next_to_clean = 0;
+                       rx_rings[i].next_to_alloc = 0;
+                       /* do a struct copy */
                        *vsi->rx_rings[i] = rx_rings[i];
                }
                kfree(rx_rings);