382 lines
11 KiB
Diff
382 lines
11 KiB
Diff
From 67be9ce68d84e2800b481123a0c140e5ad912619 Mon Sep 17 00:00:00 2001
|
|
From: Carter Chen <carter.chen@infineon.com>
|
|
Date: Wed, 14 Dec 2022 01:34:23 -0600
|
|
Subject: [PATCH 49/60] non-upstream: MBO: wpa_cli mbo command by IFX vendorID
|
|
|
|
Signed-off-by: Carter Chen <carter.chen@infineon.com>
|
|
Signed-off-by: Shelley Yang <shelley.yang@infineon.com>
|
|
---
|
|
src/common/ifx_vendor.h | 52 +++++++++++
|
|
src/drivers/driver.h | 46 ++++++++++
|
|
src/drivers/driver_nl80211.c | 141 ++++++++++++++++++++++++++++++
|
|
src/drivers/driver_nl80211.h | 1 +
|
|
src/drivers/driver_nl80211_capa.c | 3 +
|
|
5 files changed, 243 insertions(+)
|
|
|
|
diff --git a/src/common/ifx_vendor.h b/src/common/ifx_vendor.h
|
|
index aa8e83b..6cd3b87 100644
|
|
--- a/src/common/ifx_vendor.h
|
|
+++ b/src/common/ifx_vendor.h
|
|
@@ -54,10 +54,12 @@
|
|
*
|
|
* @IFX_VENDOR_SCMD_AMSDU: Vendor command to enable/disable AMSDU on all the TID queues
|
|
*
|
|
* @IFX_VENDOR_SCMD_TWT: Vendor subcommand to configure TWT
|
|
* Uses attributes defined in enum ifx_vendor_attr_twt.
|
|
+ * @IFX_VENDOR_SCMD_MBO: Vendor subcommand to configure MBO
|
|
+ * Uses attribute IFX_VENDOR_ATTR_MBO to configure.
|
|
*
|
|
* @IFX_VENDOR_SCMD_MAX: This acts as a the tail of cmds list.
|
|
* Make sure it located at the end of the list.
|
|
*/
|
|
enum ifx_nl80211_vendor_subcmds {
|
|
@@ -72,10 +74,12 @@ enum ifx_nl80211_vendor_subcmds {
|
|
/* Reserved 7-10 */
|
|
IFX_VENDOR_SCMD_MUEDCA_OPT_ENABLE = 11,
|
|
IFX_VENDOR_SCMD_LDPC_CAP = 12,
|
|
IFX_VENDOR_SCMD_AMSDU = 13,
|
|
IFX_VENDOR_SCMD_TWT = 14,
|
|
+ /* Reserved 15-17 */
|
|
+ IFX_VENDOR_SCMD_MBO = 18,
|
|
IFX_VENDOR_SCMD_MAX
|
|
};
|
|
|
|
/*
|
|
* enum ifx_vendor_attr - IFX nl80211 vendor attributes
|
|
@@ -94,10 +98,17 @@ enum ifx_vendor_attr {
|
|
IFX_VENDOR_ATTR_UNSPEC = 0,
|
|
/* Reserved 1-10 */
|
|
IFX_VENDOR_ATTR_MAX = 11
|
|
};
|
|
|
|
+enum ifx_vendor_attr_mbo {
|
|
+ IFX_VENDOR_ATTR_MBO_UNSPEC,
|
|
+ IFX_VENDOR_ATTR_MBO_CMD,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAMS,
|
|
+ IFX_VENDOR_ATTR_MBO_MAX
|
|
+};
|
|
+
|
|
/*
|
|
* enum ifx_vendor_attr_twt - Attributes for the TWT vendor command
|
|
*
|
|
* @IFX_VENDOR_ATTR_TWT_UNSPEC: Reserved value 0
|
|
*
|
|
@@ -258,6 +269,47 @@ enum ifx_twt_oper_setup_cmd_type {
|
|
IFX_TWT_OPER_SETUP_CMD_TYPE_DICTATE = 6,
|
|
IFX_TWT_OPER_SETUP_CMD_TYPE_REJECT = 7,
|
|
IFX_TWT_OPER_SETUP_CMD_TYPE_MAX = 8
|
|
};
|
|
|
|
+enum ifx_mbo_config_cmd_type {
|
|
+ IFX_MBO_CONFIG_CMD_TYPE_INVALID = -1,
|
|
+ //align internal definition
|
|
+ IFX_MBO_CONFIG_CMD_ADD_CHAN_PREF = 1,
|
|
+ IFX_MBO_CONFIG_CMD_DEL_CHAN_PREF = 2,
|
|
+ IFX_MBO_CONFIG_CMD_LIST_CHAN_PREF = 3,
|
|
+ IFX_MBO_CONFIG_CMD_CELLULAR_DATA_CAP = 4,
|
|
+ IFX_MBO_CONFIG_CMD_DUMP_COUNTER = 5,
|
|
+ IFX_MBO_CONFIG_CMD_CLEAR_COUNTER = 6,
|
|
+ IFX_MBO_CONFIG_CMD_FORCE_ASSOC = 7,
|
|
+ IFX_MBO_CONFIG_CMD_BSSTRANS_REJ = 8,
|
|
+ IFX_MBO_CONFIG_CMD_SEND_NOTIF = 9,
|
|
+ IFX_MBO_CONFIG_CMD_CLR_CHAN_PREF = 10,
|
|
+ IFX_MBO_CONFIG_CMD_NBR_INFO_CACHE = 11,
|
|
+ IFX_MBO_CONFIG_CMD_ANQPO_SUPPORT = 12,
|
|
+ IFX_MBO_CONFIG_CMD_DBG_EVENT_CHECK = 13,
|
|
+ IFX_MBO_CONFIG_CMD_EVENT_MASK = 14,
|
|
+ IFX_MBO_CONFIG_CMD_ASSOC_DISALLOWED = 15,
|
|
+ IFX_MBO_CONFIG_CMD_CELLULAR_DATA_PREF = 16,
|
|
+ IFX_MBO_CONFIG_CMD_TYPE_MAX = 17
|
|
+};
|
|
+
|
|
+enum ifx_vendor_attr_mbo_param {
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_UNSPEC,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_OPCLASS,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_CHAN,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_PREFERENCE,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_REASON_CODE,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_CELL_DATA_CAP,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_COUNTERS,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_ENABLE,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_SUB_ELEM_TYPE,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_BTQ_TRIG_START_OFFSET,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_BTQ_TRIG_RSSI_DELTA,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_ANQP_CELL_SUPP,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_BIT_MASK,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_ASSOC_DISALLOWED,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_CELLULAR_DATA_PREF,
|
|
+ IFX_VENDOR_ATTR_MBO_PARAM_MAX
|
|
+};
|
|
+
|
|
#endif /* IFX_VENDOR_H */
|
|
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
|
|
index 23f599b..996614e 100644
|
|
--- a/src/drivers/driver.h
|
|
+++ b/src/drivers/driver.h
|
|
@@ -2551,10 +2551,55 @@ struct drv_teardown_twt_params {
|
|
u8 flow_id;
|
|
u8 bcast_twt_id;
|
|
u8 teardown_all_twt;
|
|
};
|
|
#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
+
|
|
+struct drv_config_mbo_params {
|
|
+ u8 cmd;
|
|
+ union {
|
|
+ struct {
|
|
+ u8 op_class;
|
|
+ u8 chan;
|
|
+ u8 pref_val;
|
|
+ u8 reason;
|
|
+ } add_chan_pref;
|
|
+ struct {
|
|
+ u8 op_class;
|
|
+ u8 chan;
|
|
+ } del_chan_pref;
|
|
+ struct {
|
|
+ u8 cap;
|
|
+ } cell_data_cap;
|
|
+ struct {
|
|
+ u8 enable;
|
|
+ } force_assoc;
|
|
+ struct {
|
|
+ u8 enable;
|
|
+ u8 reason;
|
|
+ } bsstrans_reject;
|
|
+ struct {
|
|
+ u8 type;
|
|
+ } send_notif;
|
|
+ struct {
|
|
+ u8 enable;
|
|
+ u8 t_offset;
|
|
+ u8 trig_delta;
|
|
+ } nbr_info_cache;
|
|
+ struct {
|
|
+ u8 enable;
|
|
+ u8 value;
|
|
+ } anqpo_support;
|
|
+ struct {
|
|
+ u8 disallow;
|
|
+ u8 reason;
|
|
+ } assoc_disallow;
|
|
+ struct {
|
|
+ u8 pref_value;
|
|
+ } cellular_pref;
|
|
+ } u;
|
|
+};
|
|
#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
|
|
struct wpa_bss_trans_info {
|
|
u8 mbo_transition_reason;
|
|
u8 n_candidates;
|
|
@@ -4679,10 +4724,11 @@ struct wpa_driver_ops {
|
|
* teardown_twt - Teardown the already negotiated TWT session
|
|
* @params: Teardown TWT params
|
|
*/
|
|
int (*teardown_twt)(void *priv, struct drv_teardown_twt_params *params);
|
|
#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
+ int (*config_mbo)(void *priv, struct drv_config_mbo_params *params);
|
|
#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
|
|
};
|
|
|
|
/**
|
|
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
|
|
index 3d98e59..506b1e4 100644
|
|
--- a/src/drivers/driver_nl80211.c
|
|
+++ b/src/drivers/driver_nl80211.c
|
|
@@ -12471,10 +12471,150 @@ fail:
|
|
nl80211_nlmsg_clear(msg);
|
|
nlmsg_free(msg);
|
|
return ret;
|
|
}
|
|
#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
+
|
|
+static int wpa_driver_nl80211_config_mbo(void *priv, struct drv_config_mbo_params *params)
|
|
+{
|
|
+ struct i802_bss *bss = priv;
|
|
+ struct wpa_driver_nl80211_data *drv = bss->drv;
|
|
+ struct nl_msg *msg = NULL;
|
|
+ struct nlattr *data, *mbo_param_attrs;
|
|
+ int ret = -1;
|
|
+
|
|
+ if (!drv->ifx_mbo_offload)
|
|
+ goto fail;
|
|
+
|
|
+ if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
|
|
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_IFX) ||
|
|
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, IFX_VENDOR_SCMD_MBO))
|
|
+ goto fail;
|
|
+
|
|
+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
|
|
+ if (!data)
|
|
+ goto fail;
|
|
+
|
|
+ if (nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_CMD, params->cmd))
|
|
+ goto fail;
|
|
+
|
|
+ switch (params->cmd) {
|
|
+ case IFX_MBO_CONFIG_CMD_ADD_CHAN_PREF:
|
|
+ mbo_param_attrs = nla_nest_start(msg, IFX_VENDOR_ATTR_MBO_PARAMS);
|
|
+ if (!mbo_param_attrs)
|
|
+ goto fail;
|
|
+
|
|
+ if (nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_PARAM_OPCLASS,
|
|
+ params->u.add_chan_pref.op_class) ||
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_PARAM_CHAN,
|
|
+ params->u.add_chan_pref.chan) ||
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_PARAM_PREFERENCE,
|
|
+ params->u.add_chan_pref.pref_val) ||
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_PARAM_REASON_CODE,
|
|
+ params->u.add_chan_pref.reason)) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "nl80211: MBO config: build IFX_MBO_CONFIG_CMD_ADD_CHAN_PREF msg failed");
|
|
+ goto fail;
|
|
+ }
|
|
+ nla_nest_end(msg, mbo_param_attrs);
|
|
+ break;
|
|
+ case IFX_MBO_CONFIG_CMD_DEL_CHAN_PREF:
|
|
+ mbo_param_attrs = nla_nest_start(msg, IFX_VENDOR_ATTR_MBO_PARAMS);
|
|
+ if (!mbo_param_attrs)
|
|
+ goto fail;
|
|
+
|
|
+ if (nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_PARAM_OPCLASS,
|
|
+ params->u.del_chan_pref.op_class) ||
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_PARAM_CHAN,
|
|
+ params->u.del_chan_pref.chan)) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "nl80211: MBO config: build IFX_MBO_CONFIG_CMD_DEL_CHAN_PREF msg failed");
|
|
+ goto fail;
|
|
+ }
|
|
+ nla_nest_end(msg, mbo_param_attrs);
|
|
+ break;
|
|
+ case IFX_MBO_CONFIG_CMD_CELLULAR_DATA_CAP:
|
|
+ mbo_param_attrs = nla_nest_start(msg, IFX_VENDOR_ATTR_MBO_PARAMS);
|
|
+ if (!mbo_param_attrs)
|
|
+ goto fail;
|
|
+
|
|
+ if (nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_PARAM_CELL_DATA_CAP,
|
|
+ params->u.cell_data_cap.cap)) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "nl80211: MBO config: build IFX_MBO_CONFIG_CMD_CELLULAR_DATA_CAP msg failed");
|
|
+ goto fail;
|
|
+ }
|
|
+ nla_nest_end(msg, mbo_param_attrs);
|
|
+ break;
|
|
+ case IFX_MBO_CONFIG_CMD_FORCE_ASSOC:
|
|
+ mbo_param_attrs = nla_nest_start(msg, IFX_VENDOR_ATTR_MBO_PARAMS);
|
|
+ if (!mbo_param_attrs)
|
|
+ goto fail;
|
|
+
|
|
+ if (nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_PARAM_ENABLE,
|
|
+ params->u.force_assoc.enable)) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "nl80211: MBO config: build IFX_MBO_CONFIG_CMD_FORCE_ASSOC msg failed");
|
|
+ goto fail;
|
|
+ }
|
|
+ nla_nest_end(msg, mbo_param_attrs);
|
|
+ break;
|
|
+ case IFX_MBO_CONFIG_CMD_BSSTRANS_REJ:
|
|
+ mbo_param_attrs = nla_nest_start(msg, IFX_VENDOR_ATTR_MBO_PARAMS);
|
|
+ if (!mbo_param_attrs)
|
|
+ goto fail;
|
|
+
|
|
+ if (nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_PARAM_ENABLE,
|
|
+ params->u.bsstrans_reject.enable) ||
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_PARAM_REASON_CODE,
|
|
+ params->u.bsstrans_reject.reason)) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "nl80211: MBO config: build IFX_MBO_CONFIG_CMD_DEL_CHAN_PREF msg failed");
|
|
+ goto fail;
|
|
+ }
|
|
+ nla_nest_end(msg, mbo_param_attrs);
|
|
+ break;
|
|
+ case IFX_MBO_CONFIG_CMD_SEND_NOTIF:
|
|
+ mbo_param_attrs = nla_nest_start(msg, IFX_VENDOR_ATTR_MBO_PARAMS);
|
|
+ if (!mbo_param_attrs)
|
|
+ goto fail;
|
|
+
|
|
+ if (nla_put_u8(msg, IFX_VENDOR_ATTR_MBO_PARAM_SUB_ELEM_TYPE,
|
|
+ params->u.send_notif.type)) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "nl80211: MBO config: build IFX_MBO_CONFIG_CMD_FORCE_ASSOC msg failed");
|
|
+ goto fail;
|
|
+ }
|
|
+ nla_nest_end(msg, mbo_param_attrs);
|
|
+ break;
|
|
+ case IFX_MBO_CONFIG_CMD_LIST_CHAN_PREF:
|
|
+ case IFX_MBO_CONFIG_CMD_DUMP_COUNTER:
|
|
+ case IFX_MBO_CONFIG_CMD_CLEAR_COUNTER:
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "MBO config: cmd %d doesn't need extra attribute",
|
|
+ params->cmd);
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ nla_nest_end(msg, data);
|
|
+
|
|
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
|
+ if (ret) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "nl80211: MBO config: Failed to invoke driver "
|
|
+ "MBO config function: %s",
|
|
+ strerror(-ret));
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+fail:
|
|
+ nl80211_nlmsg_clear(msg);
|
|
+ nlmsg_free(msg);
|
|
+ return ret;
|
|
+}
|
|
#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
|
|
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
|
.name = "nl80211",
|
|
.desc = "Linux nl80211/cfg80211",
|
|
@@ -12622,7 +12762,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
|
#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
#ifdef CONFIG_TWT_OFFLOAD_IFX
|
|
.setup_twt = wpa_driver_nl80211_setup_twt,
|
|
.teardown_twt = wpa_driver_nl80211_teardown_twt,
|
|
#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
+ .config_mbo = wpa_driver_nl80211_config_mbo,
|
|
#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
};
|
|
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
|
|
index f681afb..6d2c094 100644
|
|
--- a/src/drivers/driver_nl80211.h
|
|
+++ b/src/drivers/driver_nl80211.h
|
|
@@ -180,10 +180,11 @@ struct wpa_driver_nl80211_data {
|
|
unsigned int unsol_bcast_probe_resp:1;
|
|
unsigned int qca_do_acs:1;
|
|
unsigned int brcm_do_acs:1;
|
|
#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
unsigned int ifx_twt_offload:1;
|
|
+ unsigned int ifx_mbo_offload:1;
|
|
#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
|
|
u64 vendor_scan_cookie;
|
|
u64 remain_on_chan_cookie;
|
|
u64 send_frame_cookie;
|
|
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
|
|
index 19d1569..b0807a7 100644
|
|
--- a/src/drivers/driver_nl80211_capa.c
|
|
+++ b/src/drivers/driver_nl80211_capa.c
|
|
@@ -1057,10 +1057,13 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
|
|
} else if (vinfo->vendor_id == OUI_IFX) {
|
|
switch (vinfo->subcmd) {
|
|
case IFX_VENDOR_SCMD_TWT:
|
|
drv->ifx_twt_offload = 1;
|
|
break;
|
|
+ case IFX_VENDOR_SCMD_MBO:
|
|
+ drv->ifx_mbo_offload = 1;
|
|
+ break;
|
|
}
|
|
#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
}
|
|
|
|
wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
|