return -ENOMEM;
        }
 
-       /* SMQ config limits maximum pkt size that can be transmitted */
-       req->update_smq = true;
        pfvf->max_frs = mtu +  OTX2_ETH_HLEN;
        req->maxlen = pfvf->max_frs;
 
        /* Set topology e.t.c configuration */
        if (lvl == NIX_TXSCH_LVL_SMQ) {
                req->reg[0] = NIX_AF_SMQX_CFG(schq);
-               req->regval[0] = ((pfvf->netdev->mtu  + OTX2_ETH_HLEN) << 8) |
+               req->regval[0] = ((OTX2_MAX_MTU + OTX2_ETH_HLEN) << 8) |
                                   OTX2_MIN_MTU;
 
                req->regval[0] |= (0x20ULL << 51) | (0x80ULL << 39) |
 {
        int qidx, sqe_tail, sqe_head;
        u64 incr, *ptr, val;
+       int timeout = 1000;
 
        ptr = (u64 *)otx2_get_regaddr(pfvf, NIX_LF_SQ_OP_STATUS);
        for (qidx = 0; qidx < pfvf->hw.tx_queues; qidx++) {
                incr = (u64)qidx << 32;
-               while (1) {
+               while (timeout) {
                        val = otx2_atomic64_add(incr, ptr);
                        sqe_head = (val >> 20) & 0x3F;
                        sqe_tail = (val >> 28) & 0x3F;
                        if (sqe_head == sqe_tail)
                                break;
                        usleep_range(1, 3);
+                       timeout--;
                }
        }
 }
                qmem_free(pfvf->dev, pool->fc_addr);
        }
        devm_kfree(pfvf->dev, pfvf->qset.pool);
+       pfvf->qset.pool = NULL;
 }
 
 static int otx2_aura_init(struct otx2_nic *pfvf, int aura_id,
 
        skb_set_hash(skb, hash, hash_type);
 }
 
+static void otx2_free_rcv_seg(struct otx2_nic *pfvf, struct nix_cqe_rx_s *cqe,
+                             int qidx)
+{
+       struct nix_rx_sg_s *sg = &cqe->sg;
+       void *end, *start;
+       u64 *seg_addr;
+       int seg;
+
+       start = (void *)sg;
+       end = start + ((cqe->parse.desc_sizem1 + 1) * 16);
+       while (start < end) {
+               sg = (struct nix_rx_sg_s *)start;
+               seg_addr = &sg->seg_addr;
+               for (seg = 0; seg < sg->segs; seg++, seg_addr++)
+                       otx2_aura_freeptr(pfvf, qidx, *seg_addr & ~0x07ULL);
+               start += sizeof(*sg);
+       }
+}
+
 static bool otx2_check_rcv_errors(struct otx2_nic *pfvf,
                                  struct nix_cqe_rx_s *cqe, int qidx)
 {
                /* For now ignore all the NPC parser errors and
                 * pass the packets to stack.
                 */
-               return false;
+               if (cqe->sg.segs == 1)
+                       return false;
        }
 
        /* If RXALL is enabled pass on packets to stack. */
-       if (cqe->sg.segs && (pfvf->netdev->features & NETIF_F_RXALL))
+       if (cqe->sg.segs == 1 && (pfvf->netdev->features & NETIF_F_RXALL))
                return false;
 
        /* Free buffer back to pool */
        if (cqe->sg.segs)
-               otx2_aura_freeptr(pfvf, qidx, cqe->sg.seg_addr & ~0x07ULL);
+               otx2_free_rcv_seg(pfvf, cqe, qidx);
        return true;
 }
 
        struct nix_rx_parse_s *parse = &cqe->parse;
        struct sk_buff *skb = NULL;
 
-       if (unlikely(parse->errlev || parse->errcode)) {
+       if (unlikely(parse->errlev || parse->errcode || cqe->sg.segs > 1)) {
                if (otx2_check_rcv_errors(pfvf, cqe, cq->cq_idx))
                        return;
        }
        while ((cqe = (struct nix_cqe_rx_s *)otx2_get_next_cqe(cq))) {
                if (!cqe->sg.subdc)
                        continue;
+               processed_cqe++;
+               if (cqe->sg.segs > 1) {
+                       otx2_free_rcv_seg(pfvf, cqe, cq->cq_idx);
+                       continue;
+               }
                iova = cqe->sg.seg_addr - OTX2_HEAD_ROOM;
                pa = otx2_iova_to_phys(pfvf->iommu_domain, iova);
                otx2_dma_unmap_page(pfvf, iova, pfvf->rbsize, DMA_FROM_DEVICE);
                put_page(virt_to_page(phys_to_virt(pa)));
-               processed_cqe++;
        }
 
        /* Free CQEs to HW */