forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_wlfc.c
....@@ -1,15 +1,16 @@
1
-/* SPDX-License-Identifier: GPL-2.0 */
21 /*
32 * DHD PROP_TXSTATUS Module.
43 *
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
+ *
78 * Unless you and Broadcom execute a separate written software license
89 * agreement governing use of this software, this software is licensed to you
910 * under the terms of the GNU General Public License version 2 (the "GPL"),
1011 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
1112 * following added to such license:
12
- *
13
+ *
1314 * As a special exception, the copyright holders of this software give you
1415 * permission to link this software with independent modules, and to copy and
1516 * distribute the resulting executable under terms of your choice, provided that
....@@ -17,7 +18,7 @@
1718 * the license of that module. An independent module is a module which is not
1819 * derived from this software. The special exception does not apply to any
1920 * modifications of the software.
20
- *
21
+ *
2122 * Notwithstanding the above, under no circumstances may you combine this
2223 * software in any way with any other Broadcom software provided under a license
2324 * other than the GPL, without Broadcom's express prior written consent.
....@@ -25,10 +26,9 @@
2526 *
2627 * <<Broadcom-WL-IPTag/Open:>>
2728 *
28
- * $Id: dhd_wlfc.c 606400 2015-12-15 09:59:42Z $
29
+ * $Id: dhd_wlfc.c 700323 2017-05-18 16:12:11Z $
2930 *
3031 */
31
-
3232
3333 #include <typedefs.h>
3434 #include <osl.h>
....@@ -39,24 +39,18 @@
3939 #include <dngl_stats.h>
4040 #include <dhd.h>
4141
42
-#ifdef BCMDBUS /* an abstraction layer that hides details of the underlying bus, eg \
43
- Linux USB */
44
-#include <dbus.h>
45
-#else
4642 #include <dhd_bus.h>
47
-#endif /* BCMDBUS */
4843
4944 #include <dhd_dbg.h>
5045
5146 #ifdef PROP_TXSTATUS /* a form of flow control between host and dongle */
5247 #include <wlfc_proto.h>
5348 #include <dhd_wlfc.h>
54
-#endif
49
+#endif // endif
5550
5651 #ifdef DHDTCPACK_SUPPRESS
5752 #include <dhd_ip.h>
5853 #endif /* DHDTCPACK_SUPPRESS */
59
-
6054
6155 /*
6256 * wlfc naming and lock rules:
....@@ -72,14 +66,9 @@
7266 #define WLFC_THREAD_RETRY_WAIT_MS 10000 /* 10 sec */
7367 #endif /* defined (DHD_WLFC_THREAD) */
7468
75
-#if defined(BCMDBUS)
76
-extern int dhd_dbus_txdata(dhd_pub_t *dhdp, void *pktbuf);
77
-#endif
78
-
7969 #ifdef PROP_TXSTATUS
8070
8171 #define DHD_WLFC_QMON_COMPLETE(entry)
82
-
8372
8473 /** reordering related */
8574
....@@ -132,15 +121,13 @@
132121 return;
133122
134123 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 */
137125
138126 ASSERT(!pktq_full(pq));
139
- ASSERT(!pktq_pfull(pq, prec));
127
+ ASSERT(!pktqprec_full(pq, prec));
140128
141129 q = &pq->q[prec];
142130
143
- PKTSETLINK(p, NULL);
144131 if (q->head == NULL) {
145132 /* empty queue */
146133 q->head = p;
....@@ -194,8 +181,8 @@
194181
195182 exit:
196183
197
- q->len++;
198
- pq->len++;
184
+ q->n_pkts++;
185
+ pq->n_pkts_tot++;
199186
200187 if (pq->hi_prec < prec)
201188 pq->hi_prec = (uint8)prec;
....@@ -504,8 +491,12 @@
504491 }
505492 }
506493
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
509500
510501 PKTSETLINK(p, NULL);
511502
....@@ -593,7 +584,6 @@
593584 h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
594585 if (PKTSUMNEEDED(p))
595586 h->flags |= BDC_FLAG_SUM_NEEDED;
596
-
597587
598588 h->priority = (PKTPRIO(p) & BDC_PRIORITY_MASK);
599589 h->flags2 = 0;
....@@ -699,7 +689,10 @@
699689 void *pout = NULL;
700690
701691 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
+ }
703696
704697 ctx = (athost_wl_status_info_t*)dhdp->wlfc_state;
705698
....@@ -774,12 +767,12 @@
774767 /* Fast case, precedence queue is not full and we are also not
775768 * exceeding total queue length
776769 */
777
- if (!pktq_pfull(pq, prec) && !pktq_full(pq)) {
770
+ if (!pktqprec_full(pq, prec) && !pktq_full(pq)) {
778771 goto exit;
779772 }
780773
781774 /* Determine precedence from which to evict packet, if any */
782
- if (pktq_pfull(pq, prec)) {
775
+ if (pktqprec_full(pq, prec)) {
783776 eprec = prec;
784777 } else if (pktq_full(pq)) {
785778 p = pktq_peek_tail(pq, &eprec);
....@@ -788,7 +781,7 @@
788781 return FALSE;
789782 }
790783 if ((eprec > prec) || (eprec < 0)) {
791
- if (!pktq_pempty(pq, prec)) {
784
+ if (!pktqprec_empty(pq, prec)) {
792785 eprec = prec;
793786 } else {
794787 return FALSE;
....@@ -799,7 +792,7 @@
799792 /* Evict if needed */
800793 if (eprec >= 0) {
801794 /* Detect queueing to unconfigured precedence */
802
- ASSERT(!pktq_pempty(pq, eprec));
795
+ ASSERT(!pktqprec_empty(pq, eprec));
803796 /* Evict all fragmented frames */
804797 dhd_prec_drop_pkts(dhdp, pq, eprec, _dhd_wlfc_prec_drop);
805798 }
....@@ -940,18 +933,21 @@
940933 dhdp = (dhd_pub_t *)ctx->dhdp;
941934 ASSERT(dhdp);
942935
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))
944940 return;
945941
946942 if ((ctx->hostif_flow_state[if_id] == OFF) && !_dhd_wlfc_allow_fc(ctx, if_id))
947943 return;
948944
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)) {
950946 /* start traffic */
951947 ctx->hostif_flow_state[if_id] = OFF;
952948 /*
953949 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__));
955951 */
956952 WLFC_DBGMESG(("F"));
957953
....@@ -960,12 +956,12 @@
960956 ctx->toggle_host_if = 0;
961957 }
962958
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) {
964960 /* stop traffic */
965961 ctx->hostif_flow_state[if_id] = ON;
966962 /*
967963 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__));
969965 */
970966 WLFC_DBGMESG(("N"));
971967
....@@ -1002,15 +998,13 @@
1002998 DHD_PKTTAG_WLFCPKT_SET(PKTTAG(p), 1);
1003999 #ifdef PROP_TXSTATUS_DEBUG
10041000 ctx->stats.signal_only_pkts_sent++;
1005
-#endif
1001
+#endif // endif
10061002
10071003 #if defined(BCMPCIE)
10081004 rc = dhd_bus_txdata(dhdp->bus, p, ctx->host_ifidx);
1009
-#elif defined(BCMDBUS)
1010
- rc = dhd_dbus_txdata(dhdp, p);
10111005 #else
10121006 rc = dhd_bus_txdata(dhdp->bus, p);
1013
-#endif
1007
+#endif // endif
10141008 if (rc != BCME_OK) {
10151009 _dhd_wlfc_pullheader(ctx, p);
10161010 PKTFREE(ctx->osh, p, TRUE);
....@@ -1041,8 +1035,8 @@
10411035 bool rc = FALSE;
10421036
10431037 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)) {
10461040 /* no packets in both 'normal' and 'suspended' queues */
10471041 if (entry->traffic_pending_bmp & NBITVAL(prec)) {
10481042 rc = TRUE;
....@@ -1218,7 +1212,7 @@
12181212 #ifdef PROP_TXSTATUS_DEBUG
12191213 h->items[hslot].push_time =
12201214 OSL_SYSUPTIME();
1221
-#endif
1215
+#endif // endif
12221216 } else {
12231217 DHD_ERROR(("%s() hanger_pushpkt() failed, rc: %d\n",
12241218 __FUNCTION__, rc));
....@@ -1235,10 +1229,6 @@
12351229 h->items[hslot].pkt_txstatus = 0;
12361230 h->items[hslot].state = WLFC_HANGER_ITEM_STATE_INUSE;
12371231 }
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;
12421232 }
12431233
12441234 if ((rc == BCME_OK) && header_needed) {
....@@ -1259,12 +1249,14 @@
12591249 _dhd_wlfc_is_destination_open(athost_wl_status_info_t* ctx,
12601250 wlfc_mac_descriptor_t* entry, int prec)
12611251 {
1252
+ wlfc_mac_descriptor_t* interfaces = ctx->destination_entries.interfaces;
1253
+
12621254 if (entry->interface_id >= WLFC_MAX_IFNUM) {
12631255 ASSERT(&ctx->destination_entries.other == entry);
12641256 return 1;
12651257 }
12661258
1267
- if (ctx->destination_entries.interfaces[entry->interface_id].iftype ==
1259
+ if (interfaces[entry->interface_id].iftype ==
12681260 WLC_E_IF_ROLE_P2P_GO) {
12691261 /* - destination interface is of type p2p GO.
12701262 For a p2pGO interface, if the destination is OPEN but the interface is
....@@ -1279,7 +1271,9 @@
12791271 }
12801272
12811273 /* 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) &&
12831277 (entry->requested_packet == 0)) ||
12841278 (!(entry->ac_bitmap & (1 << prec)))) {
12851279 return 0;
....@@ -1357,7 +1351,7 @@
13571351 entry->requested_credit--;
13581352 #ifdef PROP_TXSTATUS_DEBUG
13591353 entry->dstncredit_sent_packets++;
1360
-#endif
1354
+#endif // endif
13611355 } else if (entry->requested_packet > 0) {
13621356 entry->requested_packet--;
13631357 DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p));
....@@ -1406,7 +1400,6 @@
14061400 ctx->stats.delayq_full_error++;
14071401 return BCME_ERROR;
14081402 }
1409
-
14101403
14111404 /* A packet has been pushed, update traffic availability bitmap, if applicable */
14121405 _dhd_wlfc_traffic_pending_check(ctx, entry, prec);
....@@ -1543,7 +1536,7 @@
15431536 /* Optimize flush, if pktq len = 0, just return.
15441537 * pktq len of 0 means pktq's prec q's are all empty.
15451538 */
1546
- if (pq->len == 0) {
1539
+ if (pq->n_pkts_tot == 0) {
15471540 return;
15481541 }
15491542
....@@ -1608,8 +1601,12 @@
16081601 }
16091602 PKTFREE(ctx->osh, p, dir);
16101603
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
+
16131610 p = (head ? q->head : PKTLINK(prev));
16141611 } else {
16151612 prev = p;
....@@ -1618,17 +1615,15 @@
16181615 }
16191616
16201617 if (q->head == NULL) {
1621
- ASSERT(q->len == 0);
1618
+ ASSERT(q->n_pkts == 0);
16221619 q->tail = NULL;
16231620 }
16241621
16251622 }
16261623
16271624 if (fn == NULL)
1628
- ASSERT(pq->len == 0);
1625
+ ASSERT(pq->n_pkts_tot == 0);
16291626 } /* _dhd_wlfc_pktq_flush */
1630
-
1631
-#ifndef BCMDBUS
16321627
16331628 /** !BCMDBUS specific function. Dequeues a packet from the caller supplied queue. */
16341629 static void*
....@@ -1666,9 +1661,13 @@
16661661 }
16671662 }
16681663
1669
- q->len--;
1664
+ q->n_pkts--;
16701665
1671
- pq->len--;
1666
+ pq->n_pkts_tot--;
1667
+
1668
+#ifdef WL_TXQ_STALL
1669
+ q->dequeue_count++;
1670
+#endif // endif
16721671
16731672 PKTSETLINK(p, NULL);
16741673
....@@ -1707,7 +1706,6 @@
17071706 }
17081707 dhd_os_sdunlock_txq(dhd);
17091708
1710
-
17111709 while ((pkt = head)) {
17121710 head = PKTLINK(pkt);
17131711 PKTSETLINK(pkt, NULL);
....@@ -1736,8 +1734,6 @@
17361734 }
17371735 } /* _dhd_wlfc_cleanup_txq */
17381736
1739
-#endif /* !BCMDBUS */
1740
-
17411737 /** called during eg detach */
17421738 void
17431739 _dhd_wlfc_cleanup(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
....@@ -1755,10 +1751,8 @@
17551751 /*
17561752 * flush sequence should be txq -> psq -> hanger/afq, hanger has to be last one
17571753 */
1758
-#ifndef BCMDBUS
17591754 /* flush bus->txq */
17601755 _dhd_wlfc_cleanup_txq(dhd, fn, arg);
1761
-#endif /* BCMDBUS */
17621756
17631757 /* flush psq, search all entries, include nodes as well as interfaces */
17641758 total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t);
....@@ -1767,15 +1761,15 @@
17671761 for (i = 0; i < total_entries; i++) {
17681762 if (table[i].occupied) {
17691763 /* release packets held in PSQ (both delayed and suppressed) */
1770
- if (table[i].psq.len) {
1764
+ if (table[i].psq.n_pkts_tot) {
17711765 WLFC_DBGMESG(("%s(): PSQ[%d].len = %d\n",
1772
- __FUNCTION__, i, table[i].psq.len));
1766
+ __FUNCTION__, i, table[i].psq.n_pkts_tot));
17731767 _dhd_wlfc_pktq_flush(wlfc, &table[i].psq, TRUE,
17741768 fn, arg, Q_TYPE_PSQ);
17751769 }
17761770
17771771 /* 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)) {
17791773 _dhd_wlfc_pktq_flush(wlfc, &table[i].afq, TRUE,
17801774 fn, arg, Q_TYPE_AFQ);
17811775 }
....@@ -1819,7 +1813,6 @@
18191813 {
18201814 int rc = BCME_OK;
18211815
1822
-
18231816 if ((action == eWLFC_MAC_ENTRY_ACTION_ADD) || (action == eWLFC_MAC_ENTRY_ACTION_UPDATE)) {
18241817 entry->occupied = 1;
18251818 entry->state = WLFC_STATE_OPEN;
....@@ -1843,6 +1836,7 @@
18431836 dhd_pub_t *dhdp = (dhd_pub_t *)(ctx->dhdp);
18441837
18451838 pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN);
1839
+ _dhd_wlfc_flow_control_check(ctx, &entry->psq, ifid);
18461840
18471841 if (WLFC_GET_AFQ(dhdp->wlfc_mode)) {
18481842 pktq_init(&entry->afq, WLFC_AFQ_PREC_COUNT, WLFC_PSQ_LEN);
....@@ -1898,7 +1892,6 @@
18981892 }
18991893 return rc;
19001894 } /* _dhd_wlfc_mac_entry_update */
1901
-
19021895
19031896 #ifdef LIMIT_BORROW
19041897
....@@ -2189,8 +2182,13 @@
21892182 }
21902183 }
21912184
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
+
21942192 ctx->pkt_cnt_in_q[DHD_PKTTAG_IF(PKTTAG(p))][prec]--;
21952193 ctx->pkt_cnt_per_ac[prec]--;
21962194
....@@ -2232,7 +2230,7 @@
22322230 if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) {
22332231 memcpy(&seq, pkt_info + WLFC_CTL_VALUE_LEN_TXSTATUS, WLFC_CTL_VALUE_LEN_SEQ);
22342232 seq = ltoh16(seq);
2235
- seq_fromfw = WL_SEQ_GET_FROMFW(seq);
2233
+ seq_fromfw = GET_WL_HAS_ASSIGNED_SEQ(seq);
22362234 seq_num = WL_SEQ_GET_NUM(seq);
22372235 }
22382236
....@@ -2250,10 +2248,12 @@
22502248 remove_from_hanger = 0;
22512249 } else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) {
22522250 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) {
22562252 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;
22572257 }
22582258
22592259 if (dhd->proptxstatus_txstatus_ignore) {
....@@ -2326,7 +2326,6 @@
23262326 uint32 delta;
23272327 old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[hslot].push_time;
23282328
2329
-
23302329 wlfc->stats.latency_sample_count++;
23312330 if (new_t > old_t)
23322331 delta = new_t - old_t;
....@@ -2357,7 +2356,7 @@
23572356 }
23582357 #ifdef PROP_TXSTATUS_DEBUG
23592358 entry->dstncredit_acks++;
2360
-#endif
2359
+#endif // endif
23612360 }
23622361
23632362 if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) ||
....@@ -2366,7 +2365,7 @@
23662365 WL_TXSTATUS_SET_GENERATION(DHD_PKTTAG_H2DTAG(PKTTAG(pktbuf)), gen);
23672366
23682367 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);
23702369 WL_SEQ_SET_NUM(DHD_PKTTAG_H2DSEQ(PKTTAG(pktbuf)), seq_num);
23712370 }
23722371
....@@ -2438,7 +2437,7 @@
24382437 for (i = 0; i < WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK; i++) {
24392438 #ifdef PROP_TXSTATUS_DEBUG
24402439 wlfc->stats.fifo_credits_back[i] += credits[i];
2441
-#endif
2440
+#endif // endif
24422441
24432442 /* update FIFO credits */
24442443 if (dhd->proptxstatus_mode == WLFC_FCMODE_EXPLICIT_CREDIT)
....@@ -2480,8 +2479,6 @@
24802479 return BCME_OK;
24812480 } /* _dhd_wlfc_fifocreditback_indicate */
24822481
2483
-#ifndef BCMDBUS
2484
-
24852482 /** !BCMDBUS specific function */
24862483 static void
24872484 _dhd_wlfc_suppress_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
....@@ -2516,15 +2513,18 @@
25162513 PKTSETLINK(pkt, NULL);
25172514
25182515 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;
25262519 }
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
+ }
25282528 /* fake a suppression txstatus */
25292529 htod = DHD_PKTTAG_H2DTAG(PKTTAG(pkt));
25302530 WL_TXSTATUS_SET_FLAGS(htod, WLFC_CTL_PKTFLAG_WLSUPPRESS);
....@@ -2533,9 +2533,9 @@
25332533 memcpy(results, &htod, WLFC_CTL_VALUE_LEN_TXSTATUS);
25342534 if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) {
25352535 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);
25392539 }
25402540 htodseq = htol16(htodseq);
25412541 memcpy(results + WLFC_CTL_VALUE_LEN_TXSTATUS, &htodseq,
....@@ -2557,8 +2557,6 @@
25572557 _dhd_wlfc_fifocreditback_indicate(dhd, credits);
25582558 }
25592559 } /* _dhd_wlfc_suppress_txq */
2560
-
2561
-#endif /* !BCMDBUS */
25622560
25632561 static int
25642562 _dhd_wlfc_dbg_senum_check(dhd_pub_t *dhd, uint8 *value)
....@@ -2643,8 +2641,8 @@
26432641 uint8 ifid;
26442642 uint8* ea;
26452643
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]),
26482646 ((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"),
26492647 WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0]));
26502648
....@@ -2828,7 +2826,11 @@
28282826 _dhd_wlfc_reorderinfo_indicate(uint8 *val, uint8 len, uchar *info_buf, uint *info_len)
28292827 {
28302828 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)) {
28322834 bcopy(val, info_buf, len);
28332835 *info_len = len;
28342836 } else {
....@@ -2923,7 +2925,6 @@
29232925 wlfc->allow_credit_borrow = 0;
29242926 wlfc->single_ac = 0;
29252927 wlfc->single_ac_timestamp = 0;
2926
-
29272928
29282929 exit:
29292930 dhd_os_wlfc_unblock(dhd);
....@@ -3082,12 +3083,10 @@
30823083 _dhd_wlfc_interface_update(dhd, value, type);
30833084 }
30843085
3085
-#ifndef BCMDBUS
30863086 if (entry && WLFC_GET_REORDERSUPP(dhd->wlfc_mode)) {
30873087 /* suppress all packets for this mac entry from bus->txq */
30883088 _dhd_wlfc_suppress_txq(dhd, _dhd_wlfc_entrypkt_fn, entry);
30893089 }
3090
-#endif /* !BCMDBUS */
30913090 } /* while */
30923091
30933092 if (remainder != 0 && wlfc) {
....@@ -3101,7 +3100,7 @@
31013100
31023101 dhd_os_wlfc_unblock(dhd);
31033102 return BCME_OK;
3104
-} /* dhd_wlfc_parse_header_info */
3103
+}
31053104
31063105 KERNEL_THREAD_RETURN_TYPE
31073106 dhd_wlfc_transfer_packets(void *data)
....@@ -3112,6 +3111,7 @@
31123111 athost_wl_status_info_t* ctx;
31133112 int bus_retry_count = 0;
31143113 int pkt_send = 0;
3114
+ int pkt_send_per_ac = 0;
31153115
31163116 uint8 tx_map = 0; /* packets (send + in queue), Bitmask for 4 ACs + BC/MC */
31173117 uint8 rx_map = 0; /* received packets, Bitmask for 4 ACs + BC/MC */
....@@ -3179,7 +3179,9 @@
31793179
31803180 tx_map |= (1 << ac);
31813181 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)) {
31833185 /* packets from delayQ with less priority are fresh and
31843186 * they'd need header and have no MAC entry
31853187 */
....@@ -3199,7 +3201,7 @@
31993201 no_credit = FALSE;
32003202 }
32013203 }
3202
-#endif
3204
+#endif // endif
32033205 commit_info.needs_hdr = 1;
32043206 commit_info.mac_entry = NULL;
32053207 commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
....@@ -3215,7 +3217,7 @@
32153217 if (lender != -1 && dhdp->wlfc_borrow_allowed) {
32163218 _dhd_wlfc_return_credit(ctx, lender, ac);
32173219 }
3218
-#endif
3220
+#endif // endif
32193221 break;
32203222 }
32213223
....@@ -3229,6 +3231,7 @@
32293231 /* Bus commits may fail (e.g. flow control); abort after retries */
32303232 if (rc == BCME_OK) {
32313233 pkt_send++;
3234
+ pkt_send_per_ac++;
32323235 if (commit_info.ac_fifo_credit_spent && (lender == -1)) {
32333236 ctx->FIFO_credit[ac]--;
32343237 }
....@@ -3237,13 +3240,13 @@
32373240 dhdp->wlfc_borrow_allowed) {
32383241 _dhd_wlfc_return_credit(ctx, lender, ac);
32393242 }
3240
-#endif
3243
+#endif // endif
32413244 } else {
32423245 #ifdef LIMIT_BORROW
32433246 if (lender != -1 && dhdp->wlfc_borrow_allowed) {
32443247 _dhd_wlfc_return_credit(ctx, lender, ac);
32453248 }
3246
-#endif
3249
+#endif // endif
32473250 bus_retry_count++;
32483251 if (bus_retry_count >= BUS_RETRIES) {
32493252 DHD_ERROR(("%s: bus error %d\n", __FUNCTION__, rc));
....@@ -3316,7 +3319,7 @@
33163319 }
33173320 else
33183321 break;
3319
-#endif
3322
+#endif // endif
33203323 commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
33213324 &(commit_info.ac_fifo_credit_spent),
33223325 &(commit_info.needs_hdr),
....@@ -3326,7 +3329,7 @@
33263329 /* before borrow only one ac exists and now this only ac is empty */
33273330 #ifdef LIMIT_BORROW
33283331 _dhd_wlfc_return_credit(ctx, lender, ac);
3329
-#endif
3332
+#endif // endif
33303333 break;
33313334 }
33323335
....@@ -3342,16 +3345,16 @@
33423345 if (commit_info.ac_fifo_credit_spent) {
33433346 #ifndef LIMIT_BORROW
33443347 ctx->FIFO_credit[ac]--;
3345
-#endif
3348
+#endif // endif
33463349 } else {
33473350 #ifdef LIMIT_BORROW
33483351 _dhd_wlfc_return_credit(ctx, lender, ac);
3349
-#endif
3352
+#endif // endif
33503353 }
33513354 } else {
33523355 #ifdef LIMIT_BORROW
33533356 _dhd_wlfc_return_credit(ctx, lender, ac);
3354
-#endif
3357
+#endif // endif
33553358 bus_retry_count++;
33563359 if (bus_retry_count >= BUS_RETRIES) {
33573360 DHD_ERROR(("%s: bus error %d\n", __FUNCTION__, rc));
....@@ -3414,16 +3417,6 @@
34143417 }
34153418
34163419 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
34273420
34283421 if (dhdp->proptxstatus_module_ignore) {
34293422 if (pktbuf) {
....@@ -3503,7 +3496,7 @@
35033496 if (DHD_PKTTAG_SIGNALONLY(PKTTAG(txp))) {
35043497 #ifdef PROP_TXSTATUS_DEBUG
35053498 wlfc->stats.signal_only_pkts_freed++;
3506
-#endif
3499
+#endif // endif
35073500 /* is this a signal-only packet? */
35083501 _dhd_wlfc_pullheader(wlfc, txp);
35093502 PKTFREE(wlfc->osh, txp, TRUE);
....@@ -3546,7 +3539,6 @@
35463539 }
35473540 }
35483541
3549
- ASSERT(entry->onbus_pkts_count > 0);
35503542 if (entry->onbus_pkts_count > 0)
35513543 entry->onbus_pkts_count--;
35523544 if (entry->suppressed &&
....@@ -3585,7 +3577,6 @@
35853577 WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE |
35863578 WLFC_FLAGS_HOST_RXRERODER_ACTIVE;
35873579
3588
-
35893580 /*
35903581 try to enable/disable signaling by sending "tlv" iovar. if that fails,
35913582 fallback to no flow control? Print a message for now.
....@@ -3610,18 +3601,10 @@
36103601 DHD_INFO(("%s: query wlfc_mode succeed, fw_caps=0x%x\n", __FUNCTION__, fw_caps));
36113602
36123603 if (WLFC_IS_OLD_DEF(fw_caps)) {
3613
-#ifdef BCMDBUS
3614
- mode = WLFC_MODE_HANGER;
3615
-#else
36163604 /* enable proptxtstatus v2 by default */
36173605 mode = WLFC_MODE_AFQ;
3618
-#endif /* BCMDBUS */
36193606 } else {
36203607 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));
36253608 WLFC_SET_REORDERSUPP(mode, WLFC_GET_REORDERSUPP(fw_caps));
36263609 }
36273610 ret = dhd_wl_ioctl_set_intiovar(dhd, "wlfc_mode", mode, WLC_SET_VAR, TRUE, 0);
....@@ -3641,7 +3624,7 @@
36413624 DHD_INFO(("dhd_wlfc_init(): wlfc_mode=0x%x, ret=%d\n", dhd->wlfc_mode, ret));
36423625 #ifdef LIMIT_BORROW
36433626 dhd->wlfc_borrow_allowed = TRUE;
3644
-#endif
3627
+#endif // endif
36453628 dhd_os_wlfc_unblock(dhd);
36463629
36473630 if (dhd->plat_init)
....@@ -3701,9 +3684,7 @@
37013684 return WLFC_UNSUPPORTED;
37023685 }
37033686
3704
-#ifndef BCMDBUS
37053687 _dhd_wlfc_cleanup_txq(dhd, fn, arg);
3706
-#endif /* !BCMDBUS */
37073688
37083689 dhd_os_wlfc_unblock(dhd);
37093690
....@@ -3794,7 +3775,6 @@
37943775 _dhd_wlfc_hanger_delete(dhd, h);
37953776 }
37963777
3797
-
37983778 /* free top structure */
37993779 DHD_OS_PREFREE(dhd, dhd->wlfc_state,
38003780 sizeof(athost_wl_status_info_t));
....@@ -3862,8 +3842,7 @@
38623842 #ifdef LIMIT_BORROW
38633843 int dhd_wlfc_disable_credit_borrow_event(dhd_pub_t *dhdp, uint8* event_data)
38643844 {
3865
- int rc;
3866
- if (dhdp == NULL) {
3845
+ if (dhdp == NULL || event_data == NULL) {
38673846 DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
38683847 return BCME_BADARG;
38693848 }
....@@ -3871,7 +3850,7 @@
38713850 dhdp->wlfc_borrow_allowed = (bool)(*(uint32 *)event_data);
38723851 dhd_os_wlfc_unblock(dhdp);
38733852
3874
- return rc;
3853
+ return BCME_OK;
38753854 }
38763855 #endif /* LIMIT_BORROW */
38773856
....@@ -3987,10 +3966,9 @@
39873966
39883967 ea = interfaces[i].ea;
39893968 bcm_bprintf(strbuf, "INTERFACE[%d].ea = "
3990
- "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d, type: %s "
3969
+ "["MACDBG"], if:%d, type: %s "
39913970 "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,
39943972 iftype_desc, ((wlfc->hostif_flow_state[i] == OFF)
39953973 ? " OFF":" ON"));
39963974
....@@ -3998,7 +3976,7 @@
39983976 "(trans,supp_trans,onbus)"
39993977 "= (%d,%s,%d),(%d,%d,%d)\n",
40003978 i,
4001
- interfaces[i].psq.len,
3979
+ interfaces[i].psq.n_pkts_tot,
40023980 ((interfaces[i].state ==
40033981 WLFC_STATE_OPEN) ? "OPEN":"CLOSE"),
40043982 interfaces[i].requested_credit,
....@@ -4011,21 +3989,21 @@
40113989 "(delay3,sup3,afq3),(delay4,sup4,afq4) = (%d,%d,%d),"
40123990 "(%d,%d,%d),(%d,%d,%d),(%d,%d,%d),(%d,%d,%d)\n",
40133991 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);
40294007 }
40304008 }
40314009
....@@ -4034,15 +4012,14 @@
40344012 if (mac_table[i].occupied) {
40354013 ea = mac_table[i].ea;
40364014 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);
40404017
40414018 bcm_bprintf(strbuf, "MAC_table[%d].PSQ(len,state,credit),"
40424019 "(trans,supp_trans,onbus)"
40434020 "= (%d,%s,%d),(%d,%d,%d)\n",
40444021 i,
4045
- mac_table[i].psq.len,
4022
+ mac_table[i].psq.n_pkts_tot,
40464023 ((mac_table[i].state ==
40474024 WLFC_STATE_OPEN) ? " OPEN":"CLOSE"),
40484025 mac_table[i].requested_credit,
....@@ -4052,27 +4029,27 @@
40524029 #ifdef PROP_TXSTATUS_DEBUG
40534030 bcm_bprintf(strbuf, "MAC_table[%d]: (opened, closed) = (%d, %d)\n",
40544031 i, mac_table[i].opened_ct, mac_table[i].closed_ct);
4055
-#endif
4032
+#endif // endif
40564033 bcm_bprintf(strbuf, "MAC_table[%d].PSQ"
40574034 "(delay0,sup0,afq0),(delay1,sup1,afq1),(delay2,sup2,afq2),"
40584035 "(delay3,sup3,afq3),(delay4,sup4,afq4) =(%d,%d,%d),"
40594036 "(%d,%d,%d),(%d,%d,%d),(%d,%d,%d),(%d,%d,%d)\n",
40604037 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);
40764053
40774054 }
40784055 }
....@@ -4164,9 +4141,10 @@
41644141 }
41654142 #endif /* PROP_TXSTATUS_DEBUG */
41664143 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)"
41684146 "(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",
41704148 wlfc->stats.pktin,
41714149 wlfc->stats.pkt2bus,
41724150 wlfc->stats.txstatus_in,
....@@ -4176,6 +4154,8 @@
41764154 wlfc->stats.pktdropped,
41774155 wlfc->stats.wlfc_header_only_pkt,
41784156 wlfc->stats.wlc_tossed_pkts,
4157
+ wlfc->stats.pkt_dropped,
4158
+ wlfc->stats.pkt_exptime,
41794159
41804160 wlfc->stats.pkt_freed,
41814161 wlfc->stats.pkt_free_err, wlfc->stats.rollback);
....@@ -4362,10 +4342,6 @@
43624342 dhd_os_wlfc_unblock(dhdp);
43634343 }
43644344
4365
-#if defined(DHD_WLFC_THREAD)
4366
- _dhd_wlfc_thread_wakeup(dhd);
4367
-#endif /* defined(DHD_WLFC_THREAD) */
4368
-
43694345 return BCME_OK;
43704346 }
43714347
....@@ -4459,6 +4435,11 @@
44594435 __FUNCTION__, tlv));
44604436 }
44614437 }
4438
+
4439
+#if defined(DHD_WLFC_THREAD)
4440
+ _dhd_wlfc_thread_wakeup(dhd);
4441
+#endif /* defined(DHD_WLFC_THREAD) */
4442
+
44624443 return BCME_OK;
44634444 }
44644445