From d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 11 Dec 2023 02:45:28 +0000
Subject: [PATCH] add boot partition  size

---
 kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/wl_roam.c |  519 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 513 insertions(+), 6 deletions(-)

diff --git a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/wl_roam.c b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/wl_roam.c
index aa5f6ff..e3be4aa 100644
--- a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/wl_roam.c
+++ b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/wl_roam.c
@@ -1,15 +1,16 @@
-/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Linux roam cache
  *
- * 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,5 +26,511 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: wl_roam.c 589977 2015-10-01 07:03:40Z $
+ * $Id: wl_roam.c 798173 2019-01-07 09:23:21Z $
  */
+
+#include <typedefs.h>
+#include <osl.h>
+#include <bcmwifi_channels.h>
+#include <wlioctl.h>
+#include <bcmutils.h>
+#ifdef WL_CFG80211
+#include <wl_cfg80211.h>
+#endif // endif
+#include <wldev_common.h>
+#include <bcmstdlib_s.h>
+
+#ifdef ESCAN_CHANNEL_CACHE
+#define MAX_ROAM_CACHE		200
+#define MAX_SSID_BUFSIZE	36
+
+#define ROAMSCAN_MODE_NORMAL	0
+#define ROAMSCAN_MODE_WES		1
+
+typedef struct {
+	chanspec_t chanspec;
+	int ssid_len;
+	char ssid[MAX_SSID_BUFSIZE];
+} roam_channel_cache;
+
+static int n_roam_cache = 0;
+static int roam_band = WLC_BAND_AUTO;
+static roam_channel_cache roam_cache[MAX_ROAM_CACHE];
+static uint band2G, band5G, band6G, band_bw;
+
+#ifdef WES_SUPPORT
+static int roamscan_mode = ROAMSCAN_MODE_NORMAL;
+#endif /* WES_SUPPORT */
+
+#ifdef ROAM_CHANNEL_CACHE
+int init_roam_cache(struct bcm_cfg80211 *cfg, int ioctl_ver)
+{
+	int err;
+	struct net_device *dev = bcmcfg_to_prmry_ndev(cfg);
+	s32 mode;
+
+	/* Check support in firmware */
+	err = wldev_iovar_getint(dev, "roamscan_mode", &mode);
+	if (err && (err == BCME_UNSUPPORTED)) {
+		/* If firmware doesn't support, return error. Else proceed */
+		WL_ERR(("roamscan_mode iovar failed. %d\n", err));
+		return err;
+	}
+
+#ifdef D11AC_IOTYPES
+	if (ioctl_ver == 1) {
+		/* legacy chanspec */
+		band2G = WL_LCHANSPEC_BAND_2G;
+		band5G = WL_LCHANSPEC_BAND_5G;
+		band_bw = WL_LCHANSPEC_BW_20 | WL_LCHANSPEC_CTL_SB_NONE;
+	} else {
+		band2G = WL_CHANSPEC_BAND_2G;
+		band5G = WL_CHANSPEC_BAND_5G;
+		band6G = WL_CHANSPEC_BAND_6G;
+		band_bw = WL_CHANSPEC_BW_20;
+	}
+#else
+	band2G = WL_CHANSPEC_BAND_2G;
+	band5G = WL_CHANSPEC_BAND_5G;
+	band6G = WL_CHANSPEC_BAND_6G;
+	band_bw = WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE;
+#endif /* D11AC_IOTYPES */
+
+	n_roam_cache = 0;
+	roam_band = WLC_BAND_AUTO;
+#ifdef WES_SUPPORT
+	roamscan_mode = ROAMSCAN_MODE_NORMAL;
+#endif /* WES_SUPPORT */
+
+	return 0;
+}
+#endif /* ROAM_CHANNEL_CACHE */
+
+#ifdef WES_SUPPORT
+int get_roamscan_mode(struct net_device *dev, int *mode)
+{
+	*mode = roamscan_mode;
+
+	return 0;
+}
+
+int set_roamscan_mode(struct net_device *dev, int mode)
+{
+	int error = 0;
+	roamscan_mode = mode;
+	n_roam_cache = 0;
+
+	error = wldev_iovar_setint(dev, "roamscan_mode", mode);
+	if (error) {
+		WL_ERR(("Failed to set roamscan mode to %d, error = %d\n", mode, error));
+	}
+
+	return error;
+}
+
+int get_roamscan_channel_list(struct net_device *dev, unsigned char channels[],
+	int n_channels)
+{
+	int n = 0;
+	int max_channel_number = MIN(n_channels, n_roam_cache);
+
+	if (roamscan_mode == ROAMSCAN_MODE_WES) {
+		for (n = 0; n < max_channel_number; n++) {
+			channels[n] = roam_cache[n].chanspec & WL_CHANSPEC_CHAN_MASK;
+
+			WL_DBG(("channel[%d] - [%02d] \n", n, channels[n]));
+		}
+	}
+
+	return n;
+}
+
+int set_roamscan_channel_list(struct net_device *dev,
+	unsigned char n, unsigned char channels[], int ioctl_ver)
+{
+	int i;
+	int error;
+	wl_roam_channel_list_t channel_list;
+	char iobuf[WLC_IOCTL_SMLEN];
+	roamscan_mode = ROAMSCAN_MODE_WES;
+
+	if (n > MAX_ROAM_CHANNEL)
+		n = MAX_ROAM_CHANNEL;
+
+	for (i = 0; i < n; i++) {
+		chanspec_t chanspec;
+
+		if (channels[i] <= CH_MAX_2G_CHANNEL) {
+			chanspec = band2G | band_bw | channels[i];
+		} else {
+			chanspec = band5G | band_bw | channels[i];
+		}
+		roam_cache[i].chanspec = chanspec;
+		channel_list.channels[i] = chanspec;
+
+		WL_DBG(("channel[%d] - [%02d] \n", i, channels[i]));
+	}
+
+	n_roam_cache = n;
+	channel_list.n = n;
+
+	/* need to set ROAMSCAN_MODE_NORMAL to update roamscan_channels,
+	 * otherwise, it won't be updated
+	 */
+	error = wldev_iovar_setint(dev, "roamscan_mode", ROAMSCAN_MODE_NORMAL);
+	if (error) {
+		WL_ERR(("Failed to set roamscan mode to %d, error = %d\n",
+			ROAMSCAN_MODE_NORMAL, error));
+		return error;
+	}
+	error = wldev_iovar_setbuf(dev, "roamscan_channels", &channel_list,
+		sizeof(channel_list), iobuf, sizeof(iobuf), NULL);
+	if (error) {
+		WL_ERR(("Failed to set roamscan channels, error = %d\n", error));
+		return error;
+	}
+	error = wldev_iovar_setint(dev, "roamscan_mode", ROAMSCAN_MODE_WES);
+	if (error) {
+		WL_ERR(("Failed to set roamscan mode to %d, error = %d\n",
+			ROAMSCAN_MODE_WES, error));
+	}
+
+	return error;
+}
+#endif /* WES_SUPPORT */
+
+#ifdef ESCAN_CHANNEL_CACHE
+void set_roam_band(int band)
+{
+	roam_band = band;
+}
+
+void reset_roam_cache(struct bcm_cfg80211 *cfg)
+{
+	if (!cfg->rcc_enabled) {
+		return;
+	}
+
+#ifdef WES_SUPPORT
+	if (roamscan_mode == ROAMSCAN_MODE_WES)
+		return;
+#endif /* WES_SUPPORT */
+
+	n_roam_cache = 0;
+}
+
+void add_roam_cache(struct bcm_cfg80211 *cfg, wl_bss_info_t *bi)
+{
+	int i;
+	uint8 channel;
+	char chanbuf[CHANSPEC_STR_LEN];
+
+	if (!cfg->rcc_enabled) {
+		return;
+	}
+
+#ifdef WES_SUPPORT
+	if (roamscan_mode == ROAMSCAN_MODE_WES)
+		return;
+#endif /* WES_SUPPORT */
+
+	if (n_roam_cache >= MAX_ROAM_CACHE)
+		return;
+
+	for (i = 0; i < n_roam_cache; i++) {
+		if ((roam_cache[i].ssid_len == bi->SSID_len) &&
+			(roam_cache[i].chanspec == bi->chanspec) &&
+			(memcmp(roam_cache[i].ssid, bi->SSID, bi->SSID_len) == 0)) {
+			/* identical one found, just return */
+			return;
+		}
+	}
+
+	roam_cache[n_roam_cache].ssid_len = bi->SSID_len;
+	channel = wf_chspec_ctlchan(bi->chanspec);
+	WL_DBG(("CHSPEC  = %s, CTL %d\n", wf_chspec_ntoa_ex(bi->chanspec, chanbuf), channel));
+	roam_cache[n_roam_cache].chanspec =
+		(CHSPEC_IS6G(wl_chspec_driver_to_host(bi->chanspec))?
+		band6G : (channel <= CH_MAX_2G_CHANNEL ? band2G : band5G)) | band_bw | channel;
+	(void)memcpy_s(roam_cache[n_roam_cache].ssid, bi->SSID_len, bi->SSID, bi->SSID_len);
+
+	n_roam_cache++;
+}
+
+static bool is_duplicated_channel(const chanspec_t *channels, int n_channels, chanspec_t new)
+{
+	int i;
+
+	for (i = 0; i < n_channels; i++) {
+		if (channels[i] == new)
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
+int get_roam_channel_list(int target_chan,
+	chanspec_t *channels, int n_channels, const wlc_ssid_t *ssid, int ioctl_ver,
+	struct ieee80211_channel *chan)
+{
+	int i, n = 1;
+	char chanbuf[CHANSPEC_STR_LEN];
+
+	/* first index is filled with the given target channel */
+	if (target_chan) {
+		channels[0] = (target_chan & WL_CHANSPEC_CHAN_MASK) |
+			(chan->center_freq > FREQ_START_6G_CHANNEL ?
+			band6G : (target_chan <= CH_MAX_2G_CHANNEL ? band2G : band5G)) | band_bw;
+	} else {
+		/* If target channel is not provided, set the index to 0 */
+		n = 0;
+	}
+
+	WL_DBG((" %s: %03d 0x%04X\n", __FUNCTION__, target_chan, channels[0]));
+
+#ifdef WES_SUPPORT
+	if (roamscan_mode == ROAMSCAN_MODE_WES) {
+		for (i = 0; i < n_roam_cache; i++) {
+			chanspec_t ch = roam_cache[i].chanspec;
+			bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
+			bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch);
+			bool is_6G = CHSPEC_IS6G(ch);
+			bool band_match = ((roam_band == WLC_BAND_AUTO) ||
+				((roam_band == WLC_BAND_2G) && is_2G) ||
+				((roam_band == WLC_BAND_5G) && is_5G) ||
+				((roam_band == WLC_BAND_6G) && is_6G));
+
+			ch = CHSPEC_CHANNEL(ch) | (is_2G ? band2G : band5G) | band_bw;
+			ch = CHSPEC_CHANNEL(ch) |
+				(is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
+			if (band_match && !is_duplicated_channel(channels, n, ch)) {
+				WL_DBG(("%s: Chanspec = %s\n", __FUNCTION__,
+					wf_chspec_ntoa_ex(ch, chanbuf)));
+				channels[n++] = ch;
+				if (n >= n_channels) {
+					WL_ERR(("Too many roam scan channels\n"));
+					return n;
+				}
+			}
+		}
+
+		return n;
+	}
+#endif /* WES_SUPPORT */
+
+	for (i = 0; i < n_roam_cache; i++) {
+		chanspec_t ch = roam_cache[i].chanspec;
+		bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
+		bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch);
+		bool is_6G = CHSPEC_IS6G(ch);
+		bool band_match = ((roam_band == WLC_BAND_AUTO) ||
+			((roam_band == WLC_BAND_2G) && is_2G) ||
+			((roam_band == WLC_BAND_5G) && is_5G) ||
+			((roam_band == WLC_BAND_6G) && is_6G));
+
+		ch = CHSPEC_CHANNEL(ch) | (is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
+		if ((roam_cache[i].ssid_len == ssid->SSID_len) &&
+			band_match && !is_duplicated_channel(channels, n, ch) &&
+			(memcmp(roam_cache[i].ssid, ssid->SSID, ssid->SSID_len) == 0)) {
+			/* match found, add it */
+			WL_DBG(("%s: Chanspec = %s\n", __FUNCTION__,
+				wf_chspec_ntoa_ex(ch, chanbuf)));
+			channels[n++] = ch;
+			if (n >= n_channels) {
+				WL_ERR(("Too many roam scan channels\n"));
+				return n;
+			}
+		}
+	}
+
+	return n;
+}
+#endif /* ESCAN_CHANNEL_CACHE */
+
+#ifdef ROAM_CHANNEL_CACHE
+void print_roam_cache(struct bcm_cfg80211 *cfg)
+{
+	int i;
+
+	if (!cfg->rcc_enabled) {
+		return;
+	}
+
+	WL_DBG((" %d cache\n", n_roam_cache));
+
+	for (i = 0; i < n_roam_cache; i++) {
+		roam_cache[i].ssid[roam_cache[i].ssid_len] = 0;
+		WL_DBG(("0x%02X %02d %s\n", roam_cache[i].chanspec,
+			roam_cache[i].ssid_len, roam_cache[i].ssid));
+	}
+}
+
+static void add_roamcache_channel(wl_roam_channel_list_t *channels, chanspec_t ch)
+{
+	int i;
+
+	if (channels->n >= MAX_ROAM_CHANNEL) /* buffer full */
+		return;
+
+	for (i = 0; i < channels->n; i++) {
+		if (channels->channels[i] == ch) /* already in the list */
+			return;
+	}
+
+	channels->channels[i] = ch;
+	channels->n++;
+
+	WL_DBG((" RCC: %02d 0x%04X\n",
+		ch & WL_CHANSPEC_CHAN_MASK, ch));
+}
+
+void update_roam_cache(struct bcm_cfg80211 *cfg, int ioctl_ver)
+{
+	int error, i, prev_channels;
+	wl_roam_channel_list_t channel_list;
+	char iobuf[WLC_IOCTL_SMLEN];
+	struct net_device *dev = bcmcfg_to_prmry_ndev(cfg);
+	wlc_ssid_t ssid;
+
+	if (!cfg->rcc_enabled) {
+		return;
+	}
+
+#ifdef WES_SUPPORT
+	if (roamscan_mode == ROAMSCAN_MODE_WES) {
+		/* no update when ROAMSCAN_MODE_WES */
+		return;
+	}
+#endif /* WES_SUPPORT */
+
+	if (!wl_get_drv_status(cfg, CONNECTED, dev)) {
+		WL_DBG(("Not associated\n"));
+		return;
+	}
+
+	/* need to read out the current cache list
+	   as the firmware may change dynamically
+	*/
+	error = wldev_iovar_getbuf(dev, "roamscan_channels", 0, 0,
+		(void *)&channel_list, sizeof(channel_list), NULL);
+	if (error) {
+		WL_ERR(("Failed to get roamscan channels, error = %d\n", error));
+		return;
+	}
+
+	error = wldev_get_ssid(dev, &ssid);
+	if (error) {
+		WL_ERR(("Failed to get SSID, err=%d\n", error));
+		return;
+	}
+
+	prev_channels = channel_list.n;
+	for (i = 0; i < n_roam_cache; i++) {
+		chanspec_t ch = roam_cache[i].chanspec;
+		bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
+		bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(ch) : CHSPEC_IS5G(ch);
+		bool is_6G = CHSPEC_IS6G(ch);
+		bool band_match = ((roam_band == WLC_BAND_AUTO) ||
+			((roam_band == WLC_BAND_2G) && is_2G) ||
+			((roam_band == WLC_BAND_5G) && is_5G) ||
+			((roam_band == WLC_BAND_6G) && is_6G));
+
+		if ((roam_cache[i].ssid_len == ssid.SSID_len) &&
+			band_match && (memcmp(roam_cache[i].ssid, ssid.SSID, ssid.SSID_len) == 0)) {
+			/* match found, add it */
+			ch = CHSPEC_CHANNEL(ch) |
+				(is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
+			add_roamcache_channel(&channel_list, ch);
+		}
+	}
+	if (prev_channels != channel_list.n) {
+		/* channel list updated */
+		error = wldev_iovar_setbuf(dev, "roamscan_channels", &channel_list,
+			sizeof(channel_list), iobuf, sizeof(iobuf), NULL);
+		if (error) {
+			WL_ERR(("Failed to update roamscan channels, error = %d\n", error));
+		}
+	}
+
+	WL_DBG(("%d AP, %d cache item(s), err=%d\n", n_roam_cache, channel_list.n, error));
+}
+
+void wl_update_roamscan_cache_by_band(struct net_device *dev, int band)
+{
+	int i, error, ioctl_ver, wes_mode;
+	wl_roam_channel_list_t chanlist_before, chanlist_after;
+	char iobuf[WLC_IOCTL_SMLEN];
+
+	roam_band = band;
+
+	error = wldev_iovar_getint(dev, "roamscan_mode", &wes_mode);
+	if (error) {
+		WL_ERR(("Failed to get roamscan mode, error = %d\n", error));
+		return;
+	}
+
+	ioctl_ver = wl_cfg80211_get_ioctl_version();
+	/* in case of WES mode, update channel list by band based on the cache in DHD */
+	if (wes_mode) {
+		int n = 0;
+		chanlist_before.n = n_roam_cache;
+
+		for (n = 0; n < n_roam_cache; n++) {
+			chanspec_t ch = roam_cache[n].chanspec;
+			bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(ch) : CHSPEC_IS2G(ch);
+			bool is_6G = CHSPEC_IS6G(ch);
+			chanlist_before.channels[n] = CHSPEC_CHANNEL(ch) |
+				(is_6G ? band6G : (is_2G ? band2G : band5G)) | band_bw;
+		}
+	} else {
+		if (band == WLC_BAND_AUTO) {
+			return;
+		}
+		error = wldev_iovar_getbuf(dev, "roamscan_channels", 0, 0,
+				(void *)&chanlist_before, sizeof(wl_roam_channel_list_t), NULL);
+		if (error) {
+			WL_ERR(("Failed to get roamscan channels, error = %d\n", error));
+			return;
+		}
+	}
+	chanlist_after.n = 0;
+	/* filtering by the given band */
+	for (i = 0; i < chanlist_before.n; i++) {
+		chanspec_t chspec = chanlist_before.channels[i];
+		bool is_2G = ioctl_ver == 1 ? LCHSPEC_IS2G(chspec) : CHSPEC_IS2G(chspec);
+		bool is_5G = ioctl_ver == 1 ? LCHSPEC_IS5G(chspec) : CHSPEC_IS5G(chspec);
+		bool is_6G = CHSPEC_IS6G(chspec);
+		bool band_match = ((band == WLC_BAND_AUTO) ||
+				((band == WLC_BAND_2G) && is_2G) ||
+				((band == WLC_BAND_5G) && is_5G) ||
+				((band == WLC_BAND_6G) && is_6G));
+		if (band_match) {
+			chanlist_after.channels[chanlist_after.n++] = chspec;
+		}
+	}
+
+	if (wes_mode) {
+		/* need to set ROAMSCAN_MODE_NORMAL to update roamscan_channels,
+		 * otherwise, it won't be updated
+		 */
+		wldev_iovar_setint(dev, "roamscan_mode", ROAMSCAN_MODE_NORMAL);
+
+		error = wldev_iovar_setbuf(dev, "roamscan_channels", &chanlist_after,
+				sizeof(wl_roam_channel_list_t), iobuf, sizeof(iobuf), NULL);
+		if (error) {
+			WL_ERR(("Failed to update roamscan channels, error = %d\n", error));
+		}
+		wldev_iovar_setint(dev, "roamscan_mode", ROAMSCAN_MODE_WES);
+	} else {
+		if (chanlist_before.n == chanlist_after.n) {
+			return;
+		}
+		error = wldev_iovar_setbuf(dev, "roamscan_channels", &chanlist_after,
+				sizeof(wl_roam_channel_list_t), iobuf, sizeof(iobuf), NULL);
+		if (error) {
+			WL_ERR(("Failed to update roamscan channels, error = %d\n", error));
+		}
+	}
+}
+#endif /* ROAM_CHANNEL_CACHE */
+#endif /* ESCAN_CHANNEL_CACHE */

--
Gitblit v1.6.2