brcmf_netif_rx(ifp, skb);
 }
 
-void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
+void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
                      bool success)
 {
        struct brcmf_if *ifp;
        struct ethhdr *eh;
-       u8 ifidx;
        u16 type;
-       int res;
-
-       res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
 
        ifp = drvr->iflist[ifidx];
        if (!ifp)
                goto done;
 
-       if (res == 0) {
-               eh = (struct ethhdr *)(txp->data);
-               type = ntohs(eh->h_proto);
+       eh = (struct ethhdr *)(txp->data);
+       type = ntohs(eh->h_proto);
 
-               if (type == ETH_P_PAE) {
-                       atomic_dec(&ifp->pend_8021x_cnt);
-                       if (waitqueue_active(&ifp->pend_8021x_wait))
-                               wake_up(&ifp->pend_8021x_wait);
-               }
+       if (type == ETH_P_PAE) {
+               atomic_dec(&ifp->pend_8021x_cnt);
+               if (waitqueue_active(&ifp->pend_8021x_wait))
+                       wake_up(&ifp->pend_8021x_wait);
        }
+
        if (!success)
                ifp->stats.tx_errors++;
 done:
 {
        struct brcmf_bus *bus_if = dev_get_drvdata(dev);
        struct brcmf_pub *drvr = bus_if->drvr;
+       u8 ifidx;
 
        /* await txstatus signal for firmware if active */
        if (brcmf_fws_fc_active(drvr->fws)) {
                if (!success)
                        brcmf_fws_bustxfail(drvr->fws, txp);
        } else {
-               brcmf_txfinalize(drvr, txp, success);
+               if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp))
+                       brcmu_pkt_buf_free_skb(txp);
+               else
+                       brcmf_txfinalize(drvr, txp, ifidx, success);
        }
 }
 
 
 }
 
 static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
-                                        struct sk_buff *skb, u32 genbit,
-                                        u16 seq)
+                                        struct sk_buff *skb, u8 ifidx,
+                                        u32 genbit, u16 seq)
 {
        struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
        u32 hslot;
        int ret;
-       u8 ifidx;
 
        hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
 
 
        entry->generation = genbit;
 
-       ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
-       if (ret == 0) {
-               brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
-               brcmf_skbcb(skb)->htod_seq = seq;
-               if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
-                       brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
-                       brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
-               } else {
-                       brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
-               }
-               ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
-                                   skb);
+       brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
+       brcmf_skbcb(skb)->htod_seq = seq;
+       if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
+               brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
+               brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
+       } else {
+               brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
        }
+       ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb);
 
        if (ret != 0) {
-               /* suppress q is full or hdrpull failed, drop this packet */
-               brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
-                                       true);
+               /* suppress q is full drop this packet */
+               brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, true);
        } else {
-               /*
-                * Mark suppressed to avoid a double free during
-                * wlfc cleanup
-                */
+               /* Mark suppressed to avoid a double free during wlfc cleanup */
                brcmf_fws_hanger_mark_suppressed(&fws->hanger, hslot);
        }
 
        struct sk_buff *skb;
        struct brcmf_skbuff_cb *skcb;
        struct brcmf_fws_mac_descriptor *entry = NULL;
+       u8 ifidx;
 
        brcmf_dbg(DATA, "flags %d\n", flags);
 
        }
        brcmf_fws_macdesc_return_req_credit(skb);
 
+       if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) {
+               brcmu_pkt_buf_free_skb(skb);
+               return -EINVAL;
+       }
        if (!remove_from_hanger)
-               ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit,
-                                                   seq);
-
+               ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx,
+                                                   genbit, seq);
        if (remove_from_hanger || ret)
-               brcmf_txfinalize(fws->drvr, skb, true);
+               brcmf_txfinalize(fws->drvr, skb, ifidx, true);
 
        return 0;
 }
                                ret = brcmf_proto_txdata(drvr, ifidx, 0, skb);
                                brcmf_fws_lock(fws);
                                if (ret < 0)
-                                       brcmf_txfinalize(drvr, skb, false);
+                                       brcmf_txfinalize(drvr, skb, ifidx,
+                                                        false);
                                if (fws->bus_flow_blocked)
                                        break;
                        }