hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_android_ext.c
....@@ -617,11 +617,11 @@
617617 }
618618
619619 param.band = chan_info->band;
620
- err = wl_ext_iovar_getbuf(dev, "bw_cap", &param, sizeof(param),
620
+ err = wldev_iovar_getbuf(dev, "bw_cap", &param, sizeof(param),
621621 iovar_buf, WLC_IOCTL_SMLEN, NULL);
622622 if (err) {
623623 if (err != BCME_UNSUPPORTED) {
624
- AEXT_ERROR(dev->name, "bw_cap failed, %d\n", err);
624
+ AEXT_TRACE(dev->name, "bw_cap failed, %d\n", err);
625625 return err;
626626 } else {
627627 err = wl_ext_iovar_getint(dev, "mimo_bw_cap", &bw_cap);
....@@ -681,48 +681,59 @@
681681 static int
682682 wl_ext_channel(struct net_device *dev, char* command, int total_len)
683683 {
684
+ struct dhd_pub *dhd = dhd_get_pub(dev);
684685 struct wl_chan_info chan_info;
685
- int ret;
686
- char band[16]="";
687
- int channel = 0;
688
- channel_info_t ci;
689
- int bytes_written = 0;
690
- chanspec_t fw_chspec;
686
+ char chan[16]="";
687
+ int ret, bytes_written = 0;
688
+ chanspec_t chanspec;
689
+ u32 fw_chanspec = 0;
690
+
691
+ /* get: dhd_priv channel
692
+ * set: dhd_priv channel [6|36|2g6|5g36|6g5]
693
+ */
691694
692695 AEXT_TRACE(dev->name, "cmd %s", command);
693696
694
- sscanf(command, "%*s %d %s", &channel, band);
695
- if (strnicmp(band, "band=auto", strlen("band=auto")) == 0) {
696
- chan_info.band = WLC_BAND_AUTO;
697
+ sscanf(command, "%*s %s", chan);
698
+ memset(&chan_info, 0, sizeof(struct wl_chan_info));
699
+ if (strnicmp(chan, "2g", strlen("2g")) == 0) {
700
+ chan_info.band = WLC_BAND_2G;
701
+ chan_info.chan = (int)simple_strtol(chan+2, NULL, 10);
702
+ }
703
+ else if (strnicmp(chan, "5g", strlen("5g")) == 0) {
704
+ chan_info.band = WLC_BAND_5G;
705
+ chan_info.chan = (int)simple_strtol(chan+2, NULL, 10);
697706 }
698707 #ifdef WL_6G_BAND
699
- else if (strnicmp(band, "band=6g", strlen("band=6g")) == 0) {
708
+ else if (strnicmp(chan, "6g", strlen("6g")) == 0) {
700709 chan_info.band = WLC_BAND_6G;
710
+ chan_info.chan = (int)simple_strtol(chan+2, NULL, 10);
701711 }
702712 #endif /* WL_6G_BAND */
703
- else if (strnicmp(band, "band=5g", strlen("band=5g")) == 0) {
704
- chan_info.band = WLC_BAND_5G;
713
+ else if (strlen(chan)) {
714
+ chan_info.chan = (int)simple_strtol(chan, NULL, 10);
715
+ if (chan_info.chan <= CH_MAX_2G_CHANNEL)
716
+ chan_info.band = WLC_BAND_2G;
717
+ else
718
+ chan_info.band = WLC_BAND_5G;
705719 }
706
- else if (strnicmp(band, "band=2g", strlen("band=2g")) == 0) {
707
- chan_info.band = WLC_BAND_2G;
708
- }
709
- else if (channel <= CH_MAX_2G_CHANNEL)
710
- chan_info.band = WLC_BAND_2G;
711
- else
712
- chan_info.band = WLC_BAND_5G;
713720
714
- if (channel > 0) {
715
- chan_info.chan = channel;
716
- ret = wl_ext_set_chanspec(dev, &chan_info, &fw_chspec);
721
+ if (chan_info.chan > 0) {
722
+ ret = wl_ext_set_chanspec(dev, &chan_info, &chanspec);
717723 } else {
718
- if (!(ret = wl_ext_ioctl(dev, WLC_GET_CHANNEL, &ci,
719
- sizeof(channel_info_t), FALSE))) {
720
- AEXT_TRACE(dev->name, "hw_channel %d\n", ci.hw_channel);
721
- AEXT_TRACE(dev->name, "target_channel %d\n", ci.target_channel);
722
- AEXT_TRACE(dev->name, "scan_channel %d\n", ci.scan_channel);
723
- bytes_written = snprintf(command, sizeof(channel_info_t)+2,
724
- "channel %d", ci.hw_channel);
725
- AEXT_TRACE(dev->name, "command result is %s\n", command);
724
+ ret = wl_ext_iovar_getint(dev, "chanspec", (s32 *)&fw_chanspec);
725
+ if (ret == BCME_OK) {
726
+ chanspec = fw_chanspec;
727
+ chanspec = wl_ext_chspec_driver_to_host(dhd, chanspec);
728
+ chan_info.band = CHSPEC2WLC_BAND(chanspec);
729
+ chan_info.chan = wf_chspec_ctlchan(chanspec);
730
+ if (chan_info.band == WLC_BAND_6G) {
731
+ bytes_written = snprintf(command, total_len,
732
+ "channel 6g%d", chan_info.chan);
733
+ } else {
734
+ bytes_written = snprintf(command, total_len,
735
+ "channel %d", chan_info.chan);
736
+ }
726737 ret = bytes_written;
727738 }
728739 }
....@@ -735,28 +746,47 @@
735746 {
736747 int ret, i;
737748 int bytes_written = -1;
738
- u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)];
739
- wl_uint32_list_t *list;
749
+ wl_uint32_list_t *list = NULL;
750
+ chanspec_t chspec;
751
+ u32 channel;
740752
741753 AEXT_TRACE(dev->name, "cmd %s", command);
742754
743
- memset(valid_chan_list, 0, sizeof(valid_chan_list));
744
- list = (wl_uint32_list_t *)(void *) valid_chan_list;
745
- list->count = htod32(WL_NUMCHANNELS);
746
- ret = wl_ext_ioctl(dev, WLC_GET_VALID_CHANNELS, valid_chan_list,
747
- sizeof(valid_chan_list), 0);
748
- if (ret<0) {
755
+ list = kzalloc(sizeof(u32)*(MAX_CTRL_CHANSPECS + 1), GFP_KERNEL);
756
+ if (list == NULL) {
757
+ AEXT_ERROR(dev->name, "kzalloc failed\n");
758
+ ret = -ENOMEM;
759
+ goto exit;
760
+ }
761
+
762
+ ret = wl_construct_ctl_chanspec_list(dev, list);
763
+ if (ret < 0) {
749764 AEXT_ERROR(dev->name, "get channels failed with %d\n", ret);
765
+ goto exit;
750766 } else {
751
- bytes_written = snprintf(command, total_len, "channels");
752
- for (i = 0; i < dtoh32(list->count); i++) {
753
- bytes_written += snprintf(command+bytes_written, total_len, " %d",
754
- dtoh32(list->element[i]));
767
+ bytes_written = 0;
768
+ for (i = 0; i < list->count; i++) {
769
+ chspec = list->element[i];
770
+ channel = wf_chspec_ctlchan(chspec);
771
+#ifdef WL_6G_BAND
772
+ if (CHSPEC_IS6G(chspec) && (channel >= CH_MIN_6G_CHANNEL) &&
773
+ (channel <= CH_MAX_6G_CHANNEL)) {
774
+ bytes_written += snprintf(command+bytes_written, total_len, "6g%d ",
775
+ channel);
776
+ } else
777
+#endif
778
+ {
779
+ bytes_written += snprintf(command+bytes_written, total_len, "%d ",
780
+ channel);
781
+ }
755782 }
756783 AEXT_TRACE(dev->name, "command result is %s\n", command);
757784 ret = bytes_written;
758785 }
759786
787
+exit:
788
+ if (list)
789
+ kfree(list);
760790 return ret;
761791 }
762792
....@@ -3011,11 +3041,11 @@
30113041 s32 err = BCME_OK;
30123042
30133043 param.band = band;
3014
- err = wl_ext_iovar_getbuf(net, "bw_cap", &param, sizeof(param), buf,
3044
+ err = wldev_iovar_getbuf(net, "bw_cap", &param, sizeof(param), buf,
30153045 sizeof(buf), NULL);
30163046 if (err) {
30173047 if (err != BCME_UNSUPPORTED) {
3018
- AEXT_ERROR(net->name, "bw_cap failed, %d\n", err);
3048
+ AEXT_TRACE(net->name, "bw_cap failed, %d\n", err);
30193049 return err;
30203050 } else {
30213051 err = wl_ext_iovar_getint(net, "mimo_bw_cap", &bw_cap);
....@@ -3066,8 +3096,7 @@
30663096 s32 distance_6g;
30673097 #endif /* WL_6G_BAND */
30683098 s32 cen_ch, distance, distance_2g, distance_5g, chanspec, min_ap=999;
3069
- u8 valid_chan_list[sizeof(u32)*(MAX_CTRL_CHANSPECS + 1)];
3070
- wl_uint32_list_t *list;
3099
+ wl_uint32_list_t *list = NULL;
30713100 int ret;
30723101 chanspec_t chspec;
30733102 u32 channel;
....@@ -3082,13 +3111,17 @@
30823111 memset(six_g_band8, -1, sizeof(six_g_band8));
30833112 #endif /* WL_6G_BAND */
30843113
3085
- memset(valid_chan_list, 0, sizeof(valid_chan_list));
3086
- list = (wl_uint32_list_t *)(void *) valid_chan_list;
3114
+ list = kzalloc(sizeof(u32)*(MAX_CTRL_CHANSPECS + 1), GFP_KERNEL);
3115
+ if (list == NULL) {
3116
+ AEXT_ERROR(net->name, "kzalloc failed\n");
3117
+ ret = -ENOMEM;
3118
+ goto exit;
3119
+ }
30873120
30883121 ret = wl_construct_ctl_chanspec_list(net, list);
30893122 if (ret < 0) {
30903123 AEXT_ERROR(net->name, "get channels failed with %d\n", ret);
3091
- return 0;
3124
+ goto exit;
30923125 } else {
30933126 for (i = 0; i < list->count; i++) {
30943127 chspec = list->element[i];
....@@ -3313,7 +3346,9 @@
33133346 }
33143347
33153348 exit:
3316
- return 0;
3349
+ if (list)
3350
+ kfree(list);
3351
+ return ret;
33173352 }
33183353 #endif /* WL_CFG80211 || WL_ESCAN */
33193354
....@@ -3414,7 +3449,7 @@
34143449 kfree(reqbuf);
34153450 }
34163451
3417
- return channel;
3452
+ return chosen;
34183453 }
34193454 #endif /* WL_CFG80211 */
34203455
....@@ -3424,29 +3459,36 @@
34243459 {
34253460 int ret = -1, i, cnt = 0;
34263461 int retry = 0, retry_max, retry_interval = 250, up = 1;
3427
- wl_scan_info_t scan_info;
3462
+ wl_scan_info_t *scan_info = NULL;
3463
+
3464
+ scan_info = kmalloc(sizeof(wl_scan_info_t), GFP_KERNEL);
3465
+ if (scan_info == NULL) {
3466
+ AEXT_ERROR(dev->name, "kzalloc failed\n");
3467
+ ret = -ENOMEM;
3468
+ goto exit;
3469
+ }
34283470
34293471 retry_max = WL_ESCAN_TIMER_INTERVAL_MS/retry_interval;
34303472 ret = wldev_ioctl_get(dev, WLC_GET_UP, &up, sizeof(s32));
34313473 if (ret < 0 || up == 0) {
34323474 ret = wldev_ioctl_set(dev, WLC_UP, &up, sizeof(s32));
34333475 }
3434
- memset(&scan_info, 0, sizeof(wl_scan_info_t));
3476
+ memset(scan_info, 0, sizeof(wl_scan_info_t));
34353477 if (band == WLC_BAND_2G || band == WLC_BAND_AUTO) {
34363478 for (i=0; i<13; i++) {
3437
- scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(i+1,
3479
+ scan_info->channels.channel[i+cnt] = wf_create_chspec_from_primary(i+1,
34383480 WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_2G);
34393481 }
34403482 cnt += 13;
34413483 }
34423484 if (band == WLC_BAND_5G || band == WLC_BAND_AUTO) {
34433485 for (i=0; i<4; i++) {
3444
- scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(36+i*4,
3486
+ scan_info->channels.channel[i+cnt] = wf_create_chspec_from_primary(36+i*4,
34453487 WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_5G);
34463488 }
34473489 cnt += 4;
34483490 for (i=0; i<4; i++) {
3449
- scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(149+i*4,
3491
+ scan_info->channels.channel[i+cnt] = wf_create_chspec_from_primary(149+i*4,
34503492 WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_5G);
34513493 }
34523494 cnt += 4;
....@@ -3454,7 +3496,7 @@
34543496 #ifdef WL_6G_BAND
34553497 if (band == WLC_BAND_6G || band == WLC_BAND_AUTO) {
34563498 for (i=0; i<59; i++) {
3457
- scan_info.channels.channel[i+cnt] = wf_create_chspec_from_primary(1+i*4,
3499
+ scan_info->channels.channel[i+cnt] = wf_create_chspec_from_primary(1+i*4,
34583500 WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_6G);
34593501 }
34603502 cnt += 59;
....@@ -3462,13 +3504,13 @@
34623504 #endif /* WL_6G_BAND */
34633505 if (band == WLC_BAND_2G)
34643506 fast_scan = FALSE;
3465
- scan_info.channels.count = cnt;
3507
+ scan_info->channels.count = cnt;
34663508 if (fast_scan)
3467
- scan_info.scan_time = 40;
3468
- scan_info.bcast_ssid = TRUE;
3509
+ scan_info->scan_time = 40;
3510
+ scan_info->bcast_ssid = TRUE;
34693511 retry = retry_max;
34703512 while (retry--) {
3471
- ret = wl_escan_set_scan(dev, &scan_info);
3513
+ ret = wl_escan_set_scan(dev, scan_info);
34723514 if (!ret)
34733515 break;
34743516 OSL_SLEEP(retry_interval);
....@@ -3478,13 +3520,16 @@
34783520 ret = -1;
34793521 }
34803522
3523
+exit:
3524
+ if (scan_info)
3525
+ kfree(scan_info);
34813526 return ret;
34823527 }
34833528
3484
-int
3529
+static int
34853530 wl_ext_drv_apcs(struct net_device *dev, uint32 band)
34863531 {
3487
- int ret = 0, channel = 0;
3532
+ int ret = 0, chanspec = 0;
34883533 struct dhd_pub *dhd = dhd_get_pub(dev);
34893534 struct wl_escan_info *escan = NULL;
34903535 int retry = 0, retry_max, retry_interval = 250;
....@@ -3499,15 +3544,22 @@
34993544 retry = retry_max;
35003545 while (retry--) {
35013546 if (escan->escan_state == ESCAN_STATE_IDLE) {
3502
- if (band == WLC_BAND_5G)
3503
- channel = escan->best_5g_ch;
3547
+ if (band == WLC_BAND_5G) {
3548
+ chanspec = wf_create_chspec_from_primary(wf_chspec_primary20_chan(escan->best_5g_ch),
3549
+ WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_5G);
3550
+ }
35043551 #ifdef WL_6G_BAND
3505
- else if (band == WLC_BAND_6G)
3506
- channel = escan->best_6g_ch;
3552
+ else if (band == WLC_BAND_6G) {
3553
+ chanspec = wf_create_chspec_from_primary(wf_chspec_primary20_chan(escan->best_6g_ch),
3554
+ WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_6G);
3555
+ }
35073556 #endif /* WL_6G_BAND */
3508
- else
3509
- channel = escan->best_2g_ch;
3510
- WL_MSG(dev->name, "selected channel = %d\n", channel);
3557
+ else {
3558
+ chanspec = wf_create_chspec_from_primary(wf_chspec_primary20_chan(escan->best_2g_ch),
3559
+ WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_2G);
3560
+ }
3561
+ WL_MSG(dev->name, "selected channel = %d(0x%x)\n",
3562
+ wf_chspec_ctlchan(chanspec), chanspec);
35113563 goto done;
35123564 }
35133565 AEXT_INFO(dev->name, "escan_state=%d, %d tried, ret = %d\n",
....@@ -3518,46 +3570,51 @@
35183570 done:
35193571 escan->autochannel = 0;
35203572
3521
- return channel;
3573
+ return chanspec;
35223574 }
35233575 #endif /* WL_ESCAN */
35243576
35253577 int
35263578 wl_ext_autochannel(struct net_device *dev, uint acs, uint32 band)
35273579 {
3528
- int channel = 0;
3529
- uint16 chan_2g, chan_5g;
3580
+ int chosen = 0;
3581
+ uint16 chan_2g, chan_5g, channel;
35303582
3531
- AEXT_INFO(dev->name, "acs=0x%x, band=%d \n", acs, band);
3583
+ AEXT_INFO(dev->name, "acs=0x%x, band=%s\n", acs, WLCBAND2STR(band));
35323584
35333585 #ifdef WL_CFG80211
35343586 if (acs & ACS_FW_BIT) {
35353587 int ret = 0;
35363588 ret = wldev_ioctl_get(dev, WLC_GET_CHANNEL_SEL, &channel, sizeof(channel));
3537
- channel = 0;
3589
+ chosen = 0;
35383590 if (ret != BCME_UNSUPPORTED)
3539
- channel = wl_ext_fw_apcs(dev, band);
3540
- if (channel)
3541
- return channel;
3591
+ chosen = wl_ext_fw_apcs(dev, band);
3592
+ if (chosen)
3593
+ return chosen;
35423594 }
35433595 #endif
35443596
35453597 #ifdef WL_ESCAN
35463598 if (acs & ACS_DRV_BIT)
3547
- channel = wl_ext_drv_apcs(dev, band);
3599
+ chosen = wl_ext_drv_apcs(dev, band);
35483600 #endif /* WL_ESCAN */
35493601
3550
- if (channel == 0) {
3602
+ if (chosen == 0) {
35513603 wl_ext_get_default_chan(dev, &chan_2g, &chan_5g, TRUE);
35523604 if (band == WLC_BAND_5G) {
3605
+ chosen = wf_create_chspec_from_primary(wf_chspec_primary20_chan(chan_5g),
3606
+ WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_5G);
35533607 channel = chan_5g;
35543608 } else {
3609
+ chosen = wf_create_chspec_from_primary(wf_chspec_primary20_chan(chan_2g),
3610
+ WL_CHANSPEC_BW_20, WL_CHANSPEC_BAND_2G);
35553611 channel = chan_2g;
35563612 }
3557
- AEXT_ERROR(dev->name, "ACS failed. Fall back to default channel (%d) \n", channel);
3613
+ AEXT_ERROR(dev->name, "ACS failed. Fall back to default channel (%s-%d) \n",
3614
+ CHSPEC2BANDSTR(chosen), channel);
35583615 }
35593616
3560
- return channel;
3617
+ return chosen;
35613618 }
35623619
35633620 #if defined(RSSIAVG)