diff options
author | Hante Meuleman <meuleman@broadcom.com> | 2013-06-06 07:17:59 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-12 15:02:20 -0400 |
commit | 2747e5f7f83d215cbc9bdb66f69411ff3dedeeee (patch) | |
tree | fe80791b53190297b0b63ff782577fa641a81198 /drivers/net/wireless/brcm80211 | |
parent | 0d24b0eade7d4b6a5d06fe02645449b1fd0f8e17 (diff) |
brcmfmac: Signalling header push and pull on logic places.
Currently suppressed packets get enque-ed with header which
then gets pulled before transmit. It is more logical and clean
to pull the header on return and push it unconditionally on xmit.
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 42 |
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 | |||
1665 | fail: | ||
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++; |