/* Specific functions used for Ring mode */
 
 /* Enhanced descriptors */
-static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end)
+static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end,
+                                          int bfsize)
 {
-       p->des1 |= cpu_to_le32((BUF_SIZE_8KiB
-                       << ERDES1_BUFFER2_SIZE_SHIFT)
-                  & ERDES1_BUFFER2_SIZE_MASK);
+       if (bfsize == BUF_SIZE_16KiB)
+               p->des1 |= cpu_to_le32((BUF_SIZE_8KiB
+                               << ERDES1_BUFFER2_SIZE_SHIFT)
+                          & ERDES1_BUFFER2_SIZE_MASK);
 
        if (end)
                p->des1 |= cpu_to_le32(ERDES1_END_RING);
 }
 
 /* Normal descriptors */
-static inline void ndesc_rx_set_on_ring(struct dma_desc *p, int end)
+static inline void ndesc_rx_set_on_ring(struct dma_desc *p, int end, int bfsize)
 {
-       p->des1 |= cpu_to_le32(((BUF_SIZE_2KiB - 1)
-                               << RDES1_BUFFER2_SIZE_SHIFT)
-                   & RDES1_BUFFER2_SIZE_MASK);
+       if (bfsize >= BUF_SIZE_2KiB) {
+               int bfsize2;
+
+               bfsize2 = min(bfsize - BUF_SIZE_2KiB + 1, BUF_SIZE_2KiB - 1);
+               p->des1 |= cpu_to_le32((bfsize2 << RDES1_BUFFER2_SIZE_SHIFT)
+                           & RDES1_BUFFER2_SIZE_MASK);
+       }
 
        if (end)
                p->des1 |= cpu_to_le32(RDES1_END_RING);
 
 }
 
 static void dwmac4_rd_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
-                                  int mode, int end)
+                                  int mode, int end, int bfsize)
 {
        dwmac4_set_rx_owner(p, disable_rx_ic);
 }
 
 }
 
 static void dwxgmac2_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
-                                 int mode, int end)
+                                 int mode, int end, int bfsize)
 {
        dwxgmac2_set_rx_owner(p, disable_rx_ic);
 }
 
 }
 
 static void enh_desc_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
-                                 int mode, int end)
+                                 int mode, int end, int bfsize)
 {
+       int bfsize1;
+
        p->des0 |= cpu_to_le32(RDES0_OWN);
-       p->des1 |= cpu_to_le32(BUF_SIZE_8KiB & ERDES1_BUFFER1_SIZE_MASK);
+
+       bfsize1 = min(bfsize, BUF_SIZE_8KiB);
+       p->des1 |= cpu_to_le32(bfsize1 & ERDES1_BUFFER1_SIZE_MASK);
 
        if (mode == STMMAC_CHAIN_MODE)
                ehn_desc_rx_set_on_chain(p);
        else
-               ehn_desc_rx_set_on_ring(p, end);
+               ehn_desc_rx_set_on_ring(p, end, bfsize);
 
        if (disable_rx_ic)
                p->des1 |= cpu_to_le32(ERDES1_DISABLE_IC);
 
 struct stmmac_desc_ops {
        /* DMA RX descriptor ring initialization */
        void (*init_rx_desc)(struct dma_desc *p, int disable_rx_ic, int mode,
-                       int end);
+                       int end, int bfsize);
        /* DMA TX descriptor ring initialization */
        void (*init_tx_desc)(struct dma_desc *p, int mode, int end);
        /* Invoked by the xmit function to prepare the tx descriptor */
 
 }
 
 static void ndesc_init_rx_desc(struct dma_desc *p, int disable_rx_ic, int mode,
-                              int end)
+                              int end, int bfsize)
 {
+       int bfsize1;
+
        p->des0 |= cpu_to_le32(RDES0_OWN);
-       p->des1 |= cpu_to_le32((BUF_SIZE_2KiB - 1) & RDES1_BUFFER1_SIZE_MASK);
+
+       bfsize1 = min(bfsize, BUF_SIZE_2KiB - 1);
+       p->des1 |= cpu_to_le32(bfsize & RDES1_BUFFER1_SIZE_MASK);
 
        if (mode == STMMAC_CHAIN_MODE)
                ndesc_rx_set_on_chain(p, end);
        else
-               ndesc_rx_set_on_ring(p, end);
+               ndesc_rx_set_on_ring(p, end, bfsize);
 
        if (disable_rx_ic)
                p->des1 |= cpu_to_le32(RDES1_DISABLE_IC);
 
                if (priv->extend_desc)
                        stmmac_init_rx_desc(priv, &rx_q->dma_erx[i].basic,
                                        priv->use_riwt, priv->mode,
-                                       (i == DMA_RX_SIZE - 1));
+                                       (i == DMA_RX_SIZE - 1),
+                                       priv->dma_buf_sz);
                else
                        stmmac_init_rx_desc(priv, &rx_q->dma_rx[i],
                                        priv->use_riwt, priv->mode,
-                                       (i == DMA_RX_SIZE - 1));
+                                       (i == DMA_RX_SIZE - 1),
+                                       priv->dma_buf_sz);
 }
 
 /**