struct ionic_rxq_sg_desc *sg_desc;
        struct ionic_rxq_sg_elem *sg_elem;
        struct ionic_rxq_desc *desc;
+       unsigned int remain_len;
+       unsigned int seg_len;
        unsigned int nfrags;
        bool ring_doorbell;
        unsigned int i, j;
        nfrags = round_up(len, PAGE_SIZE) / PAGE_SIZE;
 
        for (i = ionic_q_space_avail(q); i; i--) {
+               remain_len = len;
                desc_info = q->head;
                desc = desc_info->desc;
                sg_desc = desc_info->sg_desc;
                        return;
                }
                desc->addr = cpu_to_le64(page_info->dma_addr);
-               desc->len = cpu_to_le16(PAGE_SIZE);
+               seg_len = min_t(unsigned int, PAGE_SIZE, len);
+               desc->len = cpu_to_le16(seg_len);
+               remain_len -= seg_len;
                page_info++;
 
                /* fill sg descriptors - pages[1..n] */
                                return;
                        }
                        sg_elem->addr = cpu_to_le64(page_info->dma_addr);
-                       sg_elem->len = cpu_to_le16(PAGE_SIZE);
+                       seg_len = min_t(unsigned int, PAGE_SIZE, remain_len);
+                       sg_elem->len = cpu_to_le16(seg_len);
+                       remain_len -= seg_len;
                        page_info++;
                }