if(curfragnum!=pfhdr->attrib.frag_num)// [1] <== { //the first fragment number must be 0 //free the whole queue rtw_free_recvframe(prframe, pfree_recv_queue); rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
//check the fragment sequence (2nd ~n fragment frame)
if(curfragnum!=pnfhdr->attrib.frag_num)// [2] <== { //the fragment number must be increasing (after decache) //release the defrag_q & prframe rtw_free_recvframe(prframe, pfree_recv_queue); rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); returnNULL; }
curfragnum++;
//copy the 2nd~n fragment frame's payload to the first fragment //get the 2nd~last fragment frame's payload
/* 6 is for IP header 8 bytes alignment in QoS packet case. */ if (pfhdr->attrib.qos) shift_sz = 6; else shift_sz = 0;
/* for first fragment packet, need to allocate */ /* (1536 + RXDESC_SIZE + drvinfo_sz) to reassemble packet */ /* 8 is for skb->data 8 bytes alignment. * alloc_sz = _RND(1536 + RXDESC_SIZE + pfhdr->attrib.drvinfosize + shift_sz + 8, 128); */ alloc_sz = 1664; /* round (1536 + 24 + 32 + shift_sz + 8) to 128 bytes alignment */
/* 3 1. alloc new skb */ /* prepare extra space for 4 bytes alignment */ ppkt = rtw_skb_alloc(alloc_sz);
if (!ppkt) return; /* no way to expand */
/* 3 2. Prepare new skb to replace & release old skb */ /* force ppkt->data at 8-byte alignment address */ skb_reserve(ppkt, 8 - ((SIZE_PTR)ppkt->data & 7)); /* force ip_hdr at 8-byte alignment address according to shift_sz */ skb_reserve(ppkt, shift_sz);
/* copy data to new pkt */ ptr = skb_put(ppkt, pfhdr->len); if (ptr) _rtw_memcpy(ptr, pfhdr->rx_data, pfhdr->len);