From 297b60346df8beafee954a0fd7c2d64f33f3b9bc Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 11 May 2024 01:44:05 +0000
Subject: [PATCH] rtl8211F_led_control
---
kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_wlfc.c | 355 ++++++++++++++++++++++++++++-------------------------------
1 files changed, 168 insertions(+), 187 deletions(-)
diff --git a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_wlfc.c b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_wlfc.c
index f8f1595..ba83762 100644
--- a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_wlfc.c
+++ b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_wlfc.c
@@ -1,15 +1,16 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
* DHD PROP_TXSTATUS Module.
*
- * Copyright (C) 1999-2019, Broadcom Corporation
- *
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ *
+ * Copyright (C) 1999-2017, Broadcom Corporation
+ *
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
* under the terms of the GNU General Public License version 2 (the "GPL"),
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
* following added to such license:
- *
+ *
* As a special exception, the copyright holders of this software give you
* permission to link this software with independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that
@@ -17,7 +18,7 @@
* the license of that module. An independent module is a module which is not
* derived from this software. The special exception does not apply to any
* modifications of the software.
- *
+ *
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
@@ -25,10 +26,9 @@
*
* <<Broadcom-WL-IPTag/Open:>>
*
- * $Id: dhd_wlfc.c 606400 2015-12-15 09:59:42Z $
+ * $Id: dhd_wlfc.c 700323 2017-05-18 16:12:11Z $
*
*/
-
#include <typedefs.h>
#include <osl.h>
@@ -39,24 +39,18 @@
#include <dngl_stats.h>
#include <dhd.h>
-#ifdef BCMDBUS /* an abstraction layer that hides details of the underlying bus, eg \
- Linux USB */
-#include <dbus.h>
-#else
#include <dhd_bus.h>
-#endif /* BCMDBUS */
#include <dhd_dbg.h>
#ifdef PROP_TXSTATUS /* a form of flow control between host and dongle */
#include <wlfc_proto.h>
#include <dhd_wlfc.h>
-#endif
+#endif // endif
#ifdef DHDTCPACK_SUPPRESS
#include <dhd_ip.h>
#endif /* DHDTCPACK_SUPPRESS */
-
/*
* wlfc naming and lock rules:
@@ -72,14 +66,9 @@
#define WLFC_THREAD_RETRY_WAIT_MS 10000 /* 10 sec */
#endif /* defined (DHD_WLFC_THREAD) */
-#if defined(BCMDBUS)
-extern int dhd_dbus_txdata(dhd_pub_t *dhdp, void *pktbuf);
-#endif
-
#ifdef PROP_TXSTATUS
#define DHD_WLFC_QMON_COMPLETE(entry)
-
/** reordering related */
@@ -132,15 +121,13 @@
return;
ASSERT(prec >= 0 && prec < pq->num_prec);
- /* queueing chains not allowed and no segmented SKB (Kernel-3.18.y) */
- ASSERT(!((PKTLINK(p) != NULL) && (PKTLINK(p) != p)));
+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */
ASSERT(!pktq_full(pq));
- ASSERT(!pktq_pfull(pq, prec));
+ ASSERT(!pktqprec_full(pq, prec));
q = &pq->q[prec];
- PKTSETLINK(p, NULL);
if (q->head == NULL) {
/* empty queue */
q->head = p;
@@ -194,8 +181,8 @@
exit:
- q->len++;
- pq->len++;
+ q->n_pkts++;
+ pq->n_pkts_tot++;
if (pq->hi_prec < prec)
pq->hi_prec = (uint8)prec;
@@ -504,8 +491,12 @@
}
}
- q->len--;
- pq->len--;
+ q->n_pkts--;
+ pq->n_pkts_tot--;
+
+#ifdef WL_TXQ_STALL
+ q->dequeue_count++;
+#endif // endif
PKTSETLINK(p, NULL);
@@ -593,7 +584,6 @@
h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
if (PKTSUMNEEDED(p))
h->flags |= BDC_FLAG_SUM_NEEDED;
-
h->priority = (PKTPRIO(p) & BDC_PRIORITY_MASK);
h->flags2 = 0;
@@ -699,7 +689,10 @@
void *pout = NULL;
ASSERT(dhdp && p);
- ASSERT(prec >= 0 && prec <= WLFC_PSQ_PREC_COUNT);
+ if (prec < 0 || prec >= WLFC_PSQ_PREC_COUNT) {
+ ASSERT(0);
+ return BCME_BADARG;
+ }
ctx = (athost_wl_status_info_t*)dhdp->wlfc_state;
@@ -774,12 +767,12 @@
/* Fast case, precedence queue is not full and we are also not
* exceeding total queue length
*/
- if (!pktq_pfull(pq, prec) && !pktq_full(pq)) {
+ if (!pktqprec_full(pq, prec) && !pktq_full(pq)) {
goto exit;
}
/* Determine precedence from which to evict packet, if any */
- if (pktq_pfull(pq, prec)) {
+ if (pktqprec_full(pq, prec)) {
eprec = prec;
} else if (pktq_full(pq)) {
p = pktq_peek_tail(pq, &eprec);
@@ -788,7 +781,7 @@
return FALSE;
}
if ((eprec > prec) || (eprec < 0)) {
- if (!pktq_pempty(pq, prec)) {
+ if (!pktqprec_empty(pq, prec)) {
eprec = prec;
} else {
return FALSE;
@@ -799,7 +792,7 @@
/* Evict if needed */
if (eprec >= 0) {
/* Detect queueing to unconfigured precedence */
- ASSERT(!pktq_pempty(pq, eprec));
+ ASSERT(!pktqprec_empty(pq, eprec));
/* Evict all fragmented frames */
dhd_prec_drop_pkts(dhdp, pq, eprec, _dhd_wlfc_prec_drop);
}
@@ -940,18 +933,21 @@
dhdp = (dhd_pub_t *)ctx->dhdp;
ASSERT(dhdp);
- if (dhdp->skip_fc && dhdp->skip_fc())
+ if (if_id >= 255)
+ return;
+
+ if (dhdp->skip_fc && dhdp->skip_fc((void *)dhdp, if_id))
return;
if ((ctx->hostif_flow_state[if_id] == OFF) && !_dhd_wlfc_allow_fc(ctx, if_id))
return;
- if ((pq->len <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) {
+ if ((pq->n_pkts_tot <= WLFC_FLOWCONTROL_LOWATER) && (ctx->hostif_flow_state[if_id] == ON)) {
/* start traffic */
ctx->hostif_flow_state[if_id] = OFF;
/*
WLFC_DBGMESG(("qlen:%02d, if:%02d, ->OFF, start traffic %s()\n",
- pq->len, if_id, __FUNCTION__));
+ pq->n_pkts_tot, if_id, __FUNCTION__));
*/
WLFC_DBGMESG(("F"));
@@ -960,12 +956,12 @@
ctx->toggle_host_if = 0;
}
- if ((pq->len >= WLFC_FLOWCONTROL_HIWATER) && (ctx->hostif_flow_state[if_id] == OFF)) {
+ if (pq->n_pkts_tot >= WLFC_FLOWCONTROL_HIWATER && ctx->hostif_flow_state[if_id] == OFF) {
/* stop traffic */
ctx->hostif_flow_state[if_id] = ON;
/*
WLFC_DBGMESG(("qlen:%02d, if:%02d, ->ON, stop traffic %s()\n",
- pq->len, if_id, __FUNCTION__));
+ pq->n_pkts_tot, if_id, __FUNCTION__));
*/
WLFC_DBGMESG(("N"));
@@ -1002,15 +998,13 @@
DHD_PKTTAG_WLFCPKT_SET(PKTTAG(p), 1);
#ifdef PROP_TXSTATUS_DEBUG
ctx->stats.signal_only_pkts_sent++;
-#endif
+#endif // endif
#if defined(BCMPCIE)
rc = dhd_bus_txdata(dhdp->bus, p, ctx->host_ifidx);
-#elif defined(BCMDBUS)
- rc = dhd_dbus_txdata(dhdp, p);
#else
rc = dhd_bus_txdata(dhdp->bus, p);
-#endif
+#endif // endif
if (rc != BCME_OK) {
_dhd_wlfc_pullheader(ctx, p);
PKTFREE(ctx->osh, p, TRUE);
@@ -1041,8 +1035,8 @@
bool rc = FALSE;
if (entry->state == WLFC_STATE_CLOSE) {
- if ((pktq_plen(&entry->psq, (prec << 1)) == 0) &&
- (pktq_plen(&entry->psq, ((prec << 1) + 1)) == 0)) {
+ if ((pktqprec_n_pkts(&entry->psq, (prec << 1)) == 0) &&
+ (pktqprec_n_pkts(&entry->psq, ((prec << 1) + 1)) == 0)) {
/* no packets in both 'normal' and 'suspended' queues */
if (entry->traffic_pending_bmp & NBITVAL(prec)) {
rc = TRUE;
@@ -1218,7 +1212,7 @@
#ifdef PROP_TXSTATUS_DEBUG
h->items[hslot].push_time =
OSL_SYSUPTIME();
-#endif
+#endif // endif
} else {
DHD_ERROR(("%s() hanger_pushpkt() failed, rc: %d\n",
__FUNCTION__, rc));
@@ -1235,10 +1229,6 @@
h->items[hslot].pkt_txstatus = 0;
h->items[hslot].state = WLFC_HANGER_ITEM_STATE_INUSE;
}
- } else if (!WLFC_GET_AFQ(dhdp->wlfc_mode)) {
- /* clear hanger state */
- ((wlfc_hanger_t*)(ctx->hanger))->items[hslot].pkt_state = 0;
- ((wlfc_hanger_t*)(ctx->hanger))->items[hslot].pkt_txstatus = 0;
}
if ((rc == BCME_OK) && header_needed) {
@@ -1259,12 +1249,14 @@
_dhd_wlfc_is_destination_open(athost_wl_status_info_t* ctx,
wlfc_mac_descriptor_t* entry, int prec)
{
+ wlfc_mac_descriptor_t* interfaces = ctx->destination_entries.interfaces;
+
if (entry->interface_id >= WLFC_MAX_IFNUM) {
ASSERT(&ctx->destination_entries.other == entry);
return 1;
}
- if (ctx->destination_entries.interfaces[entry->interface_id].iftype ==
+ if (interfaces[entry->interface_id].iftype ==
WLC_E_IF_ROLE_P2P_GO) {
/* - destination interface is of type p2p GO.
For a p2pGO interface, if the destination is OPEN but the interface is
@@ -1279,7 +1271,9 @@
}
/* AP, p2p_go -> unicast desc entry, STA/p2p_cl -> interface desc. entry */
- if (((entry->state == WLFC_STATE_CLOSE) && (entry->requested_credit == 0) &&
+ if ((((entry->state == WLFC_STATE_CLOSE) ||
+ (interfaces[entry->interface_id].state == WLFC_STATE_CLOSE)) &&
+ (entry->requested_credit == 0) &&
(entry->requested_packet == 0)) ||
(!(entry->ac_bitmap & (1 << prec)))) {
return 0;
@@ -1357,7 +1351,7 @@
entry->requested_credit--;
#ifdef PROP_TXSTATUS_DEBUG
entry->dstncredit_sent_packets++;
-#endif
+#endif // endif
} else if (entry->requested_packet > 0) {
entry->requested_packet--;
DHD_PKTTAG_SETONETIMEPKTRQST(PKTTAG(p));
@@ -1406,7 +1400,6 @@
ctx->stats.delayq_full_error++;
return BCME_ERROR;
}
-
/* A packet has been pushed, update traffic availability bitmap, if applicable */
_dhd_wlfc_traffic_pending_check(ctx, entry, prec);
@@ -1543,7 +1536,7 @@
/* Optimize flush, if pktq len = 0, just return.
* pktq len of 0 means pktq's prec q's are all empty.
*/
- if (pq->len == 0) {
+ if (pq->n_pkts_tot == 0) {
return;
}
@@ -1608,8 +1601,12 @@
}
PKTFREE(ctx->osh, p, dir);
- q->len--;
- pq->len--;
+ q->n_pkts--;
+ pq->n_pkts_tot--;
+#ifdef WL_TXQ_STALL
+ q->dequeue_count++;
+#endif // endif
+
p = (head ? q->head : PKTLINK(prev));
} else {
prev = p;
@@ -1618,17 +1615,15 @@
}
if (q->head == NULL) {
- ASSERT(q->len == 0);
+ ASSERT(q->n_pkts == 0);
q->tail = NULL;
}
}
if (fn == NULL)
- ASSERT(pq->len == 0);
+ ASSERT(pq->n_pkts_tot == 0);
} /* _dhd_wlfc_pktq_flush */
-
-#ifndef BCMDBUS
/** !BCMDBUS specific function. Dequeues a packet from the caller supplied queue. */
static void*
@@ -1666,9 +1661,13 @@
}
}
- q->len--;
+ q->n_pkts--;
- pq->len--;
+ pq->n_pkts_tot--;
+
+#ifdef WL_TXQ_STALL
+ q->dequeue_count++;
+#endif // endif
PKTSETLINK(p, NULL);
@@ -1707,7 +1706,6 @@
}
dhd_os_sdunlock_txq(dhd);
-
while ((pkt = head)) {
head = PKTLINK(pkt);
PKTSETLINK(pkt, NULL);
@@ -1736,8 +1734,6 @@
}
} /* _dhd_wlfc_cleanup_txq */
-#endif /* !BCMDBUS */
-
/** called during eg detach */
void
_dhd_wlfc_cleanup(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
@@ -1755,10 +1751,8 @@
/*
* flush sequence should be txq -> psq -> hanger/afq, hanger has to be last one
*/
-#ifndef BCMDBUS
/* flush bus->txq */
_dhd_wlfc_cleanup_txq(dhd, fn, arg);
-#endif /* BCMDBUS */
/* flush psq, search all entries, include nodes as well as interfaces */
total_entries = sizeof(wlfc->destination_entries)/sizeof(wlfc_mac_descriptor_t);
@@ -1767,15 +1761,15 @@
for (i = 0; i < total_entries; i++) {
if (table[i].occupied) {
/* release packets held in PSQ (both delayed and suppressed) */
- if (table[i].psq.len) {
+ if (table[i].psq.n_pkts_tot) {
WLFC_DBGMESG(("%s(): PSQ[%d].len = %d\n",
- __FUNCTION__, i, table[i].psq.len));
+ __FUNCTION__, i, table[i].psq.n_pkts_tot));
_dhd_wlfc_pktq_flush(wlfc, &table[i].psq, TRUE,
fn, arg, Q_TYPE_PSQ);
}
/* free packets held in AFQ */
- if (WLFC_GET_AFQ(dhd->wlfc_mode) && (table[i].afq.len)) {
+ if (WLFC_GET_AFQ(dhd->wlfc_mode) && (table[i].afq.n_pkts_tot)) {
_dhd_wlfc_pktq_flush(wlfc, &table[i].afq, TRUE,
fn, arg, Q_TYPE_AFQ);
}
@@ -1819,7 +1813,6 @@
{
int rc = BCME_OK;
-
if ((action == eWLFC_MAC_ENTRY_ACTION_ADD) || (action == eWLFC_MAC_ENTRY_ACTION_UPDATE)) {
entry->occupied = 1;
entry->state = WLFC_STATE_OPEN;
@@ -1843,6 +1836,7 @@
dhd_pub_t *dhdp = (dhd_pub_t *)(ctx->dhdp);
pktq_init(&entry->psq, WLFC_PSQ_PREC_COUNT, WLFC_PSQ_LEN);
+ _dhd_wlfc_flow_control_check(ctx, &entry->psq, ifid);
if (WLFC_GET_AFQ(dhdp->wlfc_mode)) {
pktq_init(&entry->afq, WLFC_AFQ_PREC_COUNT, WLFC_PSQ_LEN);
@@ -1898,7 +1892,6 @@
}
return rc;
} /* _dhd_wlfc_mac_entry_update */
-
#ifdef LIMIT_BORROW
@@ -2189,8 +2182,13 @@
}
}
- q->len--;
- pq->len--;
+ q->n_pkts--;
+ pq->n_pkts_tot--;
+
+#ifdef WL_TXQ_STALL
+ q->dequeue_count++;
+#endif // endif
+
ctx->pkt_cnt_in_q[DHD_PKTTAG_IF(PKTTAG(p))][prec]--;
ctx->pkt_cnt_per_ac[prec]--;
@@ -2232,7 +2230,7 @@
if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) {
memcpy(&seq, pkt_info + WLFC_CTL_VALUE_LEN_TXSTATUS, WLFC_CTL_VALUE_LEN_SEQ);
seq = ltoh16(seq);
- seq_fromfw = WL_SEQ_GET_FROMFW(seq);
+ seq_fromfw = GET_WL_HAS_ASSIGNED_SEQ(seq);
seq_num = WL_SEQ_GET_NUM(seq);
}
@@ -2250,10 +2248,12 @@
remove_from_hanger = 0;
} else if (status_flag == WLFC_CTL_PKTFLAG_TOSSED_BYWLC) {
wlfc->stats.wlc_tossed_pkts += len;
- }
-
- else if (status_flag == WLFC_CTL_PKTFLAG_SUPPRESS_ACKED) {
+ } else if (status_flag == WLFC_CTL_PKTFLAG_SUPPRESS_ACKED) {
wlfc->stats.pkt_freed += len;
+ } else if (status_flag == WLFC_CTL_PKTFLAG_EXPIRED) {
+ wlfc->stats.pkt_exptime += len;
+ } else if (status_flag == WLFC_CTL_PKTFLAG_DROPPED) {
+ wlfc->stats.pkt_dropped += len;
}
if (dhd->proptxstatus_txstatus_ignore) {
@@ -2326,7 +2326,6 @@
uint32 delta;
old_t = ((wlfc_hanger_t*)(wlfc->hanger))->items[hslot].push_time;
-
wlfc->stats.latency_sample_count++;
if (new_t > old_t)
delta = new_t - old_t;
@@ -2357,7 +2356,7 @@
}
#ifdef PROP_TXSTATUS_DEBUG
entry->dstncredit_acks++;
-#endif
+#endif // endif
}
if ((status_flag == WLFC_CTL_PKTFLAG_D11SUPPRESS) ||
@@ -2366,7 +2365,7 @@
WL_TXSTATUS_SET_GENERATION(DHD_PKTTAG_H2DTAG(PKTTAG(pktbuf)), gen);
if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) {
- WL_SEQ_SET_FROMDRV(DHD_PKTTAG_H2DSEQ(PKTTAG(pktbuf)), seq_fromfw);
+ WL_SEQ_SET_REUSE(DHD_PKTTAG_H2DSEQ(PKTTAG(pktbuf)), seq_fromfw);
WL_SEQ_SET_NUM(DHD_PKTTAG_H2DSEQ(PKTTAG(pktbuf)), seq_num);
}
@@ -2438,7 +2437,7 @@
for (i = 0; i < WLFC_CTL_VALUE_LEN_FIFO_CREDITBACK; i++) {
#ifdef PROP_TXSTATUS_DEBUG
wlfc->stats.fifo_credits_back[i] += credits[i];
-#endif
+#endif // endif
/* update FIFO credits */
if (dhd->proptxstatus_mode == WLFC_FCMODE_EXPLICIT_CREDIT)
@@ -2480,8 +2479,6 @@
return BCME_OK;
} /* _dhd_wlfc_fifocreditback_indicate */
-#ifndef BCMDBUS
-
/** !BCMDBUS specific function */
static void
_dhd_wlfc_suppress_txq(dhd_pub_t *dhd, f_processpkt_t fn, void *arg)
@@ -2516,15 +2513,18 @@
PKTSETLINK(pkt, NULL);
entry = _dhd_wlfc_find_table_entry(wlfc, pkt);
- if (entry) {
- if (entry->onbus_pkts_count > 0)
- entry->onbus_pkts_count--;
- if (entry->suppressed &&
- (!entry->onbus_pkts_count) &&
- (!entry->suppr_transit_count))
- entry->suppressed = FALSE;
+ if (!entry) {
+ PKTFREE(dhd->osh, pkt, TRUE);
+ continue;
}
-
+ if (entry->onbus_pkts_count > 0) {
+ entry->onbus_pkts_count--;
+ }
+ if (entry->suppressed &&
+ (!entry->onbus_pkts_count) &&
+ (!entry->suppr_transit_count)) {
+ entry->suppressed = FALSE;
+ }
/* fake a suppression txstatus */
htod = DHD_PKTTAG_H2DTAG(PKTTAG(pkt));
WL_TXSTATUS_SET_FLAGS(htod, WLFC_CTL_PKTFLAG_WLSUPPRESS);
@@ -2533,9 +2533,9 @@
memcpy(results, &htod, WLFC_CTL_VALUE_LEN_TXSTATUS);
if (WLFC_GET_REUSESEQ(dhd->wlfc_mode)) {
htodseq = DHD_PKTTAG_H2DSEQ(PKTTAG(pkt));
- if (WL_SEQ_GET_FROMDRV(htodseq)) {
- WL_SEQ_SET_FROMFW(htodseq, 1);
- WL_SEQ_SET_FROMDRV(htodseq, 0);
+ if (IS_WL_TO_REUSE_SEQ(htodseq)) {
+ SET_WL_HAS_ASSIGNED_SEQ(htodseq);
+ RESET_WL_TO_REUSE_SEQ(htodseq);
}
htodseq = htol16(htodseq);
memcpy(results + WLFC_CTL_VALUE_LEN_TXSTATUS, &htodseq,
@@ -2557,8 +2557,6 @@
_dhd_wlfc_fifocreditback_indicate(dhd, credits);
}
} /* _dhd_wlfc_suppress_txq */
-
-#endif /* !BCMDBUS */
static int
_dhd_wlfc_dbg_senum_check(dhd_pub_t *dhd, uint8 *value)
@@ -2643,8 +2641,8 @@
uint8 ifid;
uint8* ea;
- WLFC_DBGMESG(("%s(), mac [%02x:%02x:%02x:%02x:%02x:%02x],%s,idx:%d,id:0x%02x\n",
- __FUNCTION__, value[2], value[3], value[4], value[5], value[6], value[7],
+ WLFC_DBGMESG(("%s(), mac ["MACDBG"],%s,idx:%d,id:0x%02x\n",
+ __FUNCTION__, MAC2STRDBG(&value[2]),
((type == WLFC_CTL_TYPE_MACDESC_ADD) ? "ADD":"DEL"),
WLFC_MAC_DESC_GET_LOOKUP_INDEX(value[0]), value[0]));
@@ -2828,7 +2826,11 @@
_dhd_wlfc_reorderinfo_indicate(uint8 *val, uint8 len, uchar *info_buf, uint *info_len)
{
if (info_len) {
- if (info_buf) {
+ /* Check copy length to avoid buffer overrun. In case of length exceeding
+ * WLHOST_REORDERDATA_TOTLEN, return failure instead sending incomplete result
+ * of length WLHOST_REORDERDATA_TOTLEN
+ */
+ if ((info_buf) && (len <= WLHOST_REORDERDATA_TOTLEN)) {
bcopy(val, info_buf, len);
*info_len = len;
} else {
@@ -2923,7 +2925,6 @@
wlfc->allow_credit_borrow = 0;
wlfc->single_ac = 0;
wlfc->single_ac_timestamp = 0;
-
exit:
dhd_os_wlfc_unblock(dhd);
@@ -3082,12 +3083,10 @@
_dhd_wlfc_interface_update(dhd, value, type);
}
-#ifndef BCMDBUS
if (entry && WLFC_GET_REORDERSUPP(dhd->wlfc_mode)) {
/* suppress all packets for this mac entry from bus->txq */
_dhd_wlfc_suppress_txq(dhd, _dhd_wlfc_entrypkt_fn, entry);
}
-#endif /* !BCMDBUS */
} /* while */
if (remainder != 0 && wlfc) {
@@ -3101,7 +3100,7 @@
dhd_os_wlfc_unblock(dhd);
return BCME_OK;
-} /* dhd_wlfc_parse_header_info */
+}
KERNEL_THREAD_RETURN_TYPE
dhd_wlfc_transfer_packets(void *data)
@@ -3112,6 +3111,7 @@
athost_wl_status_info_t* ctx;
int bus_retry_count = 0;
int pkt_send = 0;
+ int pkt_send_per_ac = 0;
uint8 tx_map = 0; /* packets (send + in queue), Bitmask for 4 ACs + BC/MC */
uint8 rx_map = 0; /* received packets, Bitmask for 4 ACs + BC/MC */
@@ -3179,7 +3179,9 @@
tx_map |= (1 << ac);
single_ac = ac + 1;
- while (FALSE == dhdp->proptxstatus_txoff) {
+ pkt_send_per_ac = 0;
+ while ((FALSE == dhdp->proptxstatus_txoff) &&
+ (pkt_send_per_ac < WLFC_PACKET_BOUND)) {
/* packets from delayQ with less priority are fresh and
* they'd need header and have no MAC entry
*/
@@ -3199,7 +3201,7 @@
no_credit = FALSE;
}
}
-#endif
+#endif // endif
commit_info.needs_hdr = 1;
commit_info.mac_entry = NULL;
commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
@@ -3215,7 +3217,7 @@
if (lender != -1 && dhdp->wlfc_borrow_allowed) {
_dhd_wlfc_return_credit(ctx, lender, ac);
}
-#endif
+#endif // endif
break;
}
@@ -3229,6 +3231,7 @@
/* Bus commits may fail (e.g. flow control); abort after retries */
if (rc == BCME_OK) {
pkt_send++;
+ pkt_send_per_ac++;
if (commit_info.ac_fifo_credit_spent && (lender == -1)) {
ctx->FIFO_credit[ac]--;
}
@@ -3237,13 +3240,13 @@
dhdp->wlfc_borrow_allowed) {
_dhd_wlfc_return_credit(ctx, lender, ac);
}
-#endif
+#endif // endif
} else {
#ifdef LIMIT_BORROW
if (lender != -1 && dhdp->wlfc_borrow_allowed) {
_dhd_wlfc_return_credit(ctx, lender, ac);
}
-#endif
+#endif // endif
bus_retry_count++;
if (bus_retry_count >= BUS_RETRIES) {
DHD_ERROR(("%s: bus error %d\n", __FUNCTION__, rc));
@@ -3316,7 +3319,7 @@
}
else
break;
-#endif
+#endif // endif
commit_info.p = _dhd_wlfc_deque_delayedq(ctx, ac,
&(commit_info.ac_fifo_credit_spent),
&(commit_info.needs_hdr),
@@ -3326,7 +3329,7 @@
/* before borrow only one ac exists and now this only ac is empty */
#ifdef LIMIT_BORROW
_dhd_wlfc_return_credit(ctx, lender, ac);
-#endif
+#endif // endif
break;
}
@@ -3342,16 +3345,16 @@
if (commit_info.ac_fifo_credit_spent) {
#ifndef LIMIT_BORROW
ctx->FIFO_credit[ac]--;
-#endif
+#endif // endif
} else {
#ifdef LIMIT_BORROW
_dhd_wlfc_return_credit(ctx, lender, ac);
-#endif
+#endif // endif
}
} else {
#ifdef LIMIT_BORROW
_dhd_wlfc_return_credit(ctx, lender, ac);
-#endif
+#endif // endif
bus_retry_count++;
if (bus_retry_count >= BUS_RETRIES) {
DHD_ERROR(("%s: bus error %d\n", __FUNCTION__, rc));
@@ -3414,16 +3417,6 @@
}
ctx = (athost_wl_status_info_t*)dhdp->wlfc_state;
-
-#ifdef BCMDBUS
- if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN)) {
- if (pktbuf) {
- PKTFREE(ctx->osh, pktbuf, TRUE);
- rc = BCME_OK;
- }
- goto exit;
- }
-#endif
if (dhdp->proptxstatus_module_ignore) {
if (pktbuf) {
@@ -3503,7 +3496,7 @@
if (DHD_PKTTAG_SIGNALONLY(PKTTAG(txp))) {
#ifdef PROP_TXSTATUS_DEBUG
wlfc->stats.signal_only_pkts_freed++;
-#endif
+#endif // endif
/* is this a signal-only packet? */
_dhd_wlfc_pullheader(wlfc, txp);
PKTFREE(wlfc->osh, txp, TRUE);
@@ -3546,7 +3539,6 @@
}
}
- ASSERT(entry->onbus_pkts_count > 0);
if (entry->onbus_pkts_count > 0)
entry->onbus_pkts_count--;
if (entry->suppressed &&
@@ -3585,7 +3577,6 @@
WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE |
WLFC_FLAGS_HOST_RXRERODER_ACTIVE;
-
/*
try to enable/disable signaling by sending "tlv" iovar. if that fails,
fallback to no flow control? Print a message for now.
@@ -3610,18 +3601,10 @@
DHD_INFO(("%s: query wlfc_mode succeed, fw_caps=0x%x\n", __FUNCTION__, fw_caps));
if (WLFC_IS_OLD_DEF(fw_caps)) {
-#ifdef BCMDBUS
- mode = WLFC_MODE_HANGER;
-#else
/* enable proptxtstatus v2 by default */
mode = WLFC_MODE_AFQ;
-#endif /* BCMDBUS */
} else {
WLFC_SET_AFQ(mode, WLFC_GET_AFQ(fw_caps));
-#ifdef BCMDBUS
- WLFC_SET_AFQ(mode, 0);
-#endif /* BCMDBUS */
- WLFC_SET_REUSESEQ(mode, WLFC_GET_REUSESEQ(fw_caps));
WLFC_SET_REORDERSUPP(mode, WLFC_GET_REORDERSUPP(fw_caps));
}
ret = dhd_wl_ioctl_set_intiovar(dhd, "wlfc_mode", mode, WLC_SET_VAR, TRUE, 0);
@@ -3641,7 +3624,7 @@
DHD_INFO(("dhd_wlfc_init(): wlfc_mode=0x%x, ret=%d\n", dhd->wlfc_mode, ret));
#ifdef LIMIT_BORROW
dhd->wlfc_borrow_allowed = TRUE;
-#endif
+#endif // endif
dhd_os_wlfc_unblock(dhd);
if (dhd->plat_init)
@@ -3701,9 +3684,7 @@
return WLFC_UNSUPPORTED;
}
-#ifndef BCMDBUS
_dhd_wlfc_cleanup_txq(dhd, fn, arg);
-#endif /* !BCMDBUS */
dhd_os_wlfc_unblock(dhd);
@@ -3794,7 +3775,6 @@
_dhd_wlfc_hanger_delete(dhd, h);
}
-
/* free top structure */
DHD_OS_PREFREE(dhd, dhd->wlfc_state,
sizeof(athost_wl_status_info_t));
@@ -3862,8 +3842,7 @@
#ifdef LIMIT_BORROW
int dhd_wlfc_disable_credit_borrow_event(dhd_pub_t *dhdp, uint8* event_data)
{
- int rc;
- if (dhdp == NULL) {
+ if (dhdp == NULL || event_data == NULL) {
DHD_ERROR(("Error: %s():%d\n", __FUNCTION__, __LINE__));
return BCME_BADARG;
}
@@ -3871,7 +3850,7 @@
dhdp->wlfc_borrow_allowed = (bool)(*(uint32 *)event_data);
dhd_os_wlfc_unblock(dhdp);
- return rc;
+ return BCME_OK;
}
#endif /* LIMIT_BORROW */
@@ -3987,10 +3966,9 @@
ea = interfaces[i].ea;
bcm_bprintf(strbuf, "INTERFACE[%d].ea = "
- "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d, type: %s "
+ "["MACDBG"], if:%d, type: %s "
"netif_flow_control:%s\n", i,
- ea[0], ea[1], ea[2], ea[3], ea[4], ea[5],
- interfaces[i].interface_id,
+ MAC2STRDBG(ea), interfaces[i].interface_id,
iftype_desc, ((wlfc->hostif_flow_state[i] == OFF)
? " OFF":" ON"));
@@ -3998,7 +3976,7 @@
"(trans,supp_trans,onbus)"
"= (%d,%s,%d),(%d,%d,%d)\n",
i,
- interfaces[i].psq.len,
+ interfaces[i].psq.n_pkts_tot,
((interfaces[i].state ==
WLFC_STATE_OPEN) ? "OPEN":"CLOSE"),
interfaces[i].requested_credit,
@@ -4011,21 +3989,21 @@
"(delay3,sup3,afq3),(delay4,sup4,afq4) = (%d,%d,%d),"
"(%d,%d,%d),(%d,%d,%d),(%d,%d,%d),(%d,%d,%d)\n",
i,
- interfaces[i].psq.q[0].len,
- interfaces[i].psq.q[1].len,
- interfaces[i].afq.q[0].len,
- interfaces[i].psq.q[2].len,
- interfaces[i].psq.q[3].len,
- interfaces[i].afq.q[1].len,
- interfaces[i].psq.q[4].len,
- interfaces[i].psq.q[5].len,
- interfaces[i].afq.q[2].len,
- interfaces[i].psq.q[6].len,
- interfaces[i].psq.q[7].len,
- interfaces[i].afq.q[3].len,
- interfaces[i].psq.q[8].len,
- interfaces[i].psq.q[9].len,
- interfaces[i].afq.q[4].len);
+ interfaces[i].psq.q[0].n_pkts,
+ interfaces[i].psq.q[1].n_pkts,
+ interfaces[i].afq.q[0].n_pkts,
+ interfaces[i].psq.q[2].n_pkts,
+ interfaces[i].psq.q[3].n_pkts,
+ interfaces[i].afq.q[1].n_pkts,
+ interfaces[i].psq.q[4].n_pkts,
+ interfaces[i].psq.q[5].n_pkts,
+ interfaces[i].afq.q[2].n_pkts,
+ interfaces[i].psq.q[6].n_pkts,
+ interfaces[i].psq.q[7].n_pkts,
+ interfaces[i].afq.q[3].n_pkts,
+ interfaces[i].psq.q[8].n_pkts,
+ interfaces[i].psq.q[9].n_pkts,
+ interfaces[i].afq.q[4].n_pkts);
}
}
@@ -4034,15 +4012,14 @@
if (mac_table[i].occupied) {
ea = mac_table[i].ea;
bcm_bprintf(strbuf, "MAC_table[%d].ea = "
- "[%02x:%02x:%02x:%02x:%02x:%02x], if:%d \n", i,
- ea[0], ea[1], ea[2], ea[3], ea[4], ea[5],
- mac_table[i].interface_id);
+ "["MACDBG"], if:%d \n", i,
+ MAC2STRDBG(ea), mac_table[i].interface_id);
bcm_bprintf(strbuf, "MAC_table[%d].PSQ(len,state,credit),"
"(trans,supp_trans,onbus)"
"= (%d,%s,%d),(%d,%d,%d)\n",
i,
- mac_table[i].psq.len,
+ mac_table[i].psq.n_pkts_tot,
((mac_table[i].state ==
WLFC_STATE_OPEN) ? " OPEN":"CLOSE"),
mac_table[i].requested_credit,
@@ -4052,27 +4029,27 @@
#ifdef PROP_TXSTATUS_DEBUG
bcm_bprintf(strbuf, "MAC_table[%d]: (opened, closed) = (%d, %d)\n",
i, mac_table[i].opened_ct, mac_table[i].closed_ct);
-#endif
+#endif // endif
bcm_bprintf(strbuf, "MAC_table[%d].PSQ"
"(delay0,sup0,afq0),(delay1,sup1,afq1),(delay2,sup2,afq2),"
"(delay3,sup3,afq3),(delay4,sup4,afq4) =(%d,%d,%d),"
"(%d,%d,%d),(%d,%d,%d),(%d,%d,%d),(%d,%d,%d)\n",
i,
- mac_table[i].psq.q[0].len,
- mac_table[i].psq.q[1].len,
- mac_table[i].afq.q[0].len,
- mac_table[i].psq.q[2].len,
- mac_table[i].psq.q[3].len,
- mac_table[i].afq.q[1].len,
- mac_table[i].psq.q[4].len,
- mac_table[i].psq.q[5].len,
- mac_table[i].afq.q[2].len,
- mac_table[i].psq.q[6].len,
- mac_table[i].psq.q[7].len,
- mac_table[i].afq.q[3].len,
- mac_table[i].psq.q[8].len,
- mac_table[i].psq.q[9].len,
- mac_table[i].afq.q[4].len);
+ mac_table[i].psq.q[0].n_pkts,
+ mac_table[i].psq.q[1].n_pkts,
+ mac_table[i].afq.q[0].n_pkts,
+ mac_table[i].psq.q[2].n_pkts,
+ mac_table[i].psq.q[3].n_pkts,
+ mac_table[i].afq.q[1].n_pkts,
+ mac_table[i].psq.q[4].n_pkts,
+ mac_table[i].psq.q[5].n_pkts,
+ mac_table[i].afq.q[2].n_pkts,
+ mac_table[i].psq.q[6].n_pkts,
+ mac_table[i].psq.q[7].n_pkts,
+ mac_table[i].afq.q[3].n_pkts,
+ mac_table[i].psq.q[8].n_pkts,
+ mac_table[i].psq.q[9].n_pkts,
+ mac_table[i].afq.q[4].n_pkts);
}
}
@@ -4164,9 +4141,10 @@
}
#endif /* PROP_TXSTATUS_DEBUG */
bcm_bprintf(strbuf, "\n");
- bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull,out),(dropped,hdr_only,wlc_tossed)"
+ bcm_bprintf(strbuf, "wlfc- pkt((in,2bus,txstats,hdrpull,out),"
+ "(dropped,hdr_only,wlc_tossed,wlc_dropped,wlc_exptime)"
"(freed,free_err,rollback)) = "
- "((%d,%d,%d,%d,%d),(%d,%d,%d),(%d,%d,%d))\n",
+ "((%d,%d,%d,%d,%d),(%d,%d,%d,%d,%d),(%d,%d,%d))\n",
wlfc->stats.pktin,
wlfc->stats.pkt2bus,
wlfc->stats.txstatus_in,
@@ -4176,6 +4154,8 @@
wlfc->stats.pktdropped,
wlfc->stats.wlfc_header_only_pkt,
wlfc->stats.wlc_tossed_pkts,
+ wlfc->stats.pkt_dropped,
+ wlfc->stats.pkt_exptime,
wlfc->stats.pkt_freed,
wlfc->stats.pkt_free_err, wlfc->stats.rollback);
@@ -4362,10 +4342,6 @@
dhd_os_wlfc_unblock(dhdp);
}
-#if defined(DHD_WLFC_THREAD)
- _dhd_wlfc_thread_wakeup(dhd);
-#endif /* defined(DHD_WLFC_THREAD) */
-
return BCME_OK;
}
@@ -4459,6 +4435,11 @@
__FUNCTION__, tlv));
}
}
+
+#if defined(DHD_WLFC_THREAD)
+ _dhd_wlfc_thread_wakeup(dhd);
+#endif /* defined(DHD_WLFC_THREAD) */
+
return BCME_OK;
}
--
Gitblit v1.6.2