@@ -1263,6 +1263,7 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
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);
@@ -1279,9 +1280,12 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
entry->generation = genbit;
- ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb);
+ ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
+ if (ret == 0)
+ ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
+ skb);
if (ret != 0) {
- /* suppress q is full, drop this packet */
+ /* suppress q is full or hdrpull failed, drop this packet */
brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
true);
} else {
@@ -1585,18 +1589,10 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
bool first_time;
int hslot = BRCMF_FWS_HANGER_MAXITEMS;
u8 free_ctr;
- u8 ifidx;
u8 flags;
first_time = skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED;
- if (!first_time) {
- rc = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, p);
- if (rc) {
- brcmf_err("hdrpull failed\n");
- return rc;
- }
- }
brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
@@ -1619,15 +1615,14 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr);
entry->transit_count++;
- }
-
- brcmf_fws_hdrpush(fws, p);
- if (first_time) {
rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
if (rc)
brcmf_err("hanger push failed: rc=%d\n", rc);
}
+ if (rc == 0)
+ brcmf_fws_hdrpush(fws, p);
+
return rc;
}
@@ -1648,7 +1643,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
struct sk_buff *pktout;
int rc = 0;
int hslot;
- u8 ifidx;
state = brcmf_skbcb(skb)->state;
entry = brcmf_skbcb(skb)->mac;
@@ -1665,17 +1659,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
} else {
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
- /* remove header first */
- rc = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
- if (rc) {
- brcmf_err("header removal failed\n");
- /* free the hanger slot */
- brcmf_fws_hanger_poppkt(&fws->hanger, hslot,
- &pktout, true);
- rc = -EINVAL;
- goto fail;
- }
-
/* delay-q packets are going to delay-q */
pktout = brcmu_pktq_penq_head(&entry->psq,
2 * fifo, skb);
@@ -1696,8 +1679,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
rc = -ENOENT;
}
-
-fail:
if (rc) {
brcmf_fws_bustxfail(fws, skb);
fws->stats.rollback_failed++;
@@ -1767,6 +1748,7 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
struct brcmf_fws_mac_descriptor *entry;
struct brcmf_bus *bus = fws->drvr->bus_if;
int rc;
+ u8 ifidx;
entry = skcb->mac;
if (IS_ERR(entry))
@@ -1781,8 +1763,10 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags,
skcb->htod);
rc = brcmf_bus_txdata(bus, skb);
- if (rc < 0)
+ if (rc < 0) {
+ brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
goto rollback;
+ }
entry->seq[fifo]++;
fws->stats.pkt2bus++;