return 0;
 }
 
+static int
+brcmf_proto_bcdc_txdata(struct brcmf_pub *drvr, int ifidx, u8 offset,
+                       struct sk_buff *pktbuf)
+{
+       brcmf_proto_bcdc_hdrpush(drvr, ifidx, offset, pktbuf);
+       return brcmf_bus_txdata(drvr->bus_if, pktbuf);
+}
+
+
 int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
 {
        struct brcmf_bcdc *bcdc;
                goto fail;
        }
 
-       drvr->proto->hdrpush = brcmf_proto_bcdc_hdrpush;
        drvr->proto->hdrpull = brcmf_proto_bcdc_hdrpull;
        drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd;
        drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd;
+       drvr->proto->txdata = brcmf_proto_bcdc_txdata;
        drvr->proto->pd = bcdc;
 
        drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
 
        brcmf_fws_hanger_cleanup(fws, matchfn, ifidx);
 }
 
-static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
+static u8 brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
 {
        struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
        u8 *wlh;
        if (fillers)
                memset(wlh, BRCMF_FWS_TYPE_FILLER, fillers);
 
-       brcmf_proto_hdrpush(fws->drvr, brcmf_skb_if_flags_get_field(skb, INDEX),
-                           data_offset >> 2, skb);
-       return 0;
+       return (u8)(data_offset >> 2);
 }
 
 static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
                                 int fifo, bool send_immediately)
 {
        struct sk_buff *skb;
-       struct brcmf_bus *bus;
        struct brcmf_skbuff_cb *skcb;
        s32 err;
        u32 len;
+       u8 data_offset;
+       int ifidx;
 
        /* check delayedQ and suppressQ in one call using bitmap */
        if (brcmu_pktq_mlen(&entry->psq, 3 << (fifo * 2)) == 0)
                skcb->state = BRCMF_FWS_SKBSTATE_TIM;
                skcb->htod = 0;
                skcb->htod_seq = 0;
-               bus = fws->drvr->bus_if;
-               err = brcmf_fws_hdrpush(fws, skb);
-               if (err == 0) {
-                       brcmf_fws_unlock(fws);
-                       err = brcmf_bus_txdata(bus, skb);
-                       brcmf_fws_lock(fws);
-               }
+               data_offset = brcmf_fws_hdrpush(fws, skb);
+               ifidx = brcmf_skb_if_flags_get_field(skb, INDEX);
+               brcmf_fws_unlock(fws);
+               err = brcmf_proto_txdata(fws->drvr, ifidx, data_offset, skb);
+               brcmf_fws_lock(fws);
                if (err)
                        brcmu_pkt_buf_free_skb(skb);
                return true;
        return 0;
 }
 
-static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
+static u8 brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
                                   struct sk_buff *p)
 {
        struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
                flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED;
        }
        brcmf_skb_htod_tag_set_field(p, FLAGS, flags);
-       brcmf_fws_hdrpush(fws, p);
+       return brcmf_fws_hdrpush(fws, p);
 }
 
 static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
 {
        struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb);
        struct brcmf_fws_mac_descriptor *entry;
-       struct brcmf_bus *bus = fws->drvr->bus_if;
        int rc;
        u8 ifidx;
+       u8 data_offset;
 
        entry = skcb->mac;
        if (IS_ERR(entry))
                return PTR_ERR(entry);
 
-       brcmf_fws_precommit_skb(fws, fifo, skb);
+       data_offset = brcmf_fws_precommit_skb(fws, fifo, skb);
        entry->transit_count++;
        if (entry->suppressed)
                entry->suppr_transit_count++;
+       ifidx = brcmf_skb_if_flags_get_field(skb, INDEX);
        brcmf_fws_unlock(fws);
-       rc = brcmf_bus_txdata(bus, skb);
+       rc = brcmf_proto_txdata(fws->drvr, ifidx, data_offset, skb);
        brcmf_fws_lock(fws);
        brcmf_dbg(DATA, "%s flags %X htod %X bus_tx %d\n", entry->name,
                  skcb->if_flags, skcb->htod, rc);
                                                        &skb, true);
                                ifidx = brcmf_skb_if_flags_get_field(skb,
                                                                     INDEX);
-                               brcmf_proto_hdrpush(drvr, ifidx, 0, skb);
-                               /* Use bus module to send data frame */
+                               /* Use proto layer to send data frame */
                                brcmf_fws_unlock(fws);
-                               ret = brcmf_bus_txdata(drvr->bus_if, skb);
+                               ret = brcmf_proto_txdata(drvr, ifidx, 0, skb);
                                brcmf_fws_lock(fws);
                                if (ret < 0)
                                        brcmf_txfinalize(drvr, skb, false);
 
 #define BRCMFMAC_PROTO_H
 
 struct brcmf_proto {
-       void (*hdrpush)(struct brcmf_pub *drvr, int ifidx, u8 offset,
-                       struct sk_buff *skb);
        int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
                       struct sk_buff *skb);
        int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
                          void *buf, uint len);
        int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
                        uint len);
+       int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset,
+                     struct sk_buff *skb);
        void *pd;
 };
 
 int brcmf_proto_attach(struct brcmf_pub *drvr);
 void brcmf_proto_detach(struct brcmf_pub *drvr);
 
-static inline void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
-                                      u8 offset, struct sk_buff *skb)
-{
-       drvr->proto->hdrpush(drvr, ifidx, offset, skb);
-}
 static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws,
                                      u8 *ifidx, struct sk_buff *skb)
 {
 {
        return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len);
 }
+static inline int brcmf_proto_txdata(struct brcmf_pub *drvr, int ifidx,
+                                      u8 offset, struct sk_buff *skb)
+{
+       return drvr->proto->txdata(drvr, ifidx, offset, skb);
+}
 
 
 #endif /* BRCMFMAC_PROTO_H */