aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c42
1 files changed, 13 insertions, 29 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index bba4ff04ee19..6255312d5986 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1187,6 +1187,7 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
1187 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; 1187 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
1188 u32 hslot; 1188 u32 hslot;
1189 int ret; 1189 int ret;
1190 u8 ifidx;
1190 1191
1191 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); 1192 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
1192 1193
@@ -1203,9 +1204,12 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
1203 1204
1204 entry->generation = genbit; 1205 entry->generation = genbit;
1205 1206
1206 ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb); 1207 ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
1208 if (ret == 0)
1209 ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
1210 skb);
1207 if (ret != 0) { 1211 if (ret != 0) {
1208 /* suppress q is full, drop this packet */ 1212 /* suppress q is full or hdrpull failed, drop this packet */
1209 brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, 1213 brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
1210 true); 1214 true);
1211 } else { 1215 } else {
@@ -1550,18 +1554,10 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
1550 bool first_time; 1554 bool first_time;
1551 int hslot = BRCMF_FWS_HANGER_MAXITEMS; 1555 int hslot = BRCMF_FWS_HANGER_MAXITEMS;
1552 u8 free_ctr; 1556 u8 free_ctr;
1553 u8 ifidx;
1554 u8 flags; 1557 u8 flags;
1555 1558
1556 first_time = skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED; 1559 first_time = skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED;
1557 1560
1558 if (!first_time) {
1559 rc = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, p);
1560 if (rc) {
1561 brcmf_err("hdrpull failed\n");
1562 return rc;
1563 }
1564 }
1565 brcmf_skb_if_flags_set_field(p, TRANSMIT, 1); 1561 brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
1566 brcmf_skb_htod_tag_set_field(p, FIFO, fifo); 1562 brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
1567 brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation); 1563 brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
@@ -1584,15 +1580,14 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
1584 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot); 1580 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
1585 brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr); 1581 brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr);
1586 entry->transit_count++; 1582 entry->transit_count++;
1587 }
1588
1589 brcmf_fws_hdrpush(fws, p);
1590 if (first_time) {
1591 rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot); 1583 rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
1592 if (rc) 1584 if (rc)
1593 brcmf_err("hanger push failed: rc=%d\n", rc); 1585 brcmf_err("hanger push failed: rc=%d\n", rc);
1594 } 1586 }
1595 1587
1588 if (rc == 0)
1589 brcmf_fws_hdrpush(fws, p);
1590
1596 return rc; 1591 return rc;
1597} 1592}
1598 1593
@@ -1613,7 +1608,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
1613 struct sk_buff *pktout; 1608 struct sk_buff *pktout;
1614 int rc = 0; 1609 int rc = 0;
1615 int hslot; 1610 int hslot;
1616 u8 ifidx;
1617 1611
1618 state = brcmf_skbcb(skb)->state; 1612 state = brcmf_skbcb(skb)->state;
1619 entry = brcmf_skbcb(skb)->mac; 1613 entry = brcmf_skbcb(skb)->mac;
@@ -1630,17 +1624,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
1630 } else { 1624 } else {
1631 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); 1625 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
1632 1626
1633 /* remove header first */
1634 rc = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
1635 if (rc) {
1636 brcmf_err("header removal failed\n");
1637 /* free the hanger slot */
1638 brcmf_fws_hanger_poppkt(&fws->hanger, hslot,
1639 &pktout, true);
1640 rc = -EINVAL;
1641 goto fail;
1642 }
1643
1644 /* delay-q packets are going to delay-q */ 1627 /* delay-q packets are going to delay-q */
1645 pktout = brcmu_pktq_penq_head(&entry->psq, 1628 pktout = brcmu_pktq_penq_head(&entry->psq,
1646 2 * fifo, skb); 1629 2 * fifo, skb);
@@ -1661,8 +1644,6 @@ brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
1661 rc = -ENOENT; 1644 rc = -ENOENT;
1662 } 1645 }
1663 1646
1664
1665fail:
1666 if (rc) { 1647 if (rc) {
1667 brcmf_fws_bustxfail(fws, skb); 1648 brcmf_fws_bustxfail(fws, skb);
1668 fws->stats.rollback_failed++; 1649 fws->stats.rollback_failed++;
@@ -1732,6 +1713,7 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
1732 struct brcmf_fws_mac_descriptor *entry; 1713 struct brcmf_fws_mac_descriptor *entry;
1733 struct brcmf_bus *bus = fws->drvr->bus_if; 1714 struct brcmf_bus *bus = fws->drvr->bus_if;
1734 int rc; 1715 int rc;
1716 u8 ifidx;
1735 1717
1736 entry = skcb->mac; 1718 entry = skcb->mac;
1737 if (IS_ERR(entry)) 1719 if (IS_ERR(entry))
@@ -1746,8 +1728,10 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
1746 brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags, 1728 brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags,
1747 skcb->htod); 1729 skcb->htod);
1748 rc = brcmf_bus_txdata(bus, skb); 1730 rc = brcmf_bus_txdata(bus, skb);
1749 if (rc < 0) 1731 if (rc < 0) {
1732 brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
1750 goto rollback; 1733 goto rollback;
1734 }
1751 1735
1752 entry->seq[fifo]++; 1736 entry->seq[fifo]++;
1753 fws->stats.pkt2bus++; 1737 fws->stats.pkt2bus++;