| From d6a05d4839676a55e440ea03420000dd2499b4c9 Mon Sep 17 00:00:00 2001 |
| From: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
| Date: Fri, 2 Sep 2022 01:03:23 +0800 |
| Subject: [PATCH 018/126] mtk: hostapd: Add three wire PTA ctrl hostapd vendor |
| command |
| |
| Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
| --- |
| hostapd/config_file.c | 4 ++++ |
| src/ap/ap_config.c | 1 + |
| src/ap/ap_config.h | 13 ++++++++++++ |
| src/ap/ap_drv_ops.c | 11 +++++++++++ |
| src/ap/ap_drv_ops.h | 1 + |
| src/ap/hostapd.c | 2 ++ |
| src/common/mtk_vendor.h | 16 +++++++++++++++ |
| src/drivers/driver.h | 8 ++++++++ |
| src/drivers/driver_nl80211.c | 33 +++++++++++++++++++++++++++++++ |
| src/drivers/driver_nl80211.h | 1 + |
| src/drivers/driver_nl80211_capa.c | 3 +++ |
| 11 files changed, 93 insertions(+) |
| |
| diff --git a/hostapd/config_file.c b/hostapd/config_file.c |
| index 22da72c07..ebbd56734 100644 |
| --- a/hostapd/config_file.c |
| +++ b/hostapd/config_file.c |
| @@ -5513,6 +5513,10 @@ static int hostapd_config_fill(struct hostapd_config *conf, |
| return 1; |
| } |
| conf->edcca_compensation = (s8) val; |
| + } else if (os_strcmp(buf, "three_wire_enable") == 0) { |
| + u8 en = atoi(pos); |
| + |
| + conf->three_wire_enable = en; |
| } else { |
| wpa_printf(MSG_ERROR, |
| "Line %d: unknown configuration item '%s'", |
| diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c |
| index 45c391a65..cd520ebdc 100644 |
| --- a/src/ap/ap_config.c |
| +++ b/src/ap/ap_config.c |
| @@ -308,6 +308,7 @@ struct hostapd_config * hostapd_config_defaults(void) |
| |
| conf->edcca_enable = EDCCA_MODE_AUTO; |
| conf->edcca_compensation = EDCCA_DEFAULT_COMPENSATION; |
| + conf->three_wire_enable = THREE_WIRE_MODE_DISABLE; |
| |
| hostapd_set_and_check_bw320_offset(conf, 0); |
| |
| diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h |
| index baf3b40f8..3ab6cae2c 100644 |
| --- a/src/ap/ap_config.h |
| +++ b/src/ap/ap_config.h |
| @@ -1339,6 +1339,19 @@ struct hostapd_config { |
| u8 edcca_enable; |
| s8 edcca_compensation; |
| int *edcca_threshold; |
| + u8 three_wire_enable; |
| +}; |
| + |
| +enum three_wire_mode { |
| + THREE_WIRE_MODE_DISABLE, |
| + THREE_WIRE_MODE_EXT0_ENABLE, |
| + THREE_WIRE_MODE_EXT1_ENABLE, |
| + THREE_WIRE_MODE_ALL_ENABLE, |
| + |
| + /* keep last */ |
| + NUM_THREE_WIRE_MODE, |
| + THREE_WIRE_MODE_MAX = |
| + NUM_THREE_WIRE_MODE - 1 |
| }; |
| |
| enum edcca_mode { |
| diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c |
| index 56d923462..fa6aa7085 100644 |
| --- a/src/ap/ap_drv_ops.c |
| +++ b/src/ap/ap_drv_ops.c |
| @@ -1312,3 +1312,14 @@ int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff) |
| return 0; |
| return hapd->driver->mu_dump(hapd->drv_priv, mu_onoff); |
| } |
| + |
| +int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd) |
| +{ |
| + if (!hapd->driver || !hapd->driver->three_wire_ctrl) |
| + return 0; |
| + if (hapd->iconf->three_wire_enable > THREE_WIRE_MODE_MAX) { |
| + wpa_printf(MSG_INFO, "Invalid value for three wire enable\n"); |
| + return 0; |
| + } |
| + return hapd->driver->three_wire_ctrl(hapd->drv_priv, hapd->iconf->three_wire_enable); |
| +} |
| diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h |
| index 47b23513f..008f56e76 100644 |
| --- a/src/ap/ap_drv_ops.h |
| +++ b/src/ap/ap_drv_ops.h |
| @@ -158,6 +158,7 @@ int hostapd_drv_configure_edcca_threshold(struct hostapd_data *hapd, |
| int hostapd_drv_get_edcca(struct hostapd_data *hapd, const u8 mode, u8 *value); |
| int hostapd_drv_mu_ctrl(struct hostapd_data *hapd); |
| int hostapd_drv_mu_dump(struct hostapd_data *hapd, u8 *mu_onoff); |
| +int hostapd_drv_three_wire_ctrl(struct hostapd_data *hapd); |
| |
| #include "drivers/driver.h" |
| |
| diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c |
| index 227474db5..56a024bbf 100644 |
| --- a/src/ap/hostapd.c |
| +++ b/src/ap/hostapd.c |
| @@ -2764,6 +2764,8 @@ dfs_offload: |
| goto fail; |
| if (hostapd_drv_mu_ctrl(hapd) < 0) |
| goto fail; |
| + if (hostapd_drv_three_wire_ctrl(hapd) < 0) |
| + goto fail; |
| |
| wpa_printf(MSG_DEBUG, "%s: Setup of interface done.", |
| iface->bss[0]->conf->iface); |
| diff --git a/src/common/mtk_vendor.h b/src/common/mtk_vendor.h |
| index 60bc4cd4c..99ecbaf71 100644 |
| --- a/src/common/mtk_vendor.h |
| +++ b/src/common/mtk_vendor.h |
| @@ -13,6 +13,7 @@ enum mtk_nl80211_vendor_subcmds { |
| MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5, |
| MTK_NL80211_VENDOR_SUBCMD_PHY_CAPA_CTRL= 0xc6, |
| MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL = 0xc7, |
| + MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL = 0xc8 |
| }; |
| |
| enum mtk_vendor_attr_edcca_ctrl { |
| @@ -58,6 +59,21 @@ static struct nla_policy edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = { |
| [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC160_VAL] = { .type = NLA_U8 }, |
| }; |
| |
| +enum mtk_vendor_attr_3wire_ctrl { |
| + MTK_VENDOR_ATTR_3WIRE_CTRL_UNSPEC, |
| + |
| + MTK_VENDOR_ATTR_3WIRE_CTRL_MODE, |
| + |
| + /* keep last */ |
| + NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL, |
| + MTK_VENDOR_ATTR_3WIRE_CTRL_MAX = |
| + NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL - 1 |
| +}; |
| + |
| +static struct nla_policy three_wire_ctrl_policy[NUM_MTK_VENDOR_ATTRS_3WIRE_CTRL] = { |
| + [MTK_VENDOR_ATTR_3WIRE_CTRL_MODE] = {.type = NLA_U8 }, |
| +}; |
| + |
| enum mtk_vendor_attr_csi_ctrl { |
| MTK_VENDOR_ATTR_CSI_CTRL_UNSPEC, |
| |
| diff --git a/src/drivers/driver.h b/src/drivers/driver.h |
| index 2217809db..13e91d21d 100644 |
| --- a/src/drivers/driver.h |
| +++ b/src/drivers/driver.h |
| @@ -5263,6 +5263,14 @@ struct wpa_driver_ops { |
| */ |
| int (*mu_ctrl)(void *priv, u8 mu_onoff); |
| int (*mu_dump)(void *priv, u8 *mu_onoff); |
| + |
| + /** |
| + * three_wire_ctrl - set three_wire_ctrl mode |
| + * @priv: Private driver interface data |
| + * @three_wire_enable: three_wire_ctrl mode |
| + * |
| + */ |
| + int (*three_wire_ctrl)(void *priv, u8 three_wire_enable); |
| }; |
| |
| /** |
| diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c |
| index 2e011e3df..f94fa19b0 100644 |
| --- a/src/drivers/driver_nl80211.c |
| +++ b/src/drivers/driver_nl80211.c |
| @@ -14379,6 +14379,38 @@ static int nl80211_get_edcca(void *priv, const u8 mode, u8 *value) |
| return ret; |
| } |
| |
| +static int nl80211_enable_three_wire(void *priv, const u8 three_wire_enable) |
| +{ |
| + struct i802_bss *bss = priv; |
| + struct wpa_driver_nl80211_data *drv = bss->drv; |
| + /* Prepare nl80211 cmd */ |
| + struct nl_msg *msg; |
| + struct nlattr *data; |
| + int ret; |
| + |
| + if (!drv->mtk_3wire_vendor_cmd_avail) { |
| + wpa_printf(MSG_INFO, |
| + "nl80211: Driver does not support setting three wire control"); |
| + return 0; |
| + } |
| + |
| + if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) || |
| + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_MTK) || |
| + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, |
| + MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL) || |
| + !(data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) || |
| + nla_put_u8(msg, MTK_VENDOR_ATTR_3WIRE_CTRL_MODE, three_wire_enable)) { |
| + nlmsg_free(msg); |
| + return -ENOBUFS; |
| + } |
| + nla_nest_end(msg, data); |
| + ret = send_and_recv_cmd(drv, msg); |
| + if (ret) { |
| + wpa_printf(MSG_ERROR, "Failed to enable three wire. ret=%d (%s) ", |
| + ret, strerror(-ret)); |
| + } |
| + return ret; |
| +} |
| |
| const struct wpa_driver_ops wpa_driver_nl80211_ops = { |
| .name = "nl80211", |
| @@ -14546,4 +14578,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { |
| .configure_edcca_enable = nl80211_configure_edcca_enable, |
| .configure_edcca_threshold = nl80211_configure_edcca_threshold, |
| .get_edcca = nl80211_get_edcca, |
| + .three_wire_ctrl = nl80211_enable_three_wire, |
| }; |
| diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h |
| index f99bba9e1..5de6ca6f0 100644 |
| --- a/src/drivers/driver_nl80211.h |
| +++ b/src/drivers/driver_nl80211.h |
| @@ -202,6 +202,7 @@ struct wpa_driver_nl80211_data { |
| unsigned int qca_ap_allowed_freqs:1; |
| unsigned int mtk_edcca_vendor_cmd_avail:1; |
| unsigned int mtk_mu_vendor_cmd_avail:1; |
| + unsigned int mtk_3wire_vendor_cmd_avail:1; |
| |
| u32 ignore_next_local_disconnect; |
| u32 ignore_next_local_deauth; |
| diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c |
| index 0eda91d0f..433eecf56 100644 |
| --- a/src/drivers/driver_nl80211_capa.c |
| +++ b/src/drivers/driver_nl80211_capa.c |
| @@ -1147,6 +1147,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg) |
| case MTK_NL80211_VENDOR_SUBCMD_MU_CTRL : |
| drv->mtk_mu_vendor_cmd_avail = 1; |
| break; |
| + case MTK_NL80211_VENDOR_SUBCMD_3WIRE_CTRL : |
| + drv->mtk_3wire_vendor_cmd_avail = 1; |
| + break; |
| } |
| } |
| |
| -- |
| 2.18.0 |
| |