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_ip.c | 352 ++++++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 254 insertions(+), 98 deletions(-)
diff --git a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_ip.c b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_ip.c
index 96b1a2f..aef39ba 100644
--- a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_ip.c
+++ b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_ip.c
@@ -1,15 +1,16 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
* IP Packet Parser 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,26 +26,26 @@
*
* <<Broadcom-WL-IPTag/Open:>>
*
- * $Id: dhd_ip.c 709309 2019-01-17 09:04:00Z $
+ * $Id: dhd_ip.c 700444 2017-05-19 06:38:00Z $
*/
#include <typedefs.h>
#include <osl.h>
-#include <proto/ethernet.h>
-#include <proto/vlan.h>
-#include <proto/802.3.h>
-#include <proto/bcmip.h>
+#include <ethernet.h>
+#include <vlan.h>
+#include <802.3.h>
+#include <bcmip.h>
#include <bcmendian.h>
#include <dhd_dbg.h>
#include <dhd_ip.h>
-#ifdef DHDTCPACK_SUPPRESS
+#if defined(DHDTCPACK_SUPPRESS) || defined(DHDTCPSYNC_FLOOD_BLK)
#include <dhd_bus.h>
#include <dhd_proto.h>
-#include <proto/bcmtcp.h>
-#endif /* DHDTCPACK_SUPPRESS */
+#include <bcmtcp.h>
+#endif /* DHDTCPACK_SUPPRESS || DHDTCPSYNC_FLOOD_BLK */
/* special values */
/* 802.3 llc/snap header */
@@ -128,7 +129,15 @@
int ifidx;
uint8 supp_cnt;
dhd_pub_t *dhdp;
- struct timer_list timer;
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+ timer_list_compat_t timer;
+#else
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(5, 1, 21))
+ struct tasklet_hrtimer timer;
+#else
+ struct hrtimer timer;
+#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(5, 1, 21) */
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
} tcpack_info_t;
typedef struct _tdata_psh_info_t {
@@ -182,7 +191,7 @@
tcpack_sup_mod->tdata_psh_info_free = tdata_psh_info;
#ifdef DHDTCPACK_SUP_DBG
tcpack_sup_mod->psh_info_enq_num++;
-#endif
+#endif // endif
}
static tdata_psh_info_t*
@@ -290,44 +299,54 @@
}
#endif /* BCMSDIO */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
-static void dhd_tcpack_send(struct timer_list *t)
-{
- tcpack_info_t *cur_tbl = from_timer(cur_tbl, t, timer);
-#else
+#ifdef BCMPCIE
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
static void dhd_tcpack_send(ulong data)
+#else
+static enum hrtimer_restart dhd_tcpack_send(struct hrtimer *timer)
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
{
- tcpack_info_t *cur_tbl = (tcpack_info_t *)data;
-#endif
tcpack_sup_module_t *tcpack_sup_mod;
+ tcpack_info_t *cur_tbl;
dhd_pub_t *dhdp;
int ifidx;
void* pkt;
unsigned long flags;
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+ cur_tbl = (tcpack_info_t *)data;
+#else
+ cur_tbl = container_of(timer, tcpack_info_t, timer.timer);
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+
if (!cur_tbl) {
- return;
+ goto done;
}
dhdp = cur_tbl->dhdp;
if (!dhdp) {
- return;
+ goto done;
}
flags = dhd_os_tcpacklock(dhdp);
+
+ if (unlikely(dhdp->tcpack_sup_mode != TCPACK_SUP_HOLD)) {
+ dhd_os_tcpackunlock(dhdp, flags);
+ goto done;
+ }
tcpack_sup_mod = dhdp->tcpack_sup_module;
if (!tcpack_sup_mod) {
DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n",
__FUNCTION__, __LINE__));
dhd_os_tcpackunlock(dhdp, flags);
- return;
+ goto done;
}
pkt = cur_tbl->pkt_in_q;
ifidx = cur_tbl->ifidx;
if (!pkt) {
dhd_os_tcpackunlock(dhdp, flags);
- return;
+ goto done;
}
cur_tbl->pkt_in_q = NULL;
cur_tbl->pkt_ether_hdr = NULL;
@@ -341,99 +360,169 @@
dhd_os_tcpackunlock(dhdp, flags);
dhd_sendpkt(dhdp, ifidx, pkt);
+
+done:
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+ return;
+#else
+ return HRTIMER_NORESTART;
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
}
+#endif /* BCMPCIE */
int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 mode)
{
int ret = BCME_OK;
unsigned long flags;
+ tcpack_sup_module_t *tcpack_sup_module;
+ uint8 invalid_mode = FALSE;
+ int prev_mode;
+ int i = 0;
flags = dhd_os_tcpacklock(dhdp);
+ tcpack_sup_module = dhdp->tcpack_sup_module;
+ prev_mode = dhdp->tcpack_sup_mode;
- if (dhdp->tcpack_sup_mode == mode) {
+ if (prev_mode == mode) {
DHD_ERROR(("%s %d: already set to %d\n", __FUNCTION__, __LINE__, mode));
goto exit;
}
- if (mode >= TCPACK_SUP_LAST_MODE ||
-#ifndef BCMSDIO
- mode == TCPACK_SUP_DELAYTX ||
-#endif /* !BCMSDIO */
- FALSE) {
- DHD_ERROR(("%s %d: Invalid mode %d\n", __FUNCTION__, __LINE__, mode));
+ invalid_mode |= (mode >= TCPACK_SUP_LAST_MODE);
+#ifdef BCMSDIO
+ invalid_mode |= (mode == TCPACK_SUP_HOLD);
+#endif /* BCMSDIO */
+#ifdef BCMPCIE
+ invalid_mode |= ((mode == TCPACK_SUP_REPLACE) || (mode == TCPACK_SUP_DELAYTX));
+#endif /* BCMPCIE */
+
+ if (invalid_mode) {
+ DHD_ERROR(("%s %d: Invalid TCP ACK Suppress mode %d\n",
+ __FUNCTION__, __LINE__, mode));
ret = BCME_BADARG;
goto exit;
}
- DHD_TRACE(("%s: %d -> %d\n",
+ DHD_TRACE(("%s: TCP ACK Suppress mode %d -> mode %d\n",
__FUNCTION__, dhdp->tcpack_sup_mode, mode));
+ /* Pre-process routines to change a new mode as per previous mode */
+ switch (prev_mode) {
+ case TCPACK_SUP_OFF:
+ if (tcpack_sup_module == NULL) {
+ tcpack_sup_module = MALLOC(dhdp->osh, sizeof(tcpack_sup_module_t));
+ if (tcpack_sup_module == NULL) {
+ DHD_ERROR(("%s[%d]: Failed to allocate the new memory for "
+ "tcpack_sup_module\n", __FUNCTION__, __LINE__));
+ dhdp->tcpack_sup_mode = TCPACK_SUP_OFF;
+ ret = BCME_NOMEM;
+ goto exit;
+ }
+ dhdp->tcpack_sup_module = tcpack_sup_module;
+ }
+ bzero(tcpack_sup_module, sizeof(tcpack_sup_module_t));
+ break;
#ifdef BCMSDIO
- /* Old tcpack_sup_mode is TCPACK_SUP_DELAYTX */
- if (dhdp->tcpack_sup_mode == TCPACK_SUP_DELAYTX) {
- tcpack_sup_module_t *tcpack_sup_mod = dhdp->tcpack_sup_module;
- /* We won't need tdata_psh_info pool and tcpddata_info_tbl anymore */
- _tdata_psh_info_pool_deinit(dhdp, tcpack_sup_mod);
- tcpack_sup_mod->tcpdata_info_cnt = 0;
- bzero(tcpack_sup_mod->tcpdata_info_tbl,
- sizeof(tcpdata_info_t) * TCPDATA_INFO_MAXNUM);
- /* For half duplex bus interface, tx precedes rx by default */
- if (dhdp->bus)
- dhd_bus_set_dotxinrx(dhdp->bus, TRUE);
- }
+ case TCPACK_SUP_DELAYTX:
+ if (tcpack_sup_module) {
+ /* We won't need tdata_psh_info pool and
+ * tcpddata_info_tbl anymore
+ */
+ _tdata_psh_info_pool_deinit(dhdp, tcpack_sup_module);
+ tcpack_sup_module->tcpdata_info_cnt = 0;
+ bzero(tcpack_sup_module->tcpdata_info_tbl,
+ sizeof(tcpdata_info_t) * TCPDATA_INFO_MAXNUM);
+ }
+
+ /* For half duplex bus interface, tx precedes rx by default */
+ if (dhdp->bus) {
+ dhd_bus_set_dotxinrx(dhdp->bus, TRUE);
+ }
+
+ if (tcpack_sup_module == NULL) {
+ DHD_ERROR(("%s[%d]: tcpack_sup_module should not be NULL\n",
+ __FUNCTION__, __LINE__));
+ dhdp->tcpack_sup_mode = TCPACK_SUP_OFF;
+ goto exit;
+ }
+ break;
#endif /* BCMSDIO */
+ }
+
+ /* Update a new mode */
dhdp->tcpack_sup_mode = mode;
- if (mode == TCPACK_SUP_OFF) {
- ASSERT(dhdp->tcpack_sup_module != NULL);
- /* Clean up timer/data structure for any remaining/pending packet or timer. */
- dhd_tcpack_info_tbl_clean(dhdp);
- MFREE(dhdp->osh, dhdp->tcpack_sup_module, sizeof(tcpack_sup_module_t));
- dhdp->tcpack_sup_module = NULL;
- goto exit;
- }
-
- if (dhdp->tcpack_sup_module == NULL) {
- tcpack_sup_module_t *tcpack_sup_mod =
- MALLOC(dhdp->osh, sizeof(tcpack_sup_module_t));
- if (tcpack_sup_mod == NULL) {
- DHD_ERROR(("%s %d: No MEM\n", __FUNCTION__, __LINE__));
- dhdp->tcpack_sup_mode = TCPACK_SUP_OFF;
- ret = BCME_NOMEM;
- goto exit;
- }
- bzero(tcpack_sup_mod, sizeof(tcpack_sup_module_t));
- dhdp->tcpack_sup_module = tcpack_sup_mod;
- }
-
-#ifdef BCMSDIO
- if (mode == TCPACK_SUP_DELAYTX) {
- ret = _tdata_psh_info_pool_init(dhdp, dhdp->tcpack_sup_module);
- if (ret != BCME_OK)
- DHD_ERROR(("%s %d: pool init fail with %d\n", __FUNCTION__, __LINE__, ret));
- else if (dhdp->bus)
- dhd_bus_set_dotxinrx(dhdp->bus, FALSE);
- }
-#endif /* BCMSDIO */
-
- if (mode == TCPACK_SUP_HOLD) {
- int i;
- tcpack_sup_module_t *tcpack_sup_mod =
- (tcpack_sup_module_t *)dhdp->tcpack_sup_module;
- dhdp->tcpack_sup_ratio = CUSTOM_TCPACK_SUPP_RATIO;
- dhdp->tcpack_sup_delay = CUSTOM_TCPACK_DELAY_TIME;
- for (i = 0; i < TCPACK_INFO_MAXNUM; i++)
- {
- tcpack_sup_mod->tcpack_info_tbl[i].dhdp = dhdp;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
- timer_setup((struct timer_list *)&tcpack_sup_mod->tcpack_info_tbl[i].timer, dhd_tcpack_send, 0);
+ /* Process for a new mode */
+ switch (mode) {
+ case TCPACK_SUP_OFF:
+ ASSERT(tcpack_sup_module != NULL);
+ /* Clean up timer/data structure for
+ * any remaining/pending packet or timer.
+ */
+ if (tcpack_sup_module) {
+ /* Check if previous mode is TCAPACK_SUP_HOLD */
+ if (prev_mode == TCPACK_SUP_HOLD) {
+ for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
+ tcpack_info_t *tcpack_info_tbl =
+ &tcpack_sup_module->tcpack_info_tbl[i];
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+ del_timer(&tcpack_info_tbl->timer);
#else
- init_timer(&tcpack_sup_mod->tcpack_info_tbl[i].timer);
- tcpack_sup_mod->tcpack_info_tbl[i].timer.data =
- (ulong)&tcpack_sup_mod->tcpack_info_tbl[i];
- tcpack_sup_mod->tcpack_info_tbl[i].timer.function = dhd_tcpack_send;
-#endif
- }
+ hrtimer_cancel(&tcpack_info_tbl->timer.timer);
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+ if (tcpack_info_tbl->pkt_in_q) {
+ PKTFREE(dhdp->osh,
+ tcpack_info_tbl->pkt_in_q, TRUE);
+ tcpack_info_tbl->pkt_in_q = NULL;
+ }
+ }
+ }
+ MFREE(dhdp->osh, tcpack_sup_module, sizeof(tcpack_sup_module_t));
+ dhdp->tcpack_sup_module = NULL;
+ } else {
+ DHD_ERROR(("%s[%d]: tcpack_sup_module should not be NULL\n",
+ __FUNCTION__, __LINE__));
+ }
+ break;
+#ifdef BCMSDIO
+ case TCPACK_SUP_REPLACE:
+ /* There is nothing to configure for this mode */
+ break;
+ case TCPACK_SUP_DELAYTX:
+ ret = _tdata_psh_info_pool_init(dhdp, tcpack_sup_module);
+ if (ret != BCME_OK) {
+ DHD_ERROR(("%s %d: pool init fail with %d\n",
+ __FUNCTION__, __LINE__, ret));
+ break;
+ }
+ if (dhdp->bus) {
+ dhd_bus_set_dotxinrx(dhdp->bus, FALSE);
+ }
+ break;
+#endif /* BCMSDIO */
+#ifdef BCMPCIE
+ case TCPACK_SUP_HOLD:
+ dhdp->tcpack_sup_ratio = CUSTOM_TCPACK_SUPP_RATIO;
+ dhdp->tcpack_sup_delay = CUSTOM_TCPACK_DELAY_TIME;
+ for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
+ tcpack_info_t *tcpack_info_tbl =
+ &tcpack_sup_module->tcpack_info_tbl[i];
+ tcpack_info_tbl->dhdp = dhdp;
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+ init_timer_compat(&tcpack_info_tbl->timer,
+ dhd_tcpack_send, tcpack_info_tbl);
+#else
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(5, 1, 21))
+ tasklet_hrtimer_init(&tcpack_info_tbl->timer,
+ dhd_tcpack_send, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+#else
+ hrtimer_init(&tcpack_info_tbl->timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL_SOFT);
+#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(5, 1, 21) */
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+ }
+ break;
+#endif /* BCMPCIE */
}
exit:
@@ -480,7 +569,11 @@
if (dhdp->tcpack_sup_mode == TCPACK_SUP_HOLD) {
for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
del_timer_sync(&tcpack_sup_mod->tcpack_info_tbl[i].timer);
+#else
+ hrtimer_cancel(&tcpack_sup_mod->tcpack_info_tbl[i].timer.timer);
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
}
}
@@ -649,7 +742,6 @@
bool ret = FALSE;
bool set_dotxinrx = TRUE;
unsigned long flags;
-
if (dhdp->tcpack_sup_mode == TCPACK_SUP_OFF)
goto exit;
@@ -1193,7 +1285,7 @@
for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
void *oldpkt; /* TCPACK packet that is already in txq or DelayQ */
uint8 *old_ether_hdr, *old_ip_hdr, *old_tcp_hdr;
- uint32 old_ip_hdr_len, old_tcp_hdr_len;
+ uint32 old_ip_hdr_len;
uint32 old_tcpack_num; /* TCP ACK number of old TCPACK packet in Q */
if ((oldpkt = tcpack_info_tbl[i].pkt_in_q) == NULL) {
@@ -1215,7 +1307,6 @@
old_ip_hdr = old_ether_hdr + ETHER_HDR_LEN;
old_ip_hdr_len = IPV4_HLEN(old_ip_hdr);
old_tcp_hdr = old_ip_hdr + old_ip_hdr_len;
- old_tcp_hdr_len = 4 * TCP_HDRLEN(old_tcp_hdr[TCP_HLEN_OFFSET]);
DHD_TRACE(("%s %d: oldpkt %p[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
" TCP port %d %d\n", __FUNCTION__, __LINE__, oldpkt, i,
@@ -1254,7 +1345,11 @@
dhd_os_tcpackunlock(dhdp, flags);
if (!hold) {
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
del_timer_sync(&tcpack_info_tbl[i].timer);
+#else
+ hrtimer_cancel(&tcpack_sup_mod->tcpack_info_tbl[i].timer.timer);
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
}
goto exit;
}
@@ -1271,8 +1366,18 @@
tcpack_info_tbl[free_slot].pkt_ether_hdr = new_ether_hdr;
tcpack_info_tbl[free_slot].ifidx = ifidx;
tcpack_info_tbl[free_slot].supp_cnt = 1;
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
mod_timer(&tcpack_sup_mod->tcpack_info_tbl[free_slot].timer,
jiffies + msecs_to_jiffies(dhdp->tcpack_sup_delay));
+#else
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 1, 21)
+ tasklet_hrtimer_start(&tcpack_sup_mod->tcpack_info_tbl[free_slot].timer,
+ ktime_set(0, dhdp->tcpack_sup_delay*1000000), HRTIMER_MODE_REL);
+#else
+ hrtimer_start(&tcpack_sup_mod->tcpack_info_tbl[free_slot].timer,
+ ktime_set(0, dhdp->tcpack_sup_delay*1000000), HRTIMER_MODE_REL_SOFT);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) */
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
tcpack_sup_mod->tcpack_info_cnt++;
} else {
DHD_TRACE(("%s %d: No empty tcp ack info tbl\n",
@@ -1284,3 +1389,54 @@
return hold;
}
#endif /* DHDTCPACK_SUPPRESS */
+
+#ifdef DHDTCPSYNC_FLOOD_BLK
+tcp_hdr_flag_t
+dhd_tcpdata_get_flag(dhd_pub_t *dhdp, void *pkt)
+{
+ uint8 *ether_hdr; /* Ethernet header of the new packet */
+ uint16 ether_type; /* Ethernet type of the new packet */
+ uint8 *ip_hdr; /* IP header of the new packet */
+ uint8 *tcp_hdr; /* TCP header of the new packet */
+ uint32 ip_hdr_len; /* IP header length of the new packet */
+ uint32 cur_framelen;
+ uint8 flags;
+
+ ether_hdr = PKTDATA(dhdp->osh, pkt);
+ cur_framelen = PKTLEN(dhdp->osh, pkt);
+
+ ether_type = ether_hdr[12] << 8 | ether_hdr[13];
+
+ if (ether_type != ETHER_TYPE_IP) {
+ DHD_TRACE(("%s %d: Not a IP packet 0x%x\n",
+ __FUNCTION__, __LINE__, ether_type));
+ return FLAG_OTHERS;
+ }
+
+ ip_hdr = ether_hdr + ETHER_HDR_LEN;
+ cur_framelen -= ETHER_HDR_LEN;
+
+ if (cur_framelen < IPV4_MIN_HEADER_LEN) {
+ return FLAG_OTHERS;
+ }
+
+ ip_hdr_len = IPV4_HLEN(ip_hdr);
+ if (IP_VER(ip_hdr) != IP_VER_4 || IPV4_PROT(ip_hdr) != IP_PROT_TCP) {
+ DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n",
+ __FUNCTION__, __LINE__, IP_VER(ip_hdr), IPV4_PROT(ip_hdr)));
+ return FLAG_OTHERS;
+ }
+
+ tcp_hdr = ip_hdr + ip_hdr_len;
+
+ flags = (uint8)tcp_hdr[TCP_FLAGS_OFFSET];
+
+ if (flags & TCP_FLAG_SYN) {
+ if (flags & TCP_FLAG_ACK) {
+ return FLAG_SYNCACK;
+ }
+ return FLAG_SYNC;
+ }
+ return FLAG_OTHERS;
+}
+#endif /* DHDTCPSYNC_FLOOD_BLK */
--
Gitblit v1.6.2