From e3e12f52b214121840b44c91de5b3e5af5d3eb84 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 06 Nov 2023 03:04:41 +0000
Subject: [PATCH] rk3568 rt init

---
 kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c |  225 +++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 141 insertions(+), 84 deletions(-)

diff --git a/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c b/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c
index 6005a44..18d7714 100644
--- a/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c
+++ b/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c
@@ -617,11 +617,11 @@
 	}
 
 	param.band = chan_info->band;
-	err = wl_ext_iovar_getbuf(dev, "bw_cap", &param, sizeof(param),
+	err = wldev_iovar_getbuf(dev, "bw_cap", &param, sizeof(param),
 		iovar_buf, WLC_IOCTL_SMLEN, NULL);
 	if (err) {
 		if (err != BCME_UNSUPPORTED) {
-			AEXT_ERROR(dev->name, "bw_cap failed, %d\n", err);
+			AEXT_TRACE(dev->name, "bw_cap failed, %d\n", err);
 			return err;
 		} else {
 			err = wl_ext_iovar_getint(dev, "mimo_bw_cap", &bw_cap);
@@ -681,48 +681,59 @@
 static int
 wl_ext_channel(struct net_device *dev, char* command, int total_len)
 {
+	struct dhd_pub *dhd = dhd_get_pub(dev);
 	struct wl_chan_info chan_info;
-	int ret;
-	char band[16]="";
-	int channel = 0;
-	channel_info_t ci;
-	int bytes_written = 0;
-	chanspec_t fw_chspec;
+	char chan[16]="";
+	int ret, bytes_written = 0;
+	chanspec_t chanspec;
+	u32 fw_chanspec = 0;
+
+	/* get: dhd_priv channel
+	  * set: dhd_priv channel [6|36|2g6|5g36|6g5]
+	*/
 
 	AEXT_TRACE(dev->name, "cmd %s", command);
 
-	sscanf(command, "%*s %d %s", &channel, band);
-	if (strnicmp(band, "band=auto", strlen("band=auto")) == 0) {
-		chan_info.band = WLC_BAND_AUTO;
+	sscanf(command, "%*s %s", chan);
+	memset(&chan_info, 0, sizeof(struct wl_chan_info));
+	if (strnicmp(chan, "2g", strlen("2g")) == 0) {
+		chan_info.band = WLC_BAND_2G;
+		chan_info.chan = (int)simple_strtol(chan+2, NULL, 10);
+	}
+	else if (strnicmp(chan, "5g", strlen("5g")) == 0) {
+		chan_info.band = WLC_BAND_5G;
+		chan_info.chan = (int)simple_strtol(chan+2, NULL, 10);
 	}
 #ifdef WL_6G_BAND
-	else if (strnicmp(band, "band=6g", strlen("band=6g")) == 0) {
+	else if (strnicmp(chan, "6g", strlen("6g")) == 0) {
 		chan_info.band = WLC_BAND_6G;
+		chan_info.chan = (int)simple_strtol(chan+2, NULL, 10);
 	}
 #endif /* WL_6G_BAND */
-	else if (strnicmp(band, "band=5g", strlen("band=5g")) == 0) {
-		chan_info.band = WLC_BAND_5G;
+	else if (strlen(chan)) {
+		chan_info.chan = (int)simple_strtol(chan, NULL, 10);
+		if (chan_info.chan <= CH_MAX_2G_CHANNEL)
+			chan_info.band = WLC_BAND_2G;
+		else
+			chan_info.band = WLC_BAND_5G;
 	}
-	else if (strnicmp(band, "band=2g", strlen("band=2g")) == 0) {
-		chan_info.band = WLC_BAND_2G;
-	}
-	else if (channel <= CH_MAX_2G_CHANNEL)
-		chan_info.band = WLC_BAND_2G;
-	else
-		chan_info.band = WLC_BAND_5G;
 
-	if (channel > 0) {
-		chan_info.chan = channel;
-		ret = wl_ext_set_chanspec(dev, &chan_info, &fw_chspec);
+	if (chan_info.chan > 0) {
+		ret = wl_ext_set_chanspec(dev, &chan_info, &chanspec);
 	} else {
-		if (!(ret = wl_ext_ioctl(dev, WLC_GET_CHANNEL, &ci,
-				sizeof(channel_info_t), FALSE))) {
-			AEXT_TRACE(dev->name, "hw_channel %d\n", ci.hw_channel);
-			AEXT_TRACE(dev->name, "target_channel %d\n", ci.target_channel);
-			AEXT_TRACE(dev->name, "scan_channel %d\n", ci.scan_channel);
-			bytes_written = snprintf(command, sizeof(channel_info_t)+2,
-				"channel %d", ci.hw_channel);
-			AEXT_TRACE(dev->name, "command result is %s\n", command);
+		ret = wl_ext_iovar_getint(dev, "chanspec", (s32 *)&fw_chanspec);
+		if (ret == BCME_OK) {
+			chanspec = fw_chanspec;
+			chanspec = wl_ext_chspec_driver_to_host(dhd, chanspec);
+			chan_info.band = CHSPEC2WLC_BAND(chanspec);
+			chan_info.chan = wf_chspec_ctlchan(chanspec);
+			if (chan_info.band == WLC_BAND_6G) {
+				bytes_written = snprintf(command, total_len,
+					"channel 6g%d", chan_info.chan);
+			} else {
+				bytes_written = snprintf(command, total_len,
+					"channel %d", chan_info.chan);
+			}
 			ret = bytes_written;
 		}
 	}
@@ -735,28 +746,47 @@
 {
 	int ret, i;
 	int bytes_written = -1;
-	u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];
-	wl_uint32_list_t *list;
+	wl_uint32_list_t *list = NULL;
+	chanspec_t chspec;
+	u32 channel;
 
 	AEXT_TRACE(dev->name, "cmd %s", command);
 
-	memset(valid_chan_list, 0, sizeof(valid_chan_list));
-	list = (wl_uint32_list_t *)(void *) valid_chan_list;
-	list->count = htod32(WL_NUMCHANNELS);
-	ret = wl_ext_ioctl(dev, WLC_GET_VALID_CHANNELS, valid_chan_list,
-		sizeof(valid_chan_list), 0);
-	if (ret<0) {
+	list = kzalloc(sizeof(u32)*(MAX_CTRL_CHANSPECS + 1), GFP_KERNEL);
+	if (list == NULL) {
+		AEXT_ERROR(dev->name, "kzalloc failed\n");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	ret = wl_construct_ctl_chanspec_list(dev, list);
+	if (ret < 0) {
 		AEXT_ERROR(dev->name, "get channels failed with %d\n", ret);
+		goto exit;
 	} else {
-		bytes_written = snprintf(command, total_len, "channels");
-		for (i = 0; i < dtoh32(list->count); i++) {
-			bytes_written += snprintf(command+bytes_written, total_len, " %d",
-				dtoh32(list->element[i]));
+		bytes_written = 0;
+		for (i = 0; i < list->count; i++) {
+			chspec = list->element[i];
+			channel = wf_chspec_ctlchan(chspec);
+#ifdef WL_6G_BAND
+			if (CHSPEC_IS6G(chspec) && (channel >= CH_MIN_6G_CHANNEL) &&
+					(channel <= CH_MAX_6G_CHANNEL)) {
+				bytes_written += snprintf(command+bytes_written, total_len, "6g%d ",
+					channel);
+			} else
+#endif
+			{
+				bytes_written += snprintf(command+bytes_written, total_len, "%d ",
+					channel);
+			}
 		}
 		AEXT_TRACE(dev->name, "command result is %s\n", command);
 		ret = bytes_written;
 	}
 
+exit:
+	if (list)
+		kfree(list);
 	return ret;
 }
 
@@ -3011,11 +3041,11 @@
 	s32 err = BCME_OK;
 
 	param.band = band;
-	err = wl_ext_iovar_getbuf(net, "bw_cap", &param, sizeof(param), buf,
+	err = wldev_iovar_getbuf(net, "bw_cap", &param, sizeof(param), buf,
 		sizeof(buf), NULL);
 	if (err) {
 		if (err != BCME_UNSUPPORTED) {
-			AEXT_ERROR(net->name, "bw_cap failed, %d\n", err);
+			AEXT_TRACE(net->name, "bw_cap failed, %d\n", err);
 			return err;
 		} else {
 			err = wl_ext_iovar_getint(net, "mimo_bw_cap", &bw_cap);
@@ -3066,8 +3096,7 @@
 	s32 distance_6g;
 #endif /* WL_6G_BAND */
 	s32 cen_ch, distance, distance_2g, distance_5g, chanspec, min_ap=999;
-	u8 valid_chan_list[sizeof(u32)*(MAX_CTRL_CHANSPECS + 1)];
-	wl_uint32_list_t *list;
+	wl_uint32_list_t *list = NULL;
 	int ret;
 	chanspec_t chspec;
 	u32 channel;
@@ -3082,13 +3111,17 @@
 	memset(six_g_band8, -1, sizeof(six_g_band8));
 #endif /* WL_6G_BAND */
 
-	memset(valid_chan_list, 0, sizeof(valid_chan_list));
-	list = (wl_uint32_list_t *)(void *) valid_chan_list;
+	list = kzalloc(sizeof(u32)*(MAX_CTRL_CHANSPECS + 1), GFP_KERNEL);
+	if (list == NULL) {
+		AEXT_ERROR(net->name, "kzalloc failed\n");
+		ret = -ENOMEM;
+		goto exit;
+	}
 
 	ret = wl_construct_ctl_chanspec_list(net, list);
 	if (ret < 0) {
 		AEXT_ERROR(net->name, "get channels failed with %d\n", ret);
-		return 0;
+		goto exit;
 	} else {
 		for (i = 0; i < list->count; i++) {
 			chspec = list->element[i];
@@ -3313,7 +3346,9 @@
 	}
 
 exit:
-	return 0;
+	if (list)
+		kfree(list);
+	return ret;
 }
 #endif /* WL_CFG80211 || WL_ESCAN */
 
@@ -3414,7 +3449,7 @@
 		kfree(reqbuf);
 	}
 
-	return channel;
+	return chosen;
 }
 #endif /* WL_CFG80211 */
 
@@ -3424,29 +3459,36 @@
 {
 	int ret = -1, i, cnt = 0;
 	int retry = 0, retry_max, retry_interval = 250, up = 1;
-	wl_scan_info_t scan_info;
+	wl_scan_info_t *scan_info = NULL;
+
+	scan_info = kmalloc(sizeof(wl_scan_info_t), GFP_KERNEL);
+	if (scan_info == NULL) {
+		AEXT_ERROR(dev->name, "kzalloc failed\n");
+		ret = -ENOMEM;
+		goto exit;
+	}
 
 	retry_max = WL_ESCAN_TIMER_INTERVAL_MS/retry_interval;
 	ret = wldev_ioctl_get(dev, WLC_GET_UP, &up, sizeof(s32));
 	if (ret < 0 || up == 0) {
 		ret = wldev_ioctl_set(dev, WLC_UP, &up, sizeof(s32));
 	}
-	memset(&scan_info, 0, sizeof(wl_scan_info_t));
+	memset(scan_info, 0, sizeof(wl_scan_info_t));
 	if (band == WLC_BAND_2G || band == WLC_BAND_AUTO) {
 		for (i=0; i<13; i++) {
-			scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(i+1,
+			scan_info->channels.channel[i+cnt] = wf_create_chspec_from_primary(i+1,
 				WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_2G);
 		}
 		cnt += 13;
 	}
 	if (band == WLC_BAND_5G || band == WLC_BAND_AUTO) {
 		for (i=0; i<4; i++) {
-			scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(36+i*4,
+			scan_info->channels.channel[i+cnt] = wf_create_chspec_from_primary(36+i*4,
 				WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_5G);
 		}
 		cnt += 4;
 		for (i=0; i<4; i++) {
-			scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(149+i*4,
+			scan_info->channels.channel[i+cnt] = wf_create_chspec_from_primary(149+i*4,
 				WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_5G);
 		}
 		cnt += 4;
@@ -3454,7 +3496,7 @@
 #ifdef WL_6G_BAND
 	if (band == WLC_BAND_6G || band == WLC_BAND_AUTO) {
 		for (i=0; i<59; i++) {
-			scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(1+i*4,
+			scan_info->channels.channel[i+cnt] = wf_create_chspec_from_primary(1+i*4,
 				WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_6G);
 		}
 		cnt += 59;
@@ -3462,13 +3504,13 @@
 #endif /* WL_6G_BAND */
 	if (band == WLC_BAND_2G)
 		fast_scan = FALSE;
-	scan_info.channels.count = cnt;
+	scan_info->channels.count = cnt;
 	if (fast_scan)
-		scan_info.scan_time = 40;
-	scan_info.bcast_ssid = TRUE;
+		scan_info->scan_time = 40;
+	scan_info->bcast_ssid = TRUE;
 	retry = retry_max;
 	while (retry--) {
-		ret = wl_escan_set_scan(dev, &scan_info);
+		ret = wl_escan_set_scan(dev, scan_info);
 		if (!ret)
 			break;
 		OSL_SLEEP(retry_interval);
@@ -3478,13 +3520,16 @@
 		ret = -1;
 	}
 
+exit:
+	if (scan_info)
+		kfree(scan_info);
 	return ret;
 }
 
-int
+static int
 wl_ext_drv_apcs(struct net_device *dev, uint32 band)
 {
-	int ret = 0, channel = 0;
+	int ret = 0, chanspec = 0;
 	struct dhd_pub *dhd = dhd_get_pub(dev);
 	struct wl_escan_info *escan = NULL;
 	int retry = 0, retry_max, retry_interval = 250;
@@ -3499,15 +3544,22 @@
 	retry = retry_max;
 	while (retry--) {
 		if (escan->escan_state == ESCAN_STATE_IDLE) {
-			if (band == WLC_BAND_5G)
-				channel = escan->best_5g_ch;
+			if (band == WLC_BAND_5G) {
+				chanspec = wf_create_chspec_from_primary(wf_chspec_primary20_chan(escan->best_5g_ch),
+					WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_5G);
+			}
 #ifdef WL_6G_BAND
-			else if (band == WLC_BAND_6G)
-				channel = escan->best_6g_ch;
+			else if (band == WLC_BAND_6G) {
+				chanspec = wf_create_chspec_from_primary(wf_chspec_primary20_chan(escan->best_6g_ch),
+					WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_6G);
+			}
 #endif /* WL_6G_BAND */
-			else
-				channel = escan->best_2g_ch;
-			WL_MSG(dev->name, "selected channel = %d\n", channel);
+			else {
+				chanspec = wf_create_chspec_from_primary(wf_chspec_primary20_chan(escan->best_2g_ch),
+					WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_2G);
+			}
+			WL_MSG(dev->name, "selected channel = %d(0x%x)\n",
+				wf_chspec_ctlchan(chanspec), chanspec);
 			goto done;
 		}
 		AEXT_INFO(dev->name, "escan_state=%d, %d tried, ret = %d\n",
@@ -3518,46 +3570,51 @@
 done:
 	escan->autochannel = 0;
 
-	return channel;
+	return chanspec;
 }
 #endif /* WL_ESCAN */
 
 int
 wl_ext_autochannel(struct net_device *dev, uint acs, uint32 band)
 {
-	int channel = 0;
-	uint16 chan_2g, chan_5g;
+	int chosen = 0;
+	uint16 chan_2g, chan_5g, channel;
 
-	AEXT_INFO(dev->name, "acs=0x%x, band=%d \n", acs, band);
+	AEXT_INFO(dev->name, "acs=0x%x, band=%s\n", acs, WLCBAND2STR(band));
 
 #ifdef WL_CFG80211
 	if (acs & ACS_FW_BIT) {
 		int ret = 0;
 		ret = wldev_ioctl_get(dev, WLC_GET_CHANNEL_SEL, &channel, sizeof(channel));
-		channel = 0;
+		chosen = 0;
 		if (ret != BCME_UNSUPPORTED)
-			channel = wl_ext_fw_apcs(dev, band);
-		if (channel)
-			return channel;
+			chosen = wl_ext_fw_apcs(dev, band);
+		if (chosen)
+			return chosen;
 	}
 #endif
 
 #ifdef WL_ESCAN
 	if (acs & ACS_DRV_BIT)
-		channel = wl_ext_drv_apcs(dev, band);
+		chosen = wl_ext_drv_apcs(dev, band);
 #endif /* WL_ESCAN */
 
-	if (channel == 0) {
+	if (chosen == 0) {
 		wl_ext_get_default_chan(dev, &chan_2g, &chan_5g, TRUE);
 		if (band == WLC_BAND_5G) {
+			chosen = wf_create_chspec_from_primary(wf_chspec_primary20_chan(chan_5g),
+				WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_5G);
 			channel = chan_5g;
 		} else {
+			chosen = wf_create_chspec_from_primary(wf_chspec_primary20_chan(chan_2g),
+				WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_2G);
 			channel = chan_2g;
 		}
-		AEXT_ERROR(dev->name, "ACS failed. Fall back to default channel (%d) \n", channel);
+		AEXT_ERROR(dev->name, "ACS failed. Fall back to default channel (%s-%d) \n",
+			CHSPEC2BANDSTR(chosen), channel);
 	}
 
-	return channel;
+	return chosen;
 }
 
 #if defined(RSSIAVG)

--
Gitblit v1.6.2