.. | .. |
---|
1 | | -/* SPDX-License-Identifier: GPL-2.0 */ |
---|
2 | 1 | /* |
---|
3 | 2 | * DHD PROP_TXSTATUS Module. |
---|
4 | 3 | * |
---|
5 | | - * Copyright (C) 1999-2019, Broadcom Corporation |
---|
6 | | - * |
---|
| 4 | + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation |
---|
| 5 | + * |
---|
| 6 | + * Copyright (C) 1999-2017, Broadcom Corporation |
---|
| 7 | + * |
---|
7 | 8 | * Unless you and Broadcom execute a separate written software license |
---|
8 | 9 | * agreement governing use of this software, this software is licensed to you |
---|
9 | 10 | * under the terms of the GNU General Public License version 2 (the "GPL"), |
---|
10 | 11 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the |
---|
11 | 12 | * following added to such license: |
---|
12 | | - * |
---|
| 13 | + * |
---|
13 | 14 | * As a special exception, the copyright holders of this software give you |
---|
14 | 15 | * permission to link this software with independent modules, and to copy and |
---|
15 | 16 | * distribute the resulting executable under terms of your choice, provided that |
---|
.. | .. |
---|
17 | 18 | * the license of that module. An independent module is a module which is not |
---|
18 | 19 | * derived from this software. The special exception does not apply to any |
---|
19 | 20 | * modifications of the software. |
---|
20 | | - * |
---|
| 21 | + * |
---|
21 | 22 | * Notwithstanding the above, under no circumstances may you combine this |
---|
22 | 23 | * software in any way with any other Broadcom software provided under a license |
---|
23 | 24 | * other than the GPL, without Broadcom's express prior written consent. |
---|
.. | .. |
---|
25 | 26 | * |
---|
26 | 27 | * <<Broadcom-WL-IPTag/Open:>> |
---|
27 | 28 | * |
---|
28 | | - * $Id: dhd_wlfc.c 606400 2015-12-15 09:59:42Z $ |
---|
| 29 | + * $Id: dhd_wlfc.c 700323 2017-05-18 16:12:11Z $ |
---|
29 | 30 | * |
---|
30 | 31 | */ |
---|
31 | | - |
---|
32 | 32 | |
---|
33 | 33 | #include <typedefs.h> |
---|
34 | 34 | #include <osl.h> |
---|
.. | .. |
---|
39 | 39 | #include <dngl_stats.h> |
---|
40 | 40 | #include <dhd.h> |
---|
41 | 41 | |
---|
42 | | -#ifdef BCMDBUS /* an abstraction layer that hides details of the underlying bus, eg \ |
---|
43 | | - Linux USB */ |
---|
44 | | -#include <dbus.h> |
---|
45 | | -#else |
---|
46 | 42 | #include <dhd_bus.h> |
---|
47 | | -#endif /* BCMDBUS */ |
---|
48 | 43 | |
---|
49 | 44 | #include <dhd_dbg.h> |
---|
50 | 45 | |
---|
51 | 46 | #ifdef PROP_TXSTATUS /* a form of flow control between host and dongle */ |
---|
52 | 47 | #include <wlfc_proto.h> |
---|
53 | 48 | #include <dhd_wlfc.h> |
---|
54 | | -#endif |
---|
| 49 | +#endif // endif |
---|
55 | 50 | |
---|
56 | 51 | #ifdef DHDTCPACK_SUPPRESS |
---|
57 | 52 | #include <dhd_ip.h> |
---|
58 | 53 | #endif /* DHDTCPACK_SUPPRESS */ |
---|
59 | | - |
---|
60 | 54 | |
---|
61 | 55 | /* |
---|
62 | 56 | * wlfc naming and lock rules: |
---|
.. | .. |
---|
72 | 66 | #define WLFC_THREAD_RETRY_WAIT_MS 10000 /* 10 sec */ |
---|
73 | 67 | #endif /* defined (DHD_WLFC_THREAD) */ |
---|
74 | 68 | |
---|
75 | | -#if defined(BCMDBUS) |
---|
76 | | -extern int dhd_dbus_txdata(dhd_pub_t *dhdp, void *pktbuf); |
---|
77 | | -#endif |
---|
78 | | - |
---|
79 | 69 | #ifdef PROP_TXSTATUS |
---|
80 | 70 | |
---|
81 | 71 | #define DHD_WLFC_QMON_COMPLETE(entry) |
---|
82 | | - |
---|
83 | 72 | |
---|
84 | 73 | /** reordering related */ |
---|
85 | 74 | |
---|
.. | .. |
---|
132 | 121 | return; |
---|
133 | 122 | |
---|
134 | 123 | ASSERT(prec >= 0 && prec < pq->num_prec); |
---|
135 | | - /* queueing chains not allowed and no segmented SKB (Kernel-3.18.y) */ |
---|
136 | | - ASSERT(!((PKTLINK(p) != NULL) && (PKTLINK(p) != p))); |
---|
| 124 | + ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ |
---|
137 | 125 | |
---|
138 | 126 | ASSERT(!pktq_full(pq)); |
---|
139 | | - ASSERT(!pktq_pfull(pq, prec)); |
---|
| 127 | + ASSERT(!pktqprec_full(pq, prec)); |
---|
140 | 128 | |
---|
141 | 129 | q = &pq->q[prec]; |
---|
142 | 130 | |
---|
143 | | - PKTSETLINK(p, NULL); |
---|
144 | 131 | if (q->head == NULL) { |
---|
145 | 132 | /* empty queue */ |
---|
146 | 133 | q->head = p; |
---|
.. | .. |
---|
194 | 181 | |
---|
195 | 182 | exit: |
---|
196 | 183 | |
---|
197 | | - q->len++; |
---|
198 | | - pq->len++; |
---|
| 184 | + q->n_pkts++; |
---|
| 185 | + pq->n_pkts_tot++; |
---|
199 | 186 | |
---|
200 | 187 | if (pq->hi_prec < prec) |
---|
201 | 188 | pq->hi_prec = (uint8)prec; |
---|
.. | .. |
---|
504 | 491 | } |
---|
505 | 492 | } |
---|
506 | 493 | |
---|
507 | | - q->len--; |
---|
508 | | - pq->len--; |
---|
| 494 | + q->n_pkts--; |
---|
| 495 | + pq->n_pkts_tot--; |
---|
| 496 | + |
---|
| 497 | +#ifdef WL_TXQ_STALL |
---|
| 498 | + q->dequeue_count++; |
---|
| 499 | +#endif // endif |
---|
509 | 500 | |
---|
510 | 501 | PKTSETLINK(p, NULL); |
---|
511 | 502 | |
---|
.. | .. |
---|
593 | 584 | h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); |
---|
594 | 585 | if (PKTSUMNEEDED(p)) |
---|
595 | 586 | h->flags |= BDC_FLAG_SUM_NEEDED; |
---|
596 | | - |
---|
597 | 587 | |
---|
598 | 588 | h->priority = (PKTPRIO(p) & BDC_PRIORITY_MASK); |
---|
599 | 589 | h->flags2 = 0; |
---|
.. | .. |
---|
699 | 689 | void *pout = NULL; |
---|
700 | 690 | |
---|
701 | 691 | ASSERT(dhdp && p); |
---|
702 | | - ASSERT(prec >= 0 && prec <= WLFC_PSQ_PREC_COUNT); |
---|
| 692 | + if (prec < 0 || prec >= WLFC_PSQ_PREC_COUNT) { |
---|
| 693 | + ASSERT(0); |
---|
| 694 | + return BCME_BADARG; |
---|
| 695 | + } |
---|
703 | 696 | |
---|
704 | 697 | ctx = (athost_wl_status_info_t*)dhdp->wlfc_state; |
---|
705 | 698 | |
---|
.. | .. |
---|
774 | 767 | /* Fast case, precedence queue is not full and we are also not |
---|
775 | 768 | * exceeding total queue length |
---|
776 | 769 | */ |
---|
777 | | - if (!pktq_pfull(pq, prec) && !pktq_full(pq)) { |
---|
| 770 | + if (!pktqprec_full(pq, prec) && !pktq_full(pq)) { |
---|
778 | 771 | goto exit; |
---|
779 | 772 | } |
---|
780 | 773 | |
---|
781 | 774 | /* Determine precedence from which to evict packet, if any */ |
---|
782 | | - if (pktq_pfull(pq, prec)) { |
---|
| 775 | + if (pktqprec_full(pq, prec)) { |
---|
783 | 776 | eprec = prec; |
---|
784 | 777 | } else if (pktq_full(pq)) { |
---|
785 | 778 | p = pktq_peek_tail(pq, &eprec); |
---|
.. | .. |
---|
788 | 781 | return FALSE; |
---|
789 | 782 | } |
---|
790 | 783 | if ((eprec > prec) || (eprec < 0)) { |
---|
791 | | - if (!pktq_pempty(pq, prec)) { |
---|
| 784 | + if (!pktqprec_empty(pq, prec)) { |
---|
792 | 785 | eprec = prec; |
---|
793 | 786 | } else { |
---|
794 | 787 | return FALSE; |
---|
.. | .. |
---|
799 | 792 | /* Evict if needed */ |
---|
800 | 793 | if (eprec >= 0) { |
---|
801 | 794 | /* Detect queueing to unconfigured precedence */ |
---|
802 | | - ASSERT(!pktq_pempty(pq, eprec)); |
---|
| 795 | + ASSERT(!pktqprec_empty(pq, eprec)); |
---|
803 | 796 | /* Evict all fragmented frames */ |
---|
804 | 797 | dhd_prec_drop_pkts(dhdp, pq, eprec, _dhd_wlfc_prec_drop); |
---|
805 | 798 | } |
---|
.. | .. |
---|
940 | 933 | dhdp = (dhd_pub_t *)ctx->dhdp; |
---|
941 | 934 | ASSERT(dhdp); |
---|
942 | 935 | |
---|
943 | | - if (dhdp->skip_fc && dhdp->skip_fc()) |
---|
| 936 | + if (if_id >= 255) |
---|
| 937 | + return; |
---|
| 938 | + |
---|
| 939 | + if (dhdp->skip_fc && dhdp->skip_fc((void *)dhdp, if_id)) |
---|
944 | 940 | return; |
---|
945 | 941 | |
---|
946 | 942 | if ((ctx->hostif_flow_state[if_id] == OFF) && !_dhd_wlfc_allow_fc(ctx, if_id)) |
---|
947 | 943 | return; |
---|
948 | 944 | |
---|
949 | | - if ((pq->len <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) { |
---|
| 945 | + if ((pq->n_pkts_tot <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) { |
---|
950 | 946 | /* start traffic */ |
---|
951 | 947 | ctx->hostif_flow_state[if_id] = OFF; |
---|
952 | 948 | /* |
---|
953 | 949 | WLFC_DBGMESG(("qlen:%02d, if:%02d, ->OFF, start traffic %s()\n", |
---|
954 | | - pq->len, if_id, __FUNCTION__)); |
---|
| 950 | + pq->n_pkts_tot, if_id, __FUNCTION__)); |
---|
955 | 951 | */ |
---|
956 | 952 | WLFC_DBGMESG(("F")); |
---|
957 | 953 | |
---|
.. | .. |
---|
960 | 956 | ctx->toggle_host_if = 0; |
---|
961 | 957 | } |
---|
962 | 958 | |
---|
963 | | - if ((pq->len >= WLFC_FLOWCONTROL_HIWATER) && (ctx->hostif_flow_state[if_id] == OFF)) { |
---|
| 959 | + if (pq->n_pkts_tot >= WLFC_FLOWCONTROL_HIWATER && ctx->hostif_flow_state[if_id] == OFF) { |
---|
964 | 960 | /* stop traffic */ |
---|
965 | 961 | ctx->hostif_flow_state[if_id] = ON; |
---|
966 | 962 | /* |
---|
967 | 963 | WLFC_DBGMESG(("qlen:%02d, if:%02d, ->ON, stop traffic %s()\n", |
---|
968 | | - pq->len, if_id, __FUNCTION__)); |
---|
| 964 | + pq->n_pkts_tot, if_id, __FUNCTION__)); |
---|
969 | 965 | */ |
---|
970 | 966 | WLFC_DBGMESG(("N")); |
---|
971 | 967 | |
---|
.. | .. |
---|
1002 | 998 | DHD_PKTTAG_WLFCPKT_SET(PKTTAG(p), 1); |
---|
1003 | 999 | #ifdef PROP_TXSTATUS_DEBUG |
---|
1004 | 1000 | ctx->stats.signal_only_pkts_sent++; |
---|
1005 | | -#endif |
---|
| 1001 | +#endif // endif |
---|
1006 | 1002 | |
---|
1007 | 1003 | #if defined(BCMPCIE) |
---|
1008 | 1004 | rc = dhd_bus_txdata(dhdp->bus, p, ctx->host_ifidx); |
---|
1009 | | -#elif defined(BCMDBUS) |
---|
1010 | | - rc = dhd_dbus_txdata(dhdp, p); |
---|
1011 | 1005 | #else |
---|
1012 | 1006 | rc = dhd_bus_txdata(dhdp->bus, p); |
---|
1013 | | -#endif |
---|
| 1007 | +#endif // endif |
---|
1014 | 1008 | if (rc != BCME_OK) { |
---|
1015 | 1009 | _dhd_wlfc_pullheader(ctx, p); |
---|
1016 | 1010 | PKTFREE(ctx->osh, p, TRUE); |
---|
.. | .. |
---|
1041 | 1035 | bool rc = FALSE; |
---|
1042 | 1036 | |
---|
1043 | 1037 | if (entry->state == WLFC_STATE_CLOSE) { |
---|
1044 | | - if ((pktq_plen(&entry->psq, (prec << 1)) == 0) && |
---|
1045 | | - (pktq_plen(&entry->psq, ((prec << 1) + 1)) == 0)) { |
---|
| 1038 | + if ((pktqprec_n_pkts(&entry->psq, (prec << 1)) == 0) && |
---|
| 1039 | + (pktqprec_n_pkts(&entry->psq, ((prec << 1) + 1)) == 0)) { |
---|
1046 | 1040 | /* no packets in both 'normal' and 'suspended' queues */ |
---|
1047 | 1041 | if (entry->traffic_pending_bmp & NBITVAL(prec)) { |
---|
1048 | 1042 | rc = TRUE; |
---|
.. | .. |
---|
1218 | 1212 | #ifdef PROP_TXSTATUS_DEBUG |
---|
1219 | 1213 | h->items[hslot].push_time = |
---|
1220 | 1214 | OSL_SYSUPTIME(); |
---|
1221 | | -#endif |
---|
| 1215 | +#endif // endif |
---|
1222 | 1216 | } else { |
---|
1223 | 1217 | DHD_ERROR(("%s() hanger_pushpkt() failed, rc: %d\n", |
---|
1224 | 1218 | __FUNCTION__, rc)); |
---|
.. | .. |
---|
1235 | 1229 | h->items[hslot].pkt_txstatus = 0; |
---|
1236 | 1230 | h->items[hslot].state = WLFC_HANGER_ITEM_STATE_INUSE; |
---|
1237 | 1231 | } |
---|
1238 | | - } else if (!WLFC_GET_AFQ(dhdp->wlfc_mode)) { |
---|
1239 | | - /* clear hanger state */ |
---|
1240 | | - ((wlfc_hanger_t*)(ctx->hanger))->items[hslot].pkt_state = 0; |
---|
1241 | | - ((wlfc_hanger_t*)(ctx->hanger))->items[hslot].pkt_txstatus = 0; |
---|
1242 | 1232 | } |
---|
1243 | 1233 | |
---|
1244 | 1234 | if ((rc == BCME_OK) && header_needed) { |
---|
.. | .. |
---|
1259 | 1249 | _dhd_wlfc_is_destination_open(athost_wl_status_info_t* ctx, |
---|
1260 | 1250 | wlfc_mac_descriptor_t* entry, int prec) |
---|
1261 | 1251 | { |
---|
| 1252 | + wlfc_mac_descriptor_t* interfaces = ctx->destination_entries.interfaces; |
---|
| 1253 | + |
---|
1262 | 1254 | if (entry->interface_id >= WLFC_MAX_IFNUM) { |
---|
1263 | 1255 | ASSERT(&ctx->destination_entries.other == entry); |
---|
1264 | 1256 | return 1; |
---|
1265 | 1257 | } |
---|
1266 | 1258 | |
---|
1267 | | - if (ctx->destination_entries.interfaces[entry->interface_id].iftype == |
---|
| 1259 | + if (interfaces[entry->interface_id].iftype == |
---|
1268 | 1260 | WLC_E_IF_ROLE_P2P_GO) { |
---|
1269 | 1261 | /* - destination interface is of type p2p GO. |
---|
1270 | 1262 | For a p2pGO interface, if the destination is OPEN but the interface is |
---|
.. | .. |
---|
1279 | 1271 | } |
---|
1280 | 1272 | |
---|
1281 | 1273 | /* AP, p2p_go -> unicast desc entry, STA/p2p_cl -> interface desc. entry */ |
---|
1282 | | - if (((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) && |
---|
| 1274 | + if ((((entry->state == WLFC_STATE_CLOSE) || |
---|
| 1275 | + (interfaces[entry->interface_id].state == WLFC_STATE_CLOSE)) && |
---|
| 1276 | + (entry->requested_credit == 0) && |
---|
1283 | 1277 | (entry->requested_packet == 0)) || |
---|
1284 | 1278 | (!(entry->ac_bitmap & (1 << prec)))) { |
---|
1285 | 1279 | return 0; |
---|
.. | .. |
---|
1357 | 1351 | entry->requested_credit--; |
---|
1358 | 1352 | #ifdef PROP_TXSTATUS_DEBUG |
---|
1359 | 1353 | entry->dstncredit_sent_packets++; |
---|
1360 | | -#endif |
---|
| 1354 | +#endif // endif |
---|
1361 | 1355 | } else if (entry->requested_packet > 0) { |
---|
1362 | 1356 | entry->requested_packet--; |
---|
1363 | 1357 | DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p)); |
---|
.. | .. |
---|
1406 | 1400 | ctx->stats.delayq_full_error++; |
---|
1407 | 1401 | return BCME_ERROR; |
---|
1408 | 1402 | } |
---|
1409 | | - |
---|
1410 | 1403 | |
---|
1411 | 1404 | /* A packet has been pushed, update traffic availability bitmap, if applicable */ |
---|
1412 | 1405 | _dhd_wlfc_traffic_pending_check(ctx, entry, prec); |
---|
.. | .. |
---|
1543 | 1536 | /* Optimize flush, if pktq len = 0, just return. |
---|
1544 | 1537 | * pktq len of 0 means pktq's prec q's are all empty. |
---|
1545 | 1538 | */ |
---|
1546 | | - if (pq->len == 0) { |
---|
| 1539 | + if (pq->n_pkts_tot == 0) { |
---|
1547 | 1540 | return; |
---|
1548 | 1541 | } |
---|
1549 | 1542 | |
---|
.. | .. |
---|
1608 | 1601 | } |
---|
1609 | 1602 | PKTFREE(ctx->osh, p, dir); |
---|
1610 | 1603 | |
---|
1611 | | - q->len--; |
---|
1612 | | - pq->len--; |
---|
| 1604 | + q->n_pkts--; |
---|
| 1605 | + pq->n_pkts_tot--; |
---|
| 1606 | +#ifdef WL_TXQ_STALL |
---|
| 1607 | + q->dequeue_count++; |
---|
| 1608 | +#endif // endif |
---|
| 1609 | + |
---|
1613 | 1610 | p = (head ? q->head : PKTLINK(prev)); |
---|
1614 | 1611 | } else { |
---|
1615 | 1612 | prev = p; |
---|
.. | .. |
---|
1618 | 1615 | } |
---|
1619 | 1616 | |
---|
1620 | 1617 | if (q->head == NULL) { |
---|
1621 | | - ASSERT(q->len == 0); |
---|
| 1618 | + ASSERT(q->n_pkts == 0); |
---|
1622 | 1619 | q->tail = NULL; |
---|
1623 | 1620 | } |
---|
1624 | 1621 | |
---|
1625 | 1622 | } |
---|
1626 | 1623 | |
---|
1627 | 1624 | if (fn == NULL) |
---|
1628 | | - ASSERT(pq->len == 0); |
---|
| 1625 | + ASSERT(pq->n_pkts_tot == 0); |
---|
1629 | 1626 | } /* _dhd_wlfc_pktq_flush */ |
---|
1630 | | - |
---|
1631 | | -#ifndef BCMDBUS |
---|
1632 | 1627 | |
---|
1633 | 1628 | /** !BCMDBUS specific function. Dequeues a packet from the caller supplied queue. */ |
---|
1634 | 1629 | static void* |
---|
.. | .. |
---|
1666 | 1661 | } |
---|
1667 | 1662 | } |
---|
1668 | 1663 | |
---|
1669 | | - q->len--; |
---|
| 1664 | + q->n_pkts--; |
---|
1670 | 1665 | |
---|
1671 | | - pq->len--; |
---|
| 1666 | + pq->n_pkts_tot--; |
---|
| 1667 | + |
---|
| 1668 | +#ifdef WL_TXQ_STALL |
---|
| 1669 | + q->dequeue_count++; |
---|
| 1670 | +#endif // endif |
---|
1672 | 1671 | |
---|
1673 | 1672 | PKTSETLINK(p, NULL); |
---|
1674 | 1673 | |
---|
.. | .. |
---|
1707 | 1706 | } |
---|
1708 | 1707 | dhd_os_sdunlock_txq(dhd); |
---|
1709 | 1708 | |
---|
1710 | | - |
---|
1711 | 1709 | while ((pkt = head)) { |
---|
1712 | 1710 | head = PKTLINK(pkt); |
---|
1713 | 1711 | PKTSETLINK(pkt, NULL); |
---|
.. | .. |
---|
1736 | 1734 | } |
---|
1737 | 1735 | } /* _dhd_wlfc_cleanup_txq */ |
---|
1738 | 1736 | |
---|
1739 | | -#endif /* !BCMDBUS */ |
---|
1740 | | - |
---|
1741 | 1737 | /** called during eg detach */ |
---|
1742 | 1738 | void |
---|
1743 | 1739 | _dhd_wlfc_cleanup(dhd_pub_t *dhd, f_processpkt_t fn, void *arg) |
---|
.. | .. |
---|
1755 | 1751 | /* |
---|
1756 | 1752 | * flush sequence should be txq -> psq -> hanger/afq, hanger has to be last one |
---|
1757 | 1753 | */ |
---|
1758 | | -#ifndef BCMDBUS |
---|
1759 | 1754 | /* flush bus->txq */ |
---|
1760 | 1755 | _dhd_wlfc_cleanup_txq(dhd, fn, arg); |
---|
1761 | | -#endif /* BCMDBUS */ |
---|
1762 | 1756 | |
---|
1763 | 1757 | /* flush psq, search all entries, include nodes as well as interfaces */ |
---|
1764 | 1758 | total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t); |
---|
.. | .. |
---|
1767 | 1761 | for (i = 0; i < total_entries; i++) { |
---|
1768 | 1762 | if (table[i].occupied) { |
---|
1769 | 1763 | /* release packets held in PSQ (both delayed and suppressed) */ |
---|
1770 | | - if (table[i].psq.len) { |
---|
| 1764 | + if (table[i].psq.n_pkts_tot) { |
---|
1771 | 1765 | WLFC_DBGMESG(("%s(): PSQ[%d].len = %d\n", |
---|
1772 | | - __FUNCTION__, i, table[i].psq.len)); |
---|
| 1766 | + __FUNCTION__, i, table[i].psq.n_pkts_tot)); |
---|
1773 | 1767 | _dhd_wlfc_pktq_flush(wlfc, &table[i].psq, TRUE, |
---|
1774 | 1768 | fn, arg, Q_TYPE_PSQ); |
---|
1775 | 1769 | } |
---|
1776 | 1770 | |
---|
1777 | 1771 | /* free packets held in AFQ */ |
---|
1778 | | - if (WLFC_GET_AFQ(dhd->wlfc_mode) && (table[i].afq.len)) { |
---|
| 1772 | + if (WLFC_GET_AFQ(dhd->wlfc_mode) && (table[i].afq.n_pkts_tot)) { |
---|
1779 | 1773 | _dhd_wlfc_pktq_flush(wlfc, &table[i].afq, TRUE, |
---|
1780 | 1774 | fn, arg, Q_TYPE_AFQ); |
---|
1781 | 1775 | } |
---|
.. | .. |
---|
1819 | 1813 | { |
---|
1820 | 1814 | int rc = BCME_OK; |
---|
1821 | 1815 | |
---|
1822 | | - |
---|
1823 | 1816 | if ((action == eWLFC_MAC_ENTRY_ACTION_ADD) || (action == eWLFC_MAC_ENTRY_ACTION_UPDATE)) { |
---|
1824 | 1817 | entry->occupied = 1; |
---|
1825 | 1818 | entry->state = WLFC_STATE_OPEN; |
---|
.. | .. |
---|
1843 | 1836 | dhd_pub_t *dhdp = (dhd_pub_t *)(ctx->dhdp); |
---|
1844 | 1837 | |
---|
1845 | 1838 | pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN); |
---|
| 1839 | + _dhd_wlfc_flow_control_check(ctx, &entry->psq, ifid); |
---|
1846 | 1840 | |
---|
1847 | 1841 | if (WLFC_GET_AFQ(dhdp->wlfc_mode)) { |
---|
1848 | 1842 | pktq_init(&entry->afq, WLFC_AFQ_PREC_COUNT, WLFC_PSQ_LEN); |
---|
.. | .. |
---|
1898 | 1892 | } |
---|
1899 | 1893 | return rc; |
---|
1900 | 1894 | } /* _dhd_wlfc_mac_entry_update */ |
---|
1901 | | - |
---|
1902 | 1895 | |
---|
1903 | 1896 | #ifdef LIMIT_BORROW |
---|
1904 | 1897 | |
---|
.. | .. |
---|
2189 | 2182 | } |
---|
2190 | 2183 | } |
---|
2191 | 2184 | |
---|
2192 | | - q->len--; |
---|
2193 | | - pq->len--; |
---|
| 2185 | + q->n_pkts--; |
---|
| 2186 | + pq->n_pkts_tot--; |
---|
| 2187 | + |
---|
| 2188 | +#ifdef WL_TXQ_STALL |
---|
| 2189 | + q->dequeue_count++; |
---|
| 2190 | +#endif // endif |
---|
| 2191 | + |
---|
2194 | 2192 | ctx->pkt_cnt_in_q[DHD_PKTTAG_IF(PKTTAG(p))][prec]--; |
---|
2195 | 2193 | ctx->pkt_cnt_per_ac[prec]--; |
---|
2196 | 2194 | |
---|
.. | .. |
---|
2232 | 2230 | if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) { |
---|
2233 | 2231 | memcpy(&seq, pkt_info + WLFC_CTL_VALUE_LEN_TXSTATUS, WLFC_CTL_VALUE_LEN_SEQ); |
---|
2234 | 2232 | seq = ltoh16(seq); |
---|
2235 | | - seq_fromfw = WL_SEQ_GET_FROMFW(seq); |
---|
| 2233 | + seq_fromfw = GET_WL_HAS_ASSIGNED_SEQ(seq); |
---|
2236 | 2234 | seq_num = WL_SEQ_GET_NUM(seq); |
---|
2237 | 2235 | } |
---|
2238 | 2236 | |
---|
.. | .. |
---|
2250 | 2248 | remove_from_hanger = 0; |
---|
2251 | 2249 | } else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) { |
---|
2252 | 2250 | wlfc->stats.wlc_tossed_pkts += len; |
---|
2253 | | - } |
---|
2254 | | - |
---|
2255 | | - else if (status_flag == WLFC_CTL_PKTFLAG_SUPPRESS_ACKED) { |
---|
| 2251 | + } else if (status_flag == WLFC_CTL_PKTFLAG_SUPPRESS_ACKED) { |
---|
2256 | 2252 | wlfc->stats.pkt_freed += len; |
---|
| 2253 | + } else if (status_flag == WLFC_CTL_PKTFLAG_EXPIRED) { |
---|
| 2254 | + wlfc->stats.pkt_exptime += len; |
---|
| 2255 | + } else if (status_flag == WLFC_CTL_PKTFLAG_DROPPED) { |
---|
| 2256 | + wlfc->stats.pkt_dropped += len; |
---|
2257 | 2257 | } |
---|
2258 | 2258 | |
---|
2259 | 2259 | if (dhd->proptxstatus_txstatus_ignore) { |
---|
.. | .. |
---|
2326 | 2326 | uint32 delta; |
---|
2327 | 2327 | old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[hslot].push_time; |
---|
2328 | 2328 | |
---|
2329 | | - |
---|
2330 | 2329 | wlfc->stats.latency_sample_count++; |
---|
2331 | 2330 | if (new_t > old_t) |
---|
2332 | 2331 | delta = new_t - old_t; |
---|
.. | .. |
---|
2357 | 2356 | } |
---|
2358 | 2357 | #ifdef PROP_TXSTATUS_DEBUG |
---|
2359 | 2358 | entry->dstncredit_acks++; |
---|
2360 | | -#endif |
---|
| 2359 | +#endif // endif |
---|
2361 | 2360 | } |
---|
2362 | 2361 | |
---|
2363 | 2362 | if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) || |
---|
.. | .. |
---|
2366 | 2365 | WL_TXSTATUS_SET_GENERATION(DHD_PKTTAG_H2DTAG(PKTTAG(pktbuf)), gen); |
---|
2367 | 2366 | |
---|
2368 | 2367 | if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) { |
---|
2369 | | - WL_SEQ_SET_FROMDRV(DHD_PKTTAG_H2DSEQ(PKTTAG(pktbuf)), seq_fromfw); |
---|
| 2368 | + WL_SEQ_SET_REUSE(DHD_PKTTAG_H2DSEQ(PKTTAG(pktbuf)), seq_fromfw); |
---|
2370 | 2369 | WL_SEQ_SET_NUM(DHD_PKTTAG_H2DSEQ(PKTTAG(pktbuf)), seq_num); |
---|
2371 | 2370 | } |
---|
2372 | 2371 | |
---|
.. | .. |
---|
2438 | 2437 | for (i = 0; i < WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK; i++) { |
---|
2439 | 2438 | #ifdef PROP_TXSTATUS_DEBUG |
---|
2440 | 2439 | wlfc->stats.fifo_credits_back[i] += credits[i]; |
---|
2441 | | -#endif |
---|
| 2440 | +#endif // endif |
---|
2442 | 2441 | |
---|
2443 | 2442 | /* update FIFO credits */ |
---|
2444 | 2443 | if (dhd->proptxstatus_mode == WLFC_FCMODE_EXPLICIT_CREDIT) |
---|
.. | .. |
---|
2480 | 2479 | return BCME_OK; |
---|
2481 | 2480 | } /* _dhd_wlfc_fifocreditback_indicate */ |
---|
2482 | 2481 | |
---|
2483 | | -#ifndef BCMDBUS |
---|
2484 | | - |
---|
2485 | 2482 | /** !BCMDBUS specific function */ |
---|
2486 | 2483 | static void |
---|
2487 | 2484 | _dhd_wlfc_suppress_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg) |
---|
.. | .. |
---|
2516 | 2513 | PKTSETLINK(pkt, NULL); |
---|
2517 | 2514 | |
---|
2518 | 2515 | entry = _dhd_wlfc_find_table_entry(wlfc, pkt); |
---|
2519 | | - if (entry) { |
---|
2520 | | - if (entry->onbus_pkts_count > 0) |
---|
2521 | | - entry->onbus_pkts_count--; |
---|
2522 | | - if (entry->suppressed && |
---|
2523 | | - (!entry->onbus_pkts_count) && |
---|
2524 | | - (!entry->suppr_transit_count)) |
---|
2525 | | - entry->suppressed = FALSE; |
---|
| 2516 | + if (!entry) { |
---|
| 2517 | + PKTFREE(dhd->osh, pkt, TRUE); |
---|
| 2518 | + continue; |
---|
2526 | 2519 | } |
---|
2527 | | - |
---|
| 2520 | + if (entry->onbus_pkts_count > 0) { |
---|
| 2521 | + entry->onbus_pkts_count--; |
---|
| 2522 | + } |
---|
| 2523 | + if (entry->suppressed && |
---|
| 2524 | + (!entry->onbus_pkts_count) && |
---|
| 2525 | + (!entry->suppr_transit_count)) { |
---|
| 2526 | + entry->suppressed = FALSE; |
---|
| 2527 | + } |
---|
2528 | 2528 | /* fake a suppression txstatus */ |
---|
2529 | 2529 | htod = DHD_PKTTAG_H2DTAG(PKTTAG(pkt)); |
---|
2530 | 2530 | WL_TXSTATUS_SET_FLAGS(htod, WLFC_CTL_PKTFLAG_WLSUPPRESS); |
---|
.. | .. |
---|
2533 | 2533 | memcpy(results, &htod, WLFC_CTL_VALUE_LEN_TXSTATUS); |
---|
2534 | 2534 | if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) { |
---|
2535 | 2535 | htodseq = DHD_PKTTAG_H2DSEQ(PKTTAG(pkt)); |
---|
2536 | | - if (WL_SEQ_GET_FROMDRV(htodseq)) { |
---|
2537 | | - WL_SEQ_SET_FROMFW(htodseq, 1); |
---|
2538 | | - WL_SEQ_SET_FROMDRV(htodseq, 0); |
---|
| 2536 | + if (IS_WL_TO_REUSE_SEQ(htodseq)) { |
---|
| 2537 | + SET_WL_HAS_ASSIGNED_SEQ(htodseq); |
---|
| 2538 | + RESET_WL_TO_REUSE_SEQ(htodseq); |
---|
2539 | 2539 | } |
---|
2540 | 2540 | htodseq = htol16(htodseq); |
---|
2541 | 2541 | memcpy(results + WLFC_CTL_VALUE_LEN_TXSTATUS, &htodseq, |
---|
.. | .. |
---|
2557 | 2557 | _dhd_wlfc_fifocreditback_indicate(dhd, credits); |
---|
2558 | 2558 | } |
---|
2559 | 2559 | } /* _dhd_wlfc_suppress_txq */ |
---|
2560 | | - |
---|
2561 | | -#endif /* !BCMDBUS */ |
---|
2562 | 2560 | |
---|
2563 | 2561 | static int |
---|
2564 | 2562 | _dhd_wlfc_dbg_senum_check(dhd_pub_t *dhd, uint8 *value) |
---|
.. | .. |
---|
2643 | 2641 | uint8 ifid; |
---|
2644 | 2642 | uint8* ea; |
---|
2645 | 2643 | |
---|
2646 | | - WLFC_DBGMESG(("%s(), mac [%02x:%02x:%02x:%02x:%02x:%02x],%s,idx:%d,id:0x%02x\n", |
---|
2647 | | - __FUNCTION__, value[2], value[3], value[4], value[5], value[6], value[7], |
---|
| 2644 | + WLFC_DBGMESG(("%s(), mac ["MACDBG"],%s,idx:%d,id:0x%02x\n", |
---|
| 2645 | + __FUNCTION__, MAC2STRDBG(&value[2]), |
---|
2648 | 2646 | ((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"), |
---|
2649 | 2647 | WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0])); |
---|
2650 | 2648 | |
---|
.. | .. |
---|
2828 | 2826 | _dhd_wlfc_reorderinfo_indicate(uint8 *val, uint8 len, uchar *info_buf, uint *info_len) |
---|
2829 | 2827 | { |
---|
2830 | 2828 | if (info_len) { |
---|
2831 | | - if (info_buf) { |
---|
| 2829 | + /* Check copy length to avoid buffer overrun. In case of length exceeding |
---|
| 2830 | + * WLHOST_REORDERDATA_TOTLEN, return failure instead sending incomplete result |
---|
| 2831 | + * of length WLHOST_REORDERDATA_TOTLEN |
---|
| 2832 | + */ |
---|
| 2833 | + if ((info_buf) && (len <= WLHOST_REORDERDATA_TOTLEN)) { |
---|
2832 | 2834 | bcopy(val, info_buf, len); |
---|
2833 | 2835 | *info_len = len; |
---|
2834 | 2836 | } else { |
---|
.. | .. |
---|
2923 | 2925 | wlfc->allow_credit_borrow = 0; |
---|
2924 | 2926 | wlfc->single_ac = 0; |
---|
2925 | 2927 | wlfc->single_ac_timestamp = 0; |
---|
2926 | | - |
---|
2927 | 2928 | |
---|
2928 | 2929 | exit: |
---|
2929 | 2930 | dhd_os_wlfc_unblock(dhd); |
---|
.. | .. |
---|
3082 | 3083 | _dhd_wlfc_interface_update(dhd, value, type); |
---|
3083 | 3084 | } |
---|
3084 | 3085 | |
---|
3085 | | -#ifndef BCMDBUS |
---|
3086 | 3086 | if (entry && WLFC_GET_REORDERSUPP(dhd->wlfc_mode)) { |
---|
3087 | 3087 | /* suppress all packets for this mac entry from bus->txq */ |
---|
3088 | 3088 | _dhd_wlfc_suppress_txq(dhd, _dhd_wlfc_entrypkt_fn, entry); |
---|
3089 | 3089 | } |
---|
3090 | | -#endif /* !BCMDBUS */ |
---|
3091 | 3090 | } /* while */ |
---|
3092 | 3091 | |
---|
3093 | 3092 | if (remainder != 0 && wlfc) { |
---|
.. | .. |
---|
3101 | 3100 | |
---|
3102 | 3101 | dhd_os_wlfc_unblock(dhd); |
---|
3103 | 3102 | return BCME_OK; |
---|
3104 | | -} /* dhd_wlfc_parse_header_info */ |
---|
| 3103 | +} |
---|
3105 | 3104 | |
---|
3106 | 3105 | KERNEL_THREAD_RETURN_TYPE |
---|
3107 | 3106 | dhd_wlfc_transfer_packets(void *data) |
---|
.. | .. |
---|
3112 | 3111 | athost_wl_status_info_t* ctx; |
---|
3113 | 3112 | int bus_retry_count = 0; |
---|
3114 | 3113 | int pkt_send = 0; |
---|
| 3114 | + int pkt_send_per_ac = 0; |
---|
3115 | 3115 | |
---|
3116 | 3116 | uint8 tx_map = 0; /* packets (send + in queue), Bitmask for 4 ACs + BC/MC */ |
---|
3117 | 3117 | uint8 rx_map = 0; /* received packets, Bitmask for 4 ACs + BC/MC */ |
---|
.. | .. |
---|
3179 | 3179 | |
---|
3180 | 3180 | tx_map |= (1 << ac); |
---|
3181 | 3181 | single_ac = ac + 1; |
---|
3182 | | - while (FALSE == dhdp->proptxstatus_txoff) { |
---|
| 3182 | + pkt_send_per_ac = 0; |
---|
| 3183 | + while ((FALSE == dhdp->proptxstatus_txoff) && |
---|
| 3184 | + (pkt_send_per_ac < WLFC_PACKET_BOUND)) { |
---|
3183 | 3185 | /* packets from delayQ with less priority are fresh and |
---|
3184 | 3186 | * they'd need header and have no MAC entry |
---|
3185 | 3187 | */ |
---|
.. | .. |
---|
3199 | 3201 | no_credit = FALSE; |
---|
3200 | 3202 | } |
---|
3201 | 3203 | } |
---|
3202 | | -#endif |
---|
| 3204 | +#endif // endif |
---|
3203 | 3205 | commit_info.needs_hdr = 1; |
---|
3204 | 3206 | commit_info.mac_entry = NULL; |
---|
3205 | 3207 | commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac, |
---|
.. | .. |
---|
3215 | 3217 | if (lender != -1 && dhdp->wlfc_borrow_allowed) { |
---|
3216 | 3218 | _dhd_wlfc_return_credit(ctx, lender, ac); |
---|
3217 | 3219 | } |
---|
3218 | | -#endif |
---|
| 3220 | +#endif // endif |
---|
3219 | 3221 | break; |
---|
3220 | 3222 | } |
---|
3221 | 3223 | |
---|
.. | .. |
---|
3229 | 3231 | /* Bus commits may fail (e.g. flow control); abort after retries */ |
---|
3230 | 3232 | if (rc == BCME_OK) { |
---|
3231 | 3233 | pkt_send++; |
---|
| 3234 | + pkt_send_per_ac++; |
---|
3232 | 3235 | if (commit_info.ac_fifo_credit_spent && (lender == -1)) { |
---|
3233 | 3236 | ctx->FIFO_credit[ac]--; |
---|
3234 | 3237 | } |
---|
.. | .. |
---|
3237 | 3240 | dhdp->wlfc_borrow_allowed) { |
---|
3238 | 3241 | _dhd_wlfc_return_credit(ctx, lender, ac); |
---|
3239 | 3242 | } |
---|
3240 | | -#endif |
---|
| 3243 | +#endif // endif |
---|
3241 | 3244 | } else { |
---|
3242 | 3245 | #ifdef LIMIT_BORROW |
---|
3243 | 3246 | if (lender != -1 && dhdp->wlfc_borrow_allowed) { |
---|
3244 | 3247 | _dhd_wlfc_return_credit(ctx, lender, ac); |
---|
3245 | 3248 | } |
---|
3246 | | -#endif |
---|
| 3249 | +#endif // endif |
---|
3247 | 3250 | bus_retry_count++; |
---|
3248 | 3251 | if (bus_retry_count >= BUS_RETRIES) { |
---|
3249 | 3252 | DHD_ERROR(("%s: bus error %d\n", __FUNCTION__, rc)); |
---|
.. | .. |
---|
3316 | 3319 | } |
---|
3317 | 3320 | else |
---|
3318 | 3321 | break; |
---|
3319 | | -#endif |
---|
| 3322 | +#endif // endif |
---|
3320 | 3323 | commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac, |
---|
3321 | 3324 | &(commit_info.ac_fifo_credit_spent), |
---|
3322 | 3325 | &(commit_info.needs_hdr), |
---|
.. | .. |
---|
3326 | 3329 | /* before borrow only one ac exists and now this only ac is empty */ |
---|
3327 | 3330 | #ifdef LIMIT_BORROW |
---|
3328 | 3331 | _dhd_wlfc_return_credit(ctx, lender, ac); |
---|
3329 | | -#endif |
---|
| 3332 | +#endif // endif |
---|
3330 | 3333 | break; |
---|
3331 | 3334 | } |
---|
3332 | 3335 | |
---|
.. | .. |
---|
3342 | 3345 | if (commit_info.ac_fifo_credit_spent) { |
---|
3343 | 3346 | #ifndef LIMIT_BORROW |
---|
3344 | 3347 | ctx->FIFO_credit[ac]--; |
---|
3345 | | -#endif |
---|
| 3348 | +#endif // endif |
---|
3346 | 3349 | } else { |
---|
3347 | 3350 | #ifdef LIMIT_BORROW |
---|
3348 | 3351 | _dhd_wlfc_return_credit(ctx, lender, ac); |
---|
3349 | | -#endif |
---|
| 3352 | +#endif // endif |
---|
3350 | 3353 | } |
---|
3351 | 3354 | } else { |
---|
3352 | 3355 | #ifdef LIMIT_BORROW |
---|
3353 | 3356 | _dhd_wlfc_return_credit(ctx, lender, ac); |
---|
3354 | | -#endif |
---|
| 3357 | +#endif // endif |
---|
3355 | 3358 | bus_retry_count++; |
---|
3356 | 3359 | if (bus_retry_count >= BUS_RETRIES) { |
---|
3357 | 3360 | DHD_ERROR(("%s: bus error %d\n", __FUNCTION__, rc)); |
---|
.. | .. |
---|
3414 | 3417 | } |
---|
3415 | 3418 | |
---|
3416 | 3419 | ctx = (athost_wl_status_info_t*)dhdp->wlfc_state; |
---|
3417 | | - |
---|
3418 | | -#ifdef BCMDBUS |
---|
3419 | | - if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN)) { |
---|
3420 | | - if (pktbuf) { |
---|
3421 | | - PKTFREE(ctx->osh, pktbuf, TRUE); |
---|
3422 | | - rc = BCME_OK; |
---|
3423 | | - } |
---|
3424 | | - goto exit; |
---|
3425 | | - } |
---|
3426 | | -#endif |
---|
3427 | 3420 | |
---|
3428 | 3421 | if (dhdp->proptxstatus_module_ignore) { |
---|
3429 | 3422 | if (pktbuf) { |
---|
.. | .. |
---|
3503 | 3496 | if (DHD_PKTTAG_SIGNALONLY(PKTTAG(txp))) { |
---|
3504 | 3497 | #ifdef PROP_TXSTATUS_DEBUG |
---|
3505 | 3498 | wlfc->stats.signal_only_pkts_freed++; |
---|
3506 | | -#endif |
---|
| 3499 | +#endif // endif |
---|
3507 | 3500 | /* is this a signal-only packet? */ |
---|
3508 | 3501 | _dhd_wlfc_pullheader(wlfc, txp); |
---|
3509 | 3502 | PKTFREE(wlfc->osh, txp, TRUE); |
---|
.. | .. |
---|
3546 | 3539 | } |
---|
3547 | 3540 | } |
---|
3548 | 3541 | |
---|
3549 | | - ASSERT(entry->onbus_pkts_count > 0); |
---|
3550 | 3542 | if (entry->onbus_pkts_count > 0) |
---|
3551 | 3543 | entry->onbus_pkts_count--; |
---|
3552 | 3544 | if (entry->suppressed && |
---|
.. | .. |
---|
3585 | 3577 | WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE | |
---|
3586 | 3578 | WLFC_FLAGS_HOST_RXRERODER_ACTIVE; |
---|
3587 | 3579 | |
---|
3588 | | - |
---|
3589 | 3580 | /* |
---|
3590 | 3581 | try to enable/disable signaling by sending "tlv" iovar. if that fails, |
---|
3591 | 3582 | fallback to no flow control? Print a message for now. |
---|
.. | .. |
---|
3610 | 3601 | DHD_INFO(("%s: query wlfc_mode succeed, fw_caps=0x%x\n", __FUNCTION__, fw_caps)); |
---|
3611 | 3602 | |
---|
3612 | 3603 | if (WLFC_IS_OLD_DEF(fw_caps)) { |
---|
3613 | | -#ifdef BCMDBUS |
---|
3614 | | - mode = WLFC_MODE_HANGER; |
---|
3615 | | -#else |
---|
3616 | 3604 | /* enable proptxtstatus v2 by default */ |
---|
3617 | 3605 | mode = WLFC_MODE_AFQ; |
---|
3618 | | -#endif /* BCMDBUS */ |
---|
3619 | 3606 | } else { |
---|
3620 | 3607 | WLFC_SET_AFQ(mode, WLFC_GET_AFQ(fw_caps)); |
---|
3621 | | -#ifdef BCMDBUS |
---|
3622 | | - WLFC_SET_AFQ(mode, 0); |
---|
3623 | | -#endif /* BCMDBUS */ |
---|
3624 | | - WLFC_SET_REUSESEQ(mode, WLFC_GET_REUSESEQ(fw_caps)); |
---|
3625 | 3608 | WLFC_SET_REORDERSUPP(mode, WLFC_GET_REORDERSUPP(fw_caps)); |
---|
3626 | 3609 | } |
---|
3627 | 3610 | ret = dhd_wl_ioctl_set_intiovar(dhd, "wlfc_mode", mode, WLC_SET_VAR, TRUE, 0); |
---|
.. | .. |
---|
3641 | 3624 | DHD_INFO(("dhd_wlfc_init(): wlfc_mode=0x%x, ret=%d\n", dhd->wlfc_mode, ret)); |
---|
3642 | 3625 | #ifdef LIMIT_BORROW |
---|
3643 | 3626 | dhd->wlfc_borrow_allowed = TRUE; |
---|
3644 | | -#endif |
---|
| 3627 | +#endif // endif |
---|
3645 | 3628 | dhd_os_wlfc_unblock(dhd); |
---|
3646 | 3629 | |
---|
3647 | 3630 | if (dhd->plat_init) |
---|
.. | .. |
---|
3701 | 3684 | return WLFC_UNSUPPORTED; |
---|
3702 | 3685 | } |
---|
3703 | 3686 | |
---|
3704 | | -#ifndef BCMDBUS |
---|
3705 | 3687 | _dhd_wlfc_cleanup_txq(dhd, fn, arg); |
---|
3706 | | -#endif /* !BCMDBUS */ |
---|
3707 | 3688 | |
---|
3708 | 3689 | dhd_os_wlfc_unblock(dhd); |
---|
3709 | 3690 | |
---|
.. | .. |
---|
3794 | 3775 | _dhd_wlfc_hanger_delete(dhd, h); |
---|
3795 | 3776 | } |
---|
3796 | 3777 | |
---|
3797 | | - |
---|
3798 | 3778 | /* free top structure */ |
---|
3799 | 3779 | DHD_OS_PREFREE(dhd, dhd->wlfc_state, |
---|
3800 | 3780 | sizeof(athost_wl_status_info_t)); |
---|
.. | .. |
---|
3862 | 3842 | #ifdef LIMIT_BORROW |
---|
3863 | 3843 | int dhd_wlfc_disable_credit_borrow_event(dhd_pub_t *dhdp, uint8* event_data) |
---|
3864 | 3844 | { |
---|
3865 | | - int rc; |
---|
3866 | | - if (dhdp == NULL) { |
---|
| 3845 | + if (dhdp == NULL || event_data == NULL) { |
---|
3867 | 3846 | DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__)); |
---|
3868 | 3847 | return BCME_BADARG; |
---|
3869 | 3848 | } |
---|
.. | .. |
---|
3871 | 3850 | dhdp->wlfc_borrow_allowed = (bool)(*(uint32 *)event_data); |
---|
3872 | 3851 | dhd_os_wlfc_unblock(dhdp); |
---|
3873 | 3852 | |
---|
3874 | | - return rc; |
---|
| 3853 | + return BCME_OK; |
---|
3875 | 3854 | } |
---|
3876 | 3855 | #endif /* LIMIT_BORROW */ |
---|
3877 | 3856 | |
---|
.. | .. |
---|
3987 | 3966 | |
---|
3988 | 3967 | ea = interfaces[i].ea; |
---|
3989 | 3968 | bcm_bprintf(strbuf, "INTERFACE[%d].ea = " |
---|
3990 | | - "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d, type: %s " |
---|
| 3969 | + "["MACDBG"], if:%d, type: %s " |
---|
3991 | 3970 | "netif_flow_control:%s\n", i, |
---|
3992 | | - ea[0], ea[1], ea[2], ea[3], ea[4], ea[5], |
---|
3993 | | - interfaces[i].interface_id, |
---|
| 3971 | + MAC2STRDBG(ea), interfaces[i].interface_id, |
---|
3994 | 3972 | iftype_desc, ((wlfc->hostif_flow_state[i] == OFF) |
---|
3995 | 3973 | ? " OFF":" ON")); |
---|
3996 | 3974 | |
---|
.. | .. |
---|
3998 | 3976 | "(trans,supp_trans,onbus)" |
---|
3999 | 3977 | "= (%d,%s,%d),(%d,%d,%d)\n", |
---|
4000 | 3978 | i, |
---|
4001 | | - interfaces[i].psq.len, |
---|
| 3979 | + interfaces[i].psq.n_pkts_tot, |
---|
4002 | 3980 | ((interfaces[i].state == |
---|
4003 | 3981 | WLFC_STATE_OPEN) ? "OPEN":"CLOSE"), |
---|
4004 | 3982 | interfaces[i].requested_credit, |
---|
.. | .. |
---|
4011 | 3989 | "(delay3,sup3,afq3),(delay4,sup4,afq4) = (%d,%d,%d)," |
---|
4012 | 3990 | "(%d,%d,%d),(%d,%d,%d),(%d,%d,%d),(%d,%d,%d)\n", |
---|
4013 | 3991 | i, |
---|
4014 | | - interfaces[i].psq.q[0].len, |
---|
4015 | | - interfaces[i].psq.q[1].len, |
---|
4016 | | - interfaces[i].afq.q[0].len, |
---|
4017 | | - interfaces[i].psq.q[2].len, |
---|
4018 | | - interfaces[i].psq.q[3].len, |
---|
4019 | | - interfaces[i].afq.q[1].len, |
---|
4020 | | - interfaces[i].psq.q[4].len, |
---|
4021 | | - interfaces[i].psq.q[5].len, |
---|
4022 | | - interfaces[i].afq.q[2].len, |
---|
4023 | | - interfaces[i].psq.q[6].len, |
---|
4024 | | - interfaces[i].psq.q[7].len, |
---|
4025 | | - interfaces[i].afq.q[3].len, |
---|
4026 | | - interfaces[i].psq.q[8].len, |
---|
4027 | | - interfaces[i].psq.q[9].len, |
---|
4028 | | - interfaces[i].afq.q[4].len); |
---|
| 3992 | + interfaces[i].psq.q[0].n_pkts, |
---|
| 3993 | + interfaces[i].psq.q[1].n_pkts, |
---|
| 3994 | + interfaces[i].afq.q[0].n_pkts, |
---|
| 3995 | + interfaces[i].psq.q[2].n_pkts, |
---|
| 3996 | + interfaces[i].psq.q[3].n_pkts, |
---|
| 3997 | + interfaces[i].afq.q[1].n_pkts, |
---|
| 3998 | + interfaces[i].psq.q[4].n_pkts, |
---|
| 3999 | + interfaces[i].psq.q[5].n_pkts, |
---|
| 4000 | + interfaces[i].afq.q[2].n_pkts, |
---|
| 4001 | + interfaces[i].psq.q[6].n_pkts, |
---|
| 4002 | + interfaces[i].psq.q[7].n_pkts, |
---|
| 4003 | + interfaces[i].afq.q[3].n_pkts, |
---|
| 4004 | + interfaces[i].psq.q[8].n_pkts, |
---|
| 4005 | + interfaces[i].psq.q[9].n_pkts, |
---|
| 4006 | + interfaces[i].afq.q[4].n_pkts); |
---|
4029 | 4007 | } |
---|
4030 | 4008 | } |
---|
4031 | 4009 | |
---|
.. | .. |
---|
4034 | 4012 | if (mac_table[i].occupied) { |
---|
4035 | 4013 | ea = mac_table[i].ea; |
---|
4036 | 4014 | bcm_bprintf(strbuf, "MAC_table[%d].ea = " |
---|
4037 | | - "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d \n", i, |
---|
4038 | | - ea[0], ea[1], ea[2], ea[3], ea[4], ea[5], |
---|
4039 | | - mac_table[i].interface_id); |
---|
| 4015 | + "["MACDBG"], if:%d \n", i, |
---|
| 4016 | + MAC2STRDBG(ea), mac_table[i].interface_id); |
---|
4040 | 4017 | |
---|
4041 | 4018 | bcm_bprintf(strbuf, "MAC_table[%d].PSQ(len,state,credit)," |
---|
4042 | 4019 | "(trans,supp_trans,onbus)" |
---|
4043 | 4020 | "= (%d,%s,%d),(%d,%d,%d)\n", |
---|
4044 | 4021 | i, |
---|
4045 | | - mac_table[i].psq.len, |
---|
| 4022 | + mac_table[i].psq.n_pkts_tot, |
---|
4046 | 4023 | ((mac_table[i].state == |
---|
4047 | 4024 | WLFC_STATE_OPEN) ? " OPEN":"CLOSE"), |
---|
4048 | 4025 | mac_table[i].requested_credit, |
---|
.. | .. |
---|
4052 | 4029 | #ifdef PROP_TXSTATUS_DEBUG |
---|
4053 | 4030 | bcm_bprintf(strbuf, "MAC_table[%d]: (opened, closed) = (%d, %d)\n", |
---|
4054 | 4031 | i, mac_table[i].opened_ct, mac_table[i].closed_ct); |
---|
4055 | | -#endif |
---|
| 4032 | +#endif // endif |
---|
4056 | 4033 | bcm_bprintf(strbuf, "MAC_table[%d].PSQ" |
---|
4057 | 4034 | "(delay0,sup0,afq0),(delay1,sup1,afq1),(delay2,sup2,afq2)," |
---|
4058 | 4035 | "(delay3,sup3,afq3),(delay4,sup4,afq4) =(%d,%d,%d)," |
---|
4059 | 4036 | "(%d,%d,%d),(%d,%d,%d),(%d,%d,%d),(%d,%d,%d)\n", |
---|
4060 | 4037 | i, |
---|
4061 | | - mac_table[i].psq.q[0].len, |
---|
4062 | | - mac_table[i].psq.q[1].len, |
---|
4063 | | - mac_table[i].afq.q[0].len, |
---|
4064 | | - mac_table[i].psq.q[2].len, |
---|
4065 | | - mac_table[i].psq.q[3].len, |
---|
4066 | | - mac_table[i].afq.q[1].len, |
---|
4067 | | - mac_table[i].psq.q[4].len, |
---|
4068 | | - mac_table[i].psq.q[5].len, |
---|
4069 | | - mac_table[i].afq.q[2].len, |
---|
4070 | | - mac_table[i].psq.q[6].len, |
---|
4071 | | - mac_table[i].psq.q[7].len, |
---|
4072 | | - mac_table[i].afq.q[3].len, |
---|
4073 | | - mac_table[i].psq.q[8].len, |
---|
4074 | | - mac_table[i].psq.q[9].len, |
---|
4075 | | - mac_table[i].afq.q[4].len); |
---|
| 4038 | + mac_table[i].psq.q[0].n_pkts, |
---|
| 4039 | + mac_table[i].psq.q[1].n_pkts, |
---|
| 4040 | + mac_table[i].afq.q[0].n_pkts, |
---|
| 4041 | + mac_table[i].psq.q[2].n_pkts, |
---|
| 4042 | + mac_table[i].psq.q[3].n_pkts, |
---|
| 4043 | + mac_table[i].afq.q[1].n_pkts, |
---|
| 4044 | + mac_table[i].psq.q[4].n_pkts, |
---|
| 4045 | + mac_table[i].psq.q[5].n_pkts, |
---|
| 4046 | + mac_table[i].afq.q[2].n_pkts, |
---|
| 4047 | + mac_table[i].psq.q[6].n_pkts, |
---|
| 4048 | + mac_table[i].psq.q[7].n_pkts, |
---|
| 4049 | + mac_table[i].afq.q[3].n_pkts, |
---|
| 4050 | + mac_table[i].psq.q[8].n_pkts, |
---|
| 4051 | + mac_table[i].psq.q[9].n_pkts, |
---|
| 4052 | + mac_table[i].afq.q[4].n_pkts); |
---|
4076 | 4053 | |
---|
4077 | 4054 | } |
---|
4078 | 4055 | } |
---|
.. | .. |
---|
4164 | 4141 | } |
---|
4165 | 4142 | #endif /* PROP_TXSTATUS_DEBUG */ |
---|
4166 | 4143 | bcm_bprintf(strbuf, "\n"); |
---|
4167 | | - bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull,out),(dropped,hdr_only,wlc_tossed)" |
---|
| 4144 | + bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull,out)," |
---|
| 4145 | + "(dropped,hdr_only,wlc_tossed,wlc_dropped,wlc_exptime)" |
---|
4168 | 4146 | "(freed,free_err,rollback)) = " |
---|
4169 | | - "((%d,%d,%d,%d,%d),(%d,%d,%d),(%d,%d,%d))\n", |
---|
| 4147 | + "((%d,%d,%d,%d,%d),(%d,%d,%d,%d,%d),(%d,%d,%d))\n", |
---|
4170 | 4148 | wlfc->stats.pktin, |
---|
4171 | 4149 | wlfc->stats.pkt2bus, |
---|
4172 | 4150 | wlfc->stats.txstatus_in, |
---|
.. | .. |
---|
4176 | 4154 | wlfc->stats.pktdropped, |
---|
4177 | 4155 | wlfc->stats.wlfc_header_only_pkt, |
---|
4178 | 4156 | wlfc->stats.wlc_tossed_pkts, |
---|
| 4157 | + wlfc->stats.pkt_dropped, |
---|
| 4158 | + wlfc->stats.pkt_exptime, |
---|
4179 | 4159 | |
---|
4180 | 4160 | wlfc->stats.pkt_freed, |
---|
4181 | 4161 | wlfc->stats.pkt_free_err, wlfc->stats.rollback); |
---|
.. | .. |
---|
4362 | 4342 | dhd_os_wlfc_unblock(dhdp); |
---|
4363 | 4343 | } |
---|
4364 | 4344 | |
---|
4365 | | -#if defined(DHD_WLFC_THREAD) |
---|
4366 | | - _dhd_wlfc_thread_wakeup(dhd); |
---|
4367 | | -#endif /* defined(DHD_WLFC_THREAD) */ |
---|
4368 | | - |
---|
4369 | 4345 | return BCME_OK; |
---|
4370 | 4346 | } |
---|
4371 | 4347 | |
---|
.. | .. |
---|
4459 | 4435 | __FUNCTION__, tlv)); |
---|
4460 | 4436 | } |
---|
4461 | 4437 | } |
---|
| 4438 | + |
---|
| 4439 | +#if defined(DHD_WLFC_THREAD) |
---|
| 4440 | + _dhd_wlfc_thread_wakeup(dhd); |
---|
| 4441 | +#endif /* defined(DHD_WLFC_THREAD) */ |
---|
| 4442 | + |
---|
4462 | 4443 | return BCME_OK; |
---|
4463 | 4444 | } |
---|
4464 | 4445 | |
---|