developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 1 | From 5070c33b7eb059d1c78ff0c02bb56b16e01431f8 Mon Sep 17 00:00:00 2001 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2 | From: Michael-CY Lee <michael-cy.lee@mediatek.com> |
| 3 | Date: Mon, 11 Sep 2023 10:16:35 +0800 |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 4 | Subject: [PATCH 051/126] mtk: hostapd: synchronize bandwidth in AP/STA support |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 5 | |
| 6 | Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com> |
| 7 | --- |
| 8 | src/ap/ucode.c | 41 +++++++++++++++++++-- |
| 9 | src/utils/ucode.c | 12 +++++-- |
| 10 | wpa_supplicant/ucode.c | 82 ++++++++++++++++++++++++++++++++++-------- |
| 11 | 3 files changed, 117 insertions(+), 18 deletions(-) |
| 12 | |
| 13 | diff --git a/src/ap/ucode.c b/src/ap/ucode.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 14 | index 3468615fd..8c3212f6f 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 15 | --- a/src/ap/ucode.c |
| 16 | +++ b/src/ap/ucode.c |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 17 | @@ -493,6 +493,9 @@ uc_hostapd_iface_stop(uc_vm_t *vm, size_t nargs) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 18 | struct hostapd_iface *iface = uc_fn_thisval("hostapd.iface"); |
| 19 | int i; |
| 20 | |
| 21 | + wpa_printf(MSG_INFO, "ucode: mtk: stop iface for %s in state %s\n", |
| 22 | + iface->phy, hostapd_state_text(iface->state)); |
| 23 | + |
| 24 | if (!iface) |
| 25 | return NULL; |
| 26 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 27 | @@ -519,6 +522,9 @@ uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 28 | uint64_t intval; |
| 29 | int i; |
| 30 | |
| 31 | + wpa_printf(MSG_INFO, "ucode: mtk: start iface for %s in state %s\n", |
| 32 | + iface->phy, hostapd_state_text(iface->state)); |
| 33 | + |
| 34 | if (!iface) |
| 35 | return NULL; |
| 36 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 37 | @@ -541,7 +547,13 @@ uc_hostapd_iface_start(uc_vm_t *vm, size_t nargs) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 38 | UPDATE_VAL(op_class, "op_class"); |
| 39 | UPDATE_VAL(hw_mode, "hw_mode"); |
| 40 | UPDATE_VAL(channel, "channel"); |
| 41 | - UPDATE_VAL(secondary_channel, "sec_channel"); |
| 42 | + |
| 43 | + intval = ucv_int64_get(ucv_object_get(info, "sec_channel", NULL)); |
| 44 | + if (!errno) { |
| 45 | + conf->secondary_channel = intval; |
| 46 | + changed = true; |
| 47 | + } |
| 48 | + |
| 49 | if (!changed && |
| 50 | (iface->bss[0]->beacon_set_done || |
| 51 | iface->state == HAPD_IFACE_DFS)) |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 52 | @@ -587,6 +599,18 @@ out: |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 53 | return ucv_boolean_new(true); |
| 54 | } |
| 55 | |
| 56 | + wpa_printf(MSG_INFO, "ucode: mtk: updated channel information:\n"); |
| 57 | + wpa_printf(MSG_INFO, " * channel: %d\n", conf->channel); |
| 58 | + wpa_printf(MSG_INFO, " * op_class: %d\n", conf->op_class); |
| 59 | + wpa_printf(MSG_INFO, " * secondary channel: %d\n", |
| 60 | + conf->secondary_channel); |
| 61 | + wpa_printf(MSG_INFO, " * seg0: %d\n", |
| 62 | + hostapd_get_oper_centr_freq_seg0_idx(conf)); |
| 63 | + wpa_printf(MSG_INFO, " * seg1: %d\n", |
| 64 | + hostapd_get_oper_centr_freq_seg0_idx(conf)); |
| 65 | + wpa_printf(MSG_INFO, " * oper_chwidth: %d\n", |
| 66 | + hostapd_get_oper_chwidth(conf)); |
| 67 | + |
| 68 | for (i = 0; i < iface->num_bss; i++) { |
| 69 | struct hostapd_data *hapd = iface->bss[i]; |
| 70 | int ret; |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 71 | @@ -621,6 +645,7 @@ uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 72 | uint64_t intval; |
| 73 | int i, ret = 0; |
| 74 | |
| 75 | + wpa_printf(MSG_INFO, "ucode: mtk: channel switch for %s\n", iface->phy); |
| 76 | if (!iface || ucv_type(info) != UC_OBJECT) |
| 77 | return NULL; |
| 78 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 79 | @@ -640,7 +665,8 @@ uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 80 | if (errno) |
| 81 | intval = hostapd_get_oper_chwidth(conf); |
| 82 | if (intval) |
| 83 | - csa.freq_params.bandwidth = 40 << intval; |
| 84 | + csa.freq_params.bandwidth = 40 << |
| 85 | + (intval == CONF_OPER_CHWIDTH_320MHZ ? 3 : intval); |
| 86 | else |
| 87 | csa.freq_params.bandwidth = csa.freq_params.sec_channel_offset ? 40 : 20; |
| 88 | |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 89 | @@ -651,6 +677,17 @@ uc_hostapd_iface_switch_channel(uc_vm_t *vm, size_t nargs) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 90 | if ((intval = ucv_int64_get(ucv_object_get(info, "center_freq2", NULL))) && !errno) |
| 91 | csa.freq_params.center_freq2 = intval; |
| 92 | |
| 93 | + wpa_printf(MSG_INFO, "ucode: mtk: switch channel information:\n"); |
| 94 | + wpa_printf(MSG_INFO, " * freq is %d\n", csa.freq_params.freq); |
| 95 | + wpa_printf(MSG_INFO, " * bandwidth is %d\n", |
| 96 | + csa.freq_params.bandwidth); |
| 97 | + wpa_printf(MSG_INFO, " * sec_chan_offset is %d\n", |
| 98 | + csa.freq_params.sec_channel_offset); |
| 99 | + wpa_printf(MSG_INFO, " * center_freq1 is %d\n", |
| 100 | + csa.freq_params.center_freq1); |
| 101 | + wpa_printf(MSG_INFO, " * center_freq2 is %d\n", |
| 102 | + csa.freq_params.center_freq2); |
| 103 | + |
| 104 | for (i = 0; i < iface->num_bss; i++) |
| 105 | ret = hostapd_switch_channel(iface->bss[i], &csa); |
| 106 | |
| 107 | diff --git a/src/utils/ucode.c b/src/utils/ucode.c |
| 108 | index 4b6ed3a94..6f82382f3 100644 |
| 109 | --- a/src/utils/ucode.c |
| 110 | +++ b/src/utils/ucode.c |
| 111 | @@ -110,6 +110,7 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs) |
| 112 | uc_value_t *freq = uc_fn_arg(0); |
| 113 | uc_value_t *sec = uc_fn_arg(1); |
| 114 | int width = ucv_uint64_get(uc_fn_arg(2)); |
| 115 | + int bw320_offset = 1; |
| 116 | int freq_val, center_idx, center_ofs; |
| 117 | enum oper_chan_width chanwidth; |
| 118 | enum hostapd_hw_mode hw_mode; |
| 119 | @@ -147,6 +148,9 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs) |
| 120 | case 9: |
| 121 | width = 3; |
| 122 | chanwidth = CONF_OPER_CHWIDTH_320MHZ; |
| 123 | + |
| 124 | + /* bw320_offset is 1 for 320 MHz-1, and 2 for 320 MHz-2 */ |
| 125 | + bw320_offset = ucv_uint64_get(uc_fn_arg(3)); |
| 126 | break; |
| 127 | default: |
| 128 | return NULL; |
| 129 | @@ -178,12 +182,16 @@ uc_value_t *uc_wpa_freq_info(uc_vm_t *vm, size_t nargs) |
| 130 | ucv_object_add(ret, "hw_mode_str", ucv_get(ucv_string_new(modestr))); |
| 131 | ucv_object_add(ret, "sec_channel", ucv_int64_new(sec_channel)); |
| 132 | ucv_object_add(ret, "frequency", ucv_int64_new(freq_val)); |
| 133 | + ucv_object_add(ret, "oper_chwidth", ucv_int64_new(chanwidth)); |
| 134 | |
| 135 | - if (!sec_channel) |
| 136 | + if (chanwidth == CONF_OPER_CHWIDTH_USE_HT && !sec_channel) { |
| 137 | + ucv_object_add(ret, "center_seg0_idx", ucv_int64_new(channel)); |
| 138 | + ucv_object_add(ret, "center_freq1", ucv_int64_new(freq_val)); |
| 139 | return ret; |
| 140 | + } |
| 141 | |
| 142 | if (freq_val >= 5900) |
| 143 | - center_ofs = 0; |
| 144 | + center_ofs = 32 * (1 - bw320_offset); |
| 145 | else if (freq_val >= 5745) |
| 146 | center_ofs = 20; |
| 147 | else |
| 148 | diff --git a/wpa_supplicant/ucode.c b/wpa_supplicant/ucode.c |
| 149 | index 397f85bde..542ca25c9 100644 |
| 150 | --- a/wpa_supplicant/ucode.c |
| 151 | +++ b/wpa_supplicant/ucode.c |
| 152 | @@ -7,6 +7,8 @@ |
| 153 | #include "wps_supplicant.h" |
| 154 | #include "bss.h" |
| 155 | #include "ucode.h" |
| 156 | +#include "driver_i.h" |
| 157 | +#include "common/ieee802_11_common.h" |
| 158 | |
| 159 | static struct wpa_global *wpa_global; |
| 160 | static uc_resource_type_t *global_type, *iface_type; |
| 161 | @@ -96,6 +98,8 @@ void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_d |
| 162 | { |
| 163 | const char *state; |
| 164 | uc_value_t *val; |
| 165 | + enum oper_chan_width ch_width; |
| 166 | + int center_freq1, bw320_offset = 1; |
| 167 | |
| 168 | if (event != EVENT_CH_SWITCH_STARTED) |
| 169 | return; |
| 170 | @@ -114,11 +118,42 @@ void wpas_ucode_event(struct wpa_supplicant *wpa_s, int event, union wpa_event_d |
| 171 | uc_value_push(ucv_get(val)); |
| 172 | |
| 173 | if (event == EVENT_CH_SWITCH_STARTED) { |
| 174 | + center_freq1 = data->ch_switch.cf1; |
| 175 | + |
| 176 | + switch (data->ch_switch.ch_width) { |
| 177 | + case CHAN_WIDTH_80: |
| 178 | + ch_width = CONF_OPER_CHWIDTH_80MHZ; |
| 179 | + break; |
| 180 | + case CHAN_WIDTH_80P80: |
| 181 | + ch_width = CONF_OPER_CHWIDTH_80P80MHZ; |
| 182 | + break; |
| 183 | + case CHAN_WIDTH_160: |
| 184 | + ch_width = CONF_OPER_CHWIDTH_160MHZ; |
| 185 | + break; |
| 186 | + case CHAN_WIDTH_320: |
| 187 | + ch_width = CONF_OPER_CHWIDTH_320MHZ; |
| 188 | + break; |
| 189 | + case CHAN_WIDTH_20_NOHT: |
| 190 | + case CHAN_WIDTH_20: |
| 191 | + case CHAN_WIDTH_40: |
| 192 | + default: |
| 193 | + ch_width = CONF_OPER_CHWIDTH_USE_HT; |
| 194 | + break; |
| 195 | + } |
| 196 | + |
| 197 | + /* Check bandwidth 320 MHz-2 */ |
| 198 | + if (ch_width == CONF_OPER_CHWIDTH_320MHZ && |
| 199 | + (center_freq1 == 6265) || center_freq1 == 6585 || |
| 200 | + center_freq1 == 6905) |
| 201 | + bw320_offset = 2; |
| 202 | + |
| 203 | ucv_object_add(val, "csa_count", ucv_int64_new(data->ch_switch.count)); |
| 204 | ucv_object_add(val, "frequency", ucv_int64_new(data->ch_switch.freq)); |
| 205 | ucv_object_add(val, "sec_chan_offset", ucv_int64_new(data->ch_switch.ch_offset)); |
| 206 | - ucv_object_add(val, "center_freq1", ucv_int64_new(data->ch_switch.cf1)); |
| 207 | + ucv_object_add(val, "center_freq1", ucv_int64_new(center_freq1)); |
| 208 | ucv_object_add(val, "center_freq2", ucv_int64_new(data->ch_switch.cf2)); |
| 209 | + ucv_object_add(val, "ch_width", ucv_int64_new(ch_width)); |
| 210 | + ucv_object_add(val, "bw320_offset", ucv_int64_new(bw320_offset)); |
| 211 | } |
| 212 | |
| 213 | ucv_put(wpa_ucode_call(4)); |
| 214 | @@ -212,6 +247,11 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs) |
| 215 | struct wpa_supplicant *wpa_s = uc_fn_thisval("wpas.iface"); |
| 216 | struct wpa_bss *bss; |
| 217 | uc_value_t *ret, *val; |
| 218 | + struct wpa_channel_info ci; |
| 219 | + u8 op_class, channel; |
| 220 | + enum oper_chan_width ch_width; |
| 221 | + int center_freq1, bw320_offset = 1, is_24ghz; |
| 222 | + enum hostapd_hw_mode hw_mode; |
| 223 | |
| 224 | if (!wpa_s) |
| 225 | return NULL; |
| 226 | @@ -224,23 +264,37 @@ uc_wpas_iface_status(uc_vm_t *vm, size_t nargs) |
| 227 | bss = wpa_s->current_bss; |
| 228 | if (bss) { |
| 229 | int sec_chan = 0; |
| 230 | - const u8 *ie; |
| 231 | - |
| 232 | - ie = wpa_bss_get_ie(bss, WLAN_EID_HT_OPERATION); |
| 233 | - if (ie && ie[1] >= 2) { |
| 234 | - const struct ieee80211_ht_operation *ht_oper; |
| 235 | - int sec; |
| 236 | - |
| 237 | - ht_oper = (const void *) (ie + 2); |
| 238 | - sec = ht_oper->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK; |
| 239 | - if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE) |
| 240 | - sec_chan = 1; |
| 241 | - else if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW) |
| 242 | - sec_chan = -1; |
| 243 | + |
| 244 | + hw_mode = ieee80211_freq_to_chan(bss->freq, &channel); |
| 245 | + is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G || |
| 246 | + hw_mode == HOSTAPD_MODE_IEEE80211B; |
| 247 | + |
| 248 | + wpa_drv_channel_info(wpa_s, &ci); |
| 249 | + center_freq1 = ci.center_frq1; |
| 250 | + |
| 251 | + if (bss->freq != center_freq1) { |
| 252 | + if (is_24ghz) |
| 253 | + sec_chan = (bss->freq < center_freq1) ? 1 : -1; |
| 254 | + else |
| 255 | + sec_chan = (bss->freq / 20) & 1 ? 1 : -1; |
| 256 | + } |
| 257 | + |
| 258 | + if (ieee80211_chaninfo_to_channel(ci.frequency, ci.chanwidth, |
| 259 | + sec_chan, &op_class, &channel)) |
| 260 | + return NULL; |
| 261 | + |
| 262 | + ch_width = op_class_to_ch_width(op_class); |
| 263 | + if (ch_width == CONF_OPER_CHWIDTH_320MHZ && |
| 264 | + (center_freq1 == 6265) || center_freq1 == 6585 || |
| 265 | + center_freq1 == 6905) { |
| 266 | + /* Bandwidth 320 MHz-2 */ |
| 267 | + bw320_offset = 2; |
| 268 | } |
| 269 | |
| 270 | ucv_object_add(ret, "sec_chan_offset", ucv_int64_new(sec_chan)); |
| 271 | ucv_object_add(ret, "frequency", ucv_int64_new(bss->freq)); |
| 272 | + ucv_object_add(ret, "ch_width", ucv_int64_new(ch_width)); |
| 273 | + ucv_object_add(ret, "bw320_offset", ucv_int64_new(bw320_offset)); |
| 274 | } |
| 275 | |
| 276 | #ifdef CONFIG_MESH |
| 277 | -- |
developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 278 | 2.18.0 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 279 | |