developer | 05f3b2b | 2024-08-19 19:17:34 +0800 | [diff] [blame] | 1 | From d45a052e2c7efe295705ad2185f36b38058ede83 Mon Sep 17 00:00:00 2001 |
| 2 | From: Allen Ye <allen.ye@mediatek.com> |
| 3 | Date: Tue, 28 May 2024 17:46:26 +0800 |
| 4 | Subject: [PATCH 112/126] mtk: hostapd: support enable/disable preamble |
| 5 | puncture from mtk vendor command |
| 6 | |
| 7 | Add mtk vendor event to update punct bitmap and trigger channel switch. |
| 8 | Change to pp user mode when use hostapd_cli to channel switch. |
| 9 | Change pp vendor cmd use link_id instead of band_idx. |
| 10 | Remove band_ind in hostapd_cli get/set pp cmd. |
| 11 | |
| 12 | Change pp default enable firmware mode. |
| 13 | |
| 14 | Signed-off-by: Allen Ye <allen.ye@mediatek.com> |
| 15 | --- |
| 16 | hostapd/config_file.c | 1 - |
| 17 | hostapd/ctrl_iface.c | 45 ++++++++-------- |
| 18 | hostapd/hostapd_cli.c | 4 +- |
| 19 | src/ap/ap_config.c | 2 +- |
| 20 | src/ap/ap_drv_ops.c | 10 +++- |
| 21 | src/ap/drv_callbacks.c | 82 ++++++++++++++++++++++++++++++ |
| 22 | src/common/mtk_vendor.h | 8 ++- |
| 23 | src/drivers/driver.h | 11 +++- |
| 24 | src/drivers/driver_nl80211.c | 10 ++-- |
| 25 | src/drivers/driver_nl80211_event.c | 48 +++++++++++++++++ |
| 26 | 10 files changed, 185 insertions(+), 36 deletions(-) |
| 27 | |
| 28 | diff --git a/hostapd/config_file.c b/hostapd/config_file.c |
| 29 | index 38273a4f2..f7bfc357a 100644 |
| 30 | --- a/hostapd/config_file.c |
| 31 | +++ b/hostapd/config_file.c |
| 32 | @@ -5452,7 +5452,6 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| 33 | if (get_u16(pos, line, &conf->punct_bitmap)) |
| 34 | return 1; |
| 35 | conf->punct_bitmap = atoi(pos); |
| 36 | - conf->pp_mode = PP_USR_MODE; |
| 37 | } else if (os_strcmp(buf, "punct_acs_threshold") == 0) { |
| 38 | int val = atoi(pos); |
| 39 | |
| 40 | diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c |
| 41 | index 988bc90de..337261f8f 100644 |
| 42 | --- a/hostapd/ctrl_iface.c |
| 43 | +++ b/hostapd/ctrl_iface.c |
| 44 | @@ -2818,6 +2818,7 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface, |
| 45 | #ifdef NEED_AP_MLME |
| 46 | struct hostapd_hw_modes *mode = iface->current_mode; |
| 47 | struct csa_settings settings, background_settings; |
| 48 | + struct hostapd_data *hapd; |
| 49 | int ret; |
| 50 | int freq, state; |
| 51 | int bandwidth, oper_chwidth; |
| 52 | @@ -2914,6 +2915,17 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface, |
| 53 | break; |
| 54 | } |
| 55 | |
| 56 | +#ifdef CONFIG_IEEE80211BE |
| 57 | + hapd = iface->bss[0]; |
| 58 | + if (hapd->iconf->punct_bitmap != settings.punct_bitmap && |
| 59 | + hapd->iconf->pp_mode != PP_USR_MODE) { |
| 60 | + hapd->iconf->pp_mode = PP_USR_MODE; |
| 61 | + ret = hostapd_drv_pp_mode_set(hapd); |
| 62 | + if (ret) |
| 63 | + return ret; |
| 64 | + } |
| 65 | +#endif /* CONFIG_IEEE80211BE */ |
| 66 | + |
| 67 | for (i = 0; i < iface->num_bss; i++) { |
| 68 | |
| 69 | /* Save CHAN_SWITCH VHT, HE, and EHT config */ |
| 70 | @@ -5172,8 +5184,7 @@ static int |
| 71 | hostapd_ctrl_iface_set_pp(struct hostapd_data *hapd, char *cmd, char *buf, |
| 72 | size_t buflen) |
| 73 | { |
| 74 | - char *band, *config, *value; |
| 75 | - u8 band_idx; |
| 76 | + char *config, *value; |
| 77 | |
| 78 | config = cmd; |
| 79 | |
| 80 | @@ -5182,31 +5193,26 @@ hostapd_ctrl_iface_set_pp(struct hostapd_data *hapd, char *cmd, char *buf, |
| 81 | return -1; |
| 82 | *value++ = '\0'; |
| 83 | |
| 84 | - band = os_strchr(value, ' '); |
| 85 | - if (band == NULL) |
| 86 | - return -1; |
| 87 | - *band++ = '\0'; |
| 88 | - band_idx = strtol(band, NULL, 10); |
| 89 | - |
| 90 | - hapd = hostapd_get_hapd_by_band_idx(hapd, band_idx); |
| 91 | - |
| 92 | - if (!hapd) |
| 93 | - return -1; |
| 94 | - |
| 95 | if (os_strcmp(config, "mode") == 0) { |
| 96 | int val = strtol(value, NULL, 10); |
| 97 | |
| 98 | - if (val < PP_DISABLE || val > PP_FW_MODE) { |
| 99 | + switch(val) { |
| 100 | + case PP_DISABLE: |
| 101 | + case PP_FW_MODE: |
| 102 | + break; |
| 103 | + case PP_USR_MODE: |
| 104 | + default: |
| 105 | wpa_printf(MSG_ERROR, "Invalid value for SET_PP"); |
| 106 | return -1; |
| 107 | } |
| 108 | hapd->iconf->pp_mode = (u8) val; |
| 109 | + hapd->iconf->punct_bitmap = 0; |
| 110 | if (hostapd_drv_pp_mode_set(hapd) != 0) |
| 111 | return -1; |
| 112 | } else { |
| 113 | wpa_printf(MSG_ERROR, |
| 114 | "Unsupported parameter %s for SET_PP" |
| 115 | - "Usage: set_pp mode <value> <band_idx>", config); |
| 116 | + "Usage: set_pp mode <value>", config); |
| 117 | return -1; |
| 118 | } |
| 119 | return os_snprintf(buf, buflen, "OK\n"); |
| 120 | @@ -5216,15 +5222,6 @@ static int |
| 121 | hostapd_ctrl_iface_get_pp(struct hostapd_data *hapd, char *cmd, char *buf, |
| 122 | size_t buflen) |
| 123 | { |
| 124 | - u8 band_idx; |
| 125 | - |
| 126 | - band_idx = strtol(cmd, NULL, 10); |
| 127 | - |
| 128 | - hapd = hostapd_get_hapd_by_band_idx(hapd, band_idx); |
| 129 | - |
| 130 | - if (!hapd) |
| 131 | - return -1; |
| 132 | - |
| 133 | return os_snprintf(buf, buflen, "pp_mode: %d, punct_bitmap: 0x%04x\n", |
| 134 | hapd->iconf->pp_mode, hapd->iconf->punct_bitmap); |
| 135 | } |
| 136 | diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c |
| 137 | index bfa912dff..12ee0a18f 100644 |
| 138 | --- a/hostapd/hostapd_cli.c |
| 139 | +++ b/hostapd/hostapd_cli.c |
| 140 | @@ -1764,13 +1764,13 @@ static int hostapd_cli_cmd_dump_csi(struct wpa_ctrl *ctrl, int argc, |
| 141 | static int hostapd_cli_cmd_set_pp(struct wpa_ctrl *ctrl, int argc, |
| 142 | char *argv[]) |
| 143 | { |
| 144 | - return hostapd_cli_cmd(ctrl, "set_pp", 3, argc, argv); |
| 145 | + return hostapd_cli_cmd(ctrl, "set_pp", 2, argc, argv); |
| 146 | } |
| 147 | |
| 148 | static int hostapd_cli_cmd_get_pp(struct wpa_ctrl *ctrl, int argc, |
| 149 | char *argv[]) |
| 150 | { |
| 151 | - return hostapd_cli_cmd(ctrl, "get_pp", 1, argc, argv); |
| 152 | + return hostapd_cli_cmd(ctrl, "get_pp", 0, argc, argv); |
| 153 | } |
| 154 | |
| 155 | static int hostapd_cli_cmd_wmm(struct wpa_ctrl *ctrl, int argc, |
| 156 | diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c |
| 157 | index 95100b25c..4528df823 100644 |
| 158 | --- a/src/ap/ap_config.c |
| 159 | +++ b/src/ap/ap_config.c |
| 160 | @@ -312,7 +312,7 @@ struct hostapd_config * hostapd_config_defaults(void) |
| 161 | conf->three_wire_enable = THREE_WIRE_MODE_DISABLE; |
| 162 | conf->ibf_enable = IBF_DEFAULT_ENABLE; |
| 163 | conf->amsdu = 1; |
| 164 | - conf->pp_mode = PP_DISABLE; |
| 165 | + conf->pp_mode = PP_FW_MODE; |
| 166 | conf->band_idx = 255; |
| 167 | |
| 168 | hostapd_set_and_check_bw320_offset(conf, 0); |
| 169 | diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c |
| 170 | index 8631bf960..f9ec9a689 100644 |
| 171 | --- a/src/ap/ap_drv_ops.c |
| 172 | +++ b/src/ap/ap_drv_ops.c |
| 173 | @@ -1447,14 +1447,20 @@ int hostapd_drv_background_radar_mode(struct hostapd_data *hapd) |
| 174 | |
| 175 | int hostapd_drv_pp_mode_set(struct hostapd_data *hapd) |
| 176 | { |
| 177 | + s8 link_id = -1; |
| 178 | + |
| 179 | if (!hapd->driver || !hapd->driver->pp_mode_set || |
| 180 | - hapd->iconf->pp_mode >= PP_USR_MODE || |
| 181 | + hapd->iconf->pp_mode > PP_USR_MODE || |
| 182 | hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A) |
| 183 | return 0; |
| 184 | |
| 185 | + if (hapd->conf->mld_ap) |
| 186 | + link_id = hapd->mld_link_id; |
| 187 | + |
| 188 | return hapd->driver->pp_mode_set(hapd->drv_priv, |
| 189 | hapd->iconf->pp_mode, |
| 190 | - hapd->iconf->band_idx); |
| 191 | + link_id, |
| 192 | + hapd->iconf->punct_bitmap); |
| 193 | } |
| 194 | |
| 195 | int hostapd_drv_beacon_ctrl(struct hostapd_data *hapd, u8 beacon_mode) |
| 196 | diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c |
| 197 | index 0e7cfd285..420d156c8 100644 |
| 198 | --- a/src/ap/drv_callbacks.c |
| 199 | +++ b/src/ap/drv_callbacks.c |
| 200 | @@ -43,6 +43,7 @@ |
| 201 | #include "fils_hlp.h" |
| 202 | #include "neighbor_db.h" |
| 203 | #include "nan_usd_ap.h" |
| 204 | +#include "ap/beacon.h" |
| 205 | |
| 206 | |
| 207 | #ifdef CONFIG_FILS |
| 208 | @@ -2456,6 +2457,81 @@ static void hostapd_event_color_change(struct hostapd_data *hapd, bool success) |
| 209 | #endif /* CONFIG_IEEE80211AX */ |
| 210 | |
| 211 | |
| 212 | +static void hostapd_event_pp_bitmap_update(struct hostapd_data *hapd, |
| 213 | + struct ch_switch *ch_switch) |
| 214 | +{ |
| 215 | + struct hostapd_iface *iface = hapd->iface; |
| 216 | + struct hostapd_hw_modes *cmode = iface->current_mode; |
| 217 | + int err, freq; |
| 218 | + struct csa_settings csa_settings; |
| 219 | + unsigned int i; |
| 220 | + |
| 221 | + /* Check if CSA in progress */ |
| 222 | + if (hostapd_csa_in_progress(iface)) |
| 223 | + return; |
| 224 | + |
| 225 | + if (!hw_get_channel_chan(cmode, iface->conf->channel, &freq)) |
| 226 | + return; |
| 227 | + |
| 228 | + if (iface->conf->punct_bitmap == ch_switch->punct_bitmap || |
| 229 | + freq != ch_switch->freq) |
| 230 | + return; |
| 231 | + |
| 232 | + /* Setup CSA request */ |
| 233 | + os_memset(&csa_settings, 0, sizeof(csa_settings)); |
| 234 | + csa_settings.cs_count = 5; |
| 235 | + csa_settings.block_tx = 0; |
| 236 | + csa_settings.punct_bitmap = ch_switch->punct_bitmap; |
| 237 | + csa_settings.link_id = ch_switch->link_id; |
| 238 | + |
| 239 | + err = hostapd_set_freq_params(&csa_settings.freq_params, |
| 240 | + iface->conf->hw_mode, |
| 241 | + freq, |
| 242 | + iface->conf->channel, |
| 243 | + iface->conf->enable_edmg, |
| 244 | + iface->conf->edmg_channel, |
| 245 | + iface->conf->ieee80211n, |
| 246 | + iface->conf->ieee80211ac, |
| 247 | + iface->conf->ieee80211ax, |
| 248 | + iface->conf->ieee80211be, |
| 249 | + iface->conf->secondary_channel, |
| 250 | + hostapd_get_oper_chwidth(iface->conf), |
| 251 | + hostapd_get_oper_centr_freq_seg0_idx(iface->conf), |
| 252 | + hostapd_get_oper_centr_freq_seg1_idx(iface->conf), |
| 253 | + cmode->vht_capab, |
| 254 | + &cmode->he_capab[IEEE80211_MODE_AP], |
| 255 | + &cmode->eht_capab[IEEE80211_MODE_AP], |
| 256 | + ch_switch->punct_bitmap); |
| 257 | + |
| 258 | + if (err) { |
| 259 | + wpa_printf(MSG_ERROR, |
| 260 | + "Failed to calculate CSA freq params"); |
| 261 | + hostapd_disable_iface(iface); |
| 262 | + return; |
| 263 | + } |
| 264 | + |
| 265 | + for (i = 0; i < iface->num_bss; i++) { |
| 266 | + ieee802_11_set_bss_critical_update(iface->bss[i], |
| 267 | + BSS_CRIT_UPDATE_EVENT_CSA); |
| 268 | + |
| 269 | + err = hostapd_switch_channel(iface->bss[i], &csa_settings); |
| 270 | + if (err) |
| 271 | + break; |
| 272 | + |
| 273 | +#ifdef CONFIG_IEEE80211BE |
| 274 | + if (iface->bss[i]->conf->mld_ap) |
| 275 | + hostapd_update_aff_link_beacon(iface->bss[i], |
| 276 | + csa_settings.cs_count); |
| 277 | + |
| 278 | + /* FIXME: |
| 279 | + * CU flag should be cleared when receiving DTIM event from FW |
| 280 | + */ |
| 281 | + iface->bss[i]->eht_mld_bss_critical_update = 0; |
| 282 | +#endif /* CONFIG_IEEE80211BE */ |
| 283 | + } |
| 284 | +} |
| 285 | + |
| 286 | + |
| 287 | void hostapd_wpa_event(void *ctx, enum wpa_event_type event, |
| 288 | union wpa_event_data *data) |
| 289 | { |
| 290 | @@ -2759,6 +2835,12 @@ void hostapd_wpa_event(void *ctx, enum wpa_event_type event, |
| 291 | hostapd_event_dfs_cac_started(hapd, &data->dfs_event); |
| 292 | break; |
| 293 | #endif /* NEED_AP_MLME */ |
| 294 | + case EVENT_PP_BITMAP_UPDATE: |
| 295 | + if (!data) |
| 296 | + break; |
| 297 | + hapd = switch_link_hapd(hapd, data->ch_switch.link_id); |
| 298 | + hostapd_event_pp_bitmap_update(hapd, &data->ch_switch); |
| 299 | + break; |
| 300 | case EVENT_INTERFACE_ENABLED: |
| 301 | wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_ENABLED); |
| 302 | if (hapd->disabled && hapd->started) { |
| 303 | diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h |
| 304 | index 937b968d5..933f0099d 100644 |
| 305 | --- a/src/common/mtk_vendor.h |
| 306 | +++ b/src/common/mtk_vendor.h |
| 307 | @@ -22,6 +22,10 @@ enum mtk_nl80211_vendor_subcmds { |
| 308 | MTK_NL80211_VENDOR_SUBCMD_EML_CTRL = 0xd3, |
| 309 | }; |
| 310 | |
| 311 | +enum mtk_nl80211_vendor_subevents { |
| 312 | + MTK_NL80211_VENDOR_EVENT_PP_BMP_UPDATE = 0x5, |
| 313 | +}; |
| 314 | + |
| 315 | enum mtk_vendor_attr_edcca_ctrl { |
| 316 | MTK_VENDOR_ATTR_EDCCA_THRESHOLD_INVALID = 0, |
| 317 | |
| 318 | @@ -271,7 +275,9 @@ enum mtk_vendor_attr_pp_ctrl { |
| 319 | MTK_VENDOR_ATTR_PP_CTRL_UNSPEC, |
| 320 | |
| 321 | MTK_VENDOR_ATTR_PP_MODE, |
| 322 | - MTK_VENDOR_ATTR_PP_BAND_IDX, |
| 323 | + MTK_VENDOR_ATTR_PP_LINK_ID, |
| 324 | + MTK_VENDOR_ATTR_PP_BITMAP, |
| 325 | + MTK_VENDOR_ATTR_PP_CURR_FREQ, |
| 326 | |
| 327 | /* keep last */ |
| 328 | NUM_MTK_VENDOR_ATTRS_PP_CTRL, |
| 329 | diff --git a/src/drivers/driver.h b/src/drivers/driver.h |
| 330 | index dacf0a98d..5e65d9e0b 100644 |
| 331 | --- a/src/drivers/driver.h |
| 332 | +++ b/src/drivers/driver.h |
| 333 | @@ -5381,9 +5381,10 @@ struct wpa_driver_ops { |
| 334 | * pp_mode_set - Set preamble puncture operation mode |
| 335 | * @priv: Private driver interface data |
| 336 | * @pp_mode: Value is defined in enum pp_mode |
| 337 | - * @band_idx: chip band index |
| 338 | + * @link_id: MLD link id. -1 if this is an non-MLD AP |
| 339 | + * @punct_bitmap: current puncture bitmap |
| 340 | */ |
| 341 | - int (*pp_mode_set)(void *priv, const u8 pp_mode, u8 band_idx); |
| 342 | + int (*pp_mode_set)(void *priv, const u8 pp_mode, s8 link_id, u16 punct_bitmap); |
| 343 | #ifdef CONFIG_IEEE80211BE |
| 344 | int (*get_mld_addr)(void *priv, u8 *addr); |
| 345 | #endif |
| 346 | @@ -6058,6 +6059,12 @@ enum wpa_event_type { |
| 347 | * channel has been updated and operating channel should expand its width. |
| 348 | */ |
| 349 | EVENT_DFS_BACKGROUND_CHAN_EXPAND, |
| 350 | + |
| 351 | + /** |
| 352 | + * EVENT_PP_BITMAP_UPDATE - Notification that the new puncture bitmap |
| 353 | + * has been applied and a channel switch should be triggered. |
| 354 | + */ |
| 355 | + EVENT_PP_BITMAP_UPDATE, |
| 356 | }; |
| 357 | |
| 358 | |
| 359 | diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c |
| 360 | index 80fe2e591..5d97317f7 100644 |
| 361 | --- a/src/drivers/driver_nl80211.c |
| 362 | +++ b/src/drivers/driver_nl80211.c |
| 363 | @@ -160,7 +160,9 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = { |
| 364 | static struct nla_policy |
| 365 | pp_ctrl_policy[NUM_MTK_VENDOR_ATTRS_PP_CTRL] = { |
| 366 | [MTK_VENDOR_ATTR_PP_MODE] = { .type = NLA_U8 }, |
| 367 | - [MTK_VENDOR_ATTR_PP_BAND_IDX] = { .type = NLA_U8 }, |
| 368 | + [MTK_VENDOR_ATTR_PP_LINK_ID] = { .type = NLA_U8 }, |
| 369 | + [MTK_VENDOR_ATTR_PP_BITMAP] = { .type = NLA_U16 }, |
| 370 | + [MTK_VENDOR_ATTR_PP_CURR_FREQ] = { .type = NLA_U32 }, |
| 371 | }; |
| 372 | |
| 373 | static struct nla_policy csi_ctrl_policy[NUM_MTK_VENDOR_ATTRS_CSI_CTRL] = { |
| 374 | @@ -15248,7 +15250,7 @@ static int nl80211_background_radar_mode(void *priv, const u8 background_radar_m |
| 375 | return ret; |
| 376 | } |
| 377 | |
| 378 | -static int nl80211_pp_mode_set(void *priv, const u8 pp_mode, u8 band_idx) |
| 379 | +static int nl80211_pp_mode_set(void *priv, const u8 pp_mode, s8 link_id, u16 punct_bitmap) |
| 380 | { |
| 381 | struct i802_bss *bss = priv; |
| 382 | struct wpa_driver_nl80211_data *drv = bss->drv; |
| 383 | @@ -15275,8 +15277,10 @@ static int nl80211_pp_mode_set(void *priv, const u8 pp_mode, u8 band_idx) |
| 384 | if (!data) |
| 385 | goto fail; |
| 386 | |
| 387 | - nla_put_u8(msg, MTK_VENDOR_ATTR_PP_BAND_IDX, band_idx); |
| 388 | + if (link_id > -1) |
| 389 | + nla_put_u8(msg, MTK_VENDOR_ATTR_PP_LINK_ID, link_id); |
| 390 | nla_put_u8(msg, MTK_VENDOR_ATTR_PP_MODE, pp_mode); |
| 391 | + nla_put_u16(msg, MTK_VENDOR_ATTR_PP_BITMAP, punct_bitmap); |
| 392 | |
| 393 | nla_nest_end(msg, data); |
| 394 | ret = send_and_recv_cmd(drv, msg); |
| 395 | diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c |
| 396 | index e95593a5b..efdb8ef7f 100644 |
| 397 | --- a/src/drivers/driver_nl80211_event.c |
| 398 | +++ b/src/drivers/driver_nl80211_event.c |
| 399 | @@ -19,6 +19,7 @@ |
| 400 | #include "common/ieee802_11_defs.h" |
| 401 | #include "common/ieee802_11_common.h" |
| 402 | #include "driver_nl80211.h" |
| 403 | +#include "common/mtk_vendor.h" |
| 404 | |
| 405 | |
| 406 | static void |
| 407 | @@ -3332,6 +3333,50 @@ static void nl80211_vendor_event_brcm(struct wpa_driver_nl80211_data *drv, |
| 408 | |
| 409 | #endif /* CONFIG_DRIVER_NL80211_BRCM */ |
| 410 | |
| 411 | +static void mtk_nl80211_pp_bitmap_update(struct wpa_driver_nl80211_data *drv, |
| 412 | + const u8 *data, size_t len) |
| 413 | +{ |
| 414 | + struct nlattr *tb[MTK_VENDOR_ATTR_PP_CTRL_MAX + 1]; |
| 415 | + union wpa_event_data event; |
| 416 | + |
| 417 | + wpa_printf(MSG_DEBUG, |
| 418 | + "nl80211: MTK pp bitmap update vendor event received"); |
| 419 | + |
| 420 | + if (nla_parse(tb, MTK_VENDOR_ATTR_PP_CTRL_MAX, |
| 421 | + (struct nlattr *) data, len, NULL) || |
| 422 | + !tb[MTK_VENDOR_ATTR_PP_CURR_FREQ] || |
| 423 | + !tb[MTK_VENDOR_ATTR_PP_BITMAP]) |
| 424 | + return; |
| 425 | + |
| 426 | + os_memset(&event, 0, sizeof(event)); |
| 427 | + event.ch_switch.freq = nla_get_u32(tb[MTK_VENDOR_ATTR_PP_CURR_FREQ]); |
| 428 | + |
| 429 | + event.ch_switch.link_id = |
| 430 | + nl80211_get_link_id_by_freq(drv->first_bss, event.ch_switch.freq); |
| 431 | + event.ch_switch.punct_bitmap = |
| 432 | + nla_get_u16(tb[MTK_VENDOR_ATTR_PP_BITMAP]); |
| 433 | + |
| 434 | + wpa_printf(MSG_DEBUG, |
| 435 | + "nl80211: puncture bitmap: 0x%04x, link_id: %d", |
| 436 | + event.ch_switch.punct_bitmap, event.ch_switch.link_id); |
| 437 | + wpa_supplicant_event(drv->ctx, EVENT_PP_BITMAP_UPDATE, &event); |
| 438 | +} |
| 439 | + |
| 440 | +static void nl80211_vendor_event_mtk(struct wpa_driver_nl80211_data *drv, |
| 441 | + u32 subcmd, u8 *data, size_t len) |
| 442 | +{ |
| 443 | + wpa_printf(MSG_DEBUG, "nl80211: Got MTK vendor event %u", subcmd); |
| 444 | + switch (subcmd) { |
| 445 | + case MTK_NL80211_VENDOR_EVENT_PP_BMP_UPDATE: |
| 446 | + mtk_nl80211_pp_bitmap_update(drv, data, len); |
| 447 | + break; |
| 448 | + default: |
| 449 | + wpa_printf(MSG_DEBUG, |
| 450 | + "%s: Ignore unsupported MTK vendor event %u", |
| 451 | + __func__, subcmd); |
| 452 | + break; |
| 453 | + } |
| 454 | +} |
| 455 | |
| 456 | static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv, |
| 457 | struct nlattr **tb) |
| 458 | @@ -3388,6 +3433,9 @@ static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv, |
| 459 | nl80211_vendor_event_brcm(drv, subcmd, data, len); |
| 460 | break; |
| 461 | #endif /* CONFIG_DRIVER_NL80211_BRCM */ |
| 462 | + case OUI_MTK: |
| 463 | + nl80211_vendor_event_mtk(drv, subcmd, data, len); |
| 464 | + break; |
| 465 | default: |
| 466 | wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event"); |
| 467 | break; |
| 468 | -- |
| 469 | 2.18.0 |
| 470 | |