qcacld-3.0: Add support for TWT get capabilities vendor command
Add support to get the TWT self and peer capabilities via the QCA_WLAN_TWT_GET_CAPABILTIES vendor command. High 16 bits - self capabilities, Low 16 bits : peer device’s capabilities The meaning of each bit is below: Bit 0: Requester Support Bit 1: Responder Support Bit 2: Broadcast TWT Support Bit 3: Flexible TWT Support Bit 4: TWT Required Change-Id: I78b0c5902c89fe3a8eec1697fa513aac3c2b7a36 CRs-Fixed: 2847177
This commit is contained in:

committed by
snandini

parent
fccdc9cc8a
commit
f7735c8ba3
@@ -885,6 +885,10 @@ int wmi_twt_del_status_to_vendor_twt_status(enum WMI_HOST_DEL_TWT_STATUS status)
|
|||||||
return QCA_WLAN_VENDOR_TWT_STATUS_NO_ACK;
|
return QCA_WLAN_VENDOR_TWT_STATUS_NO_ACK;
|
||||||
case WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR:
|
case WMI_HOST_DEL_TWT_STATUS_UNKNOWN_ERROR:
|
||||||
return QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR;
|
return QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR;
|
||||||
|
case WMI_DEL_TWT_STATUS_PEER_INIT_TEARDOWN:
|
||||||
|
return QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE;
|
||||||
|
case WMI_DEL_TWT_STATUS_ROAMING:
|
||||||
|
return QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE;
|
||||||
default:
|
default:
|
||||||
return QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR;
|
return QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
@@ -1193,6 +1197,7 @@ int hdd_send_twt_add_dialog_cmd(struct hdd_context *hdd_ctx,
|
|||||||
static int hdd_twt_setup_session(struct hdd_adapter *adapter,
|
static int hdd_twt_setup_session(struct hdd_adapter *adapter,
|
||||||
struct nlattr *twt_param_attr)
|
struct nlattr *twt_param_attr)
|
||||||
{
|
{
|
||||||
|
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||||
struct hdd_station_ctx *hdd_sta_ctx = NULL;
|
struct hdd_station_ctx *hdd_sta_ctx = NULL;
|
||||||
struct wmi_twt_add_dialog_param params = {0};
|
struct wmi_twt_add_dialog_param params = {0};
|
||||||
struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
|
struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
|
||||||
@@ -1212,6 +1217,9 @@ static int hdd_twt_setup_session(struct hdd_adapter *adapter,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hdd_is_roaming_in_progress(hdd_ctx))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
qdf_mem_copy(params.peer_macaddr,
|
qdf_mem_copy(params.peer_macaddr,
|
||||||
hdd_sta_ctx->conn_info.bssid.bytes,
|
hdd_sta_ctx->conn_info.bssid.bytes,
|
||||||
QDF_MAC_ADDR_SIZE);
|
QDF_MAC_ADDR_SIZE);
|
||||||
@@ -2014,6 +2022,125 @@ hdd_send_twt_resume_dialog_cmd(struct hdd_context *hdd_ctx,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hdd_twt_pack_get_capabilities_resp - TWT pack and send response to
|
||||||
|
* userspace for get capabilities command
|
||||||
|
* @adapter: Pointer to hdd adapter
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS
|
||||||
|
*/
|
||||||
|
static QDF_STATUS
|
||||||
|
hdd_twt_pack_get_capabilities_resp(struct hdd_adapter *adapter)
|
||||||
|
{
|
||||||
|
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||||
|
struct nlattr *config_attr;
|
||||||
|
struct sk_buff *reply_skb;
|
||||||
|
size_t skb_len = NLMSG_HDRLEN;
|
||||||
|
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
|
||||||
|
uint8_t peer_cap = 0, self_cap = 0;
|
||||||
|
bool twt_req = false, twt_bcast_req = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Length of attribute QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF &
|
||||||
|
* QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER
|
||||||
|
*/
|
||||||
|
skb_len += 2 * nla_total_size(sizeof(u16)) + NLA_HDRLEN;
|
||||||
|
|
||||||
|
reply_skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
|
||||||
|
skb_len);
|
||||||
|
if (!reply_skb) {
|
||||||
|
hdd_err("TWT: get_caps alloc reply skb failed");
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
config_attr = nla_nest_start(reply_skb,
|
||||||
|
QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
|
||||||
|
if (!config_attr) {
|
||||||
|
hdd_err("TWT: nla_nest_start error");
|
||||||
|
qdf_status = QDF_STATUS_E_FAILURE;
|
||||||
|
goto free_skb;
|
||||||
|
}
|
||||||
|
|
||||||
|
ucfg_mlme_get_twt_requestor(hdd_ctx->psoc, &twt_req);
|
||||||
|
if (twt_req)
|
||||||
|
self_cap |= QCA_WLAN_TWT_CAPA_REQUESTOR;
|
||||||
|
|
||||||
|
ucfg_mlme_get_twt_bcast_requestor(hdd_ctx->psoc,
|
||||||
|
&twt_bcast_req);
|
||||||
|
if (twt_bcast_req)
|
||||||
|
self_cap |= QCA_WLAN_TWT_CAPA_BROADCAST;
|
||||||
|
|
||||||
|
if (nla_put_u16(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF,
|
||||||
|
self_cap)) {
|
||||||
|
hdd_err("TWT: Failed to fill capabilities");
|
||||||
|
qdf_status = QDF_STATUS_E_FAILURE;
|
||||||
|
goto free_skb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nla_put_u16(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER,
|
||||||
|
peer_cap)) {
|
||||||
|
hdd_err("TWT: Failed to fill capabilities");
|
||||||
|
qdf_status = QDF_STATUS_E_FAILURE;
|
||||||
|
goto free_skb;
|
||||||
|
}
|
||||||
|
|
||||||
|
nla_nest_end(reply_skb, config_attr);
|
||||||
|
|
||||||
|
if (cfg80211_vendor_cmd_reply(reply_skb))
|
||||||
|
qdf_status = QDF_STATUS_E_INVAL;
|
||||||
|
|
||||||
|
free_skb:
|
||||||
|
if (QDF_IS_STATUS_ERROR(qdf_status) && reply_skb)
|
||||||
|
kfree_skb(reply_skb);
|
||||||
|
|
||||||
|
return qdf_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hdd_twt_get_capabilities() - Process TWT resume operation
|
||||||
|
* in the received vendor command and send it to firmware
|
||||||
|
* @adapter: adapter pointer
|
||||||
|
* @twt_param_attr: nl attributes
|
||||||
|
*
|
||||||
|
* Handles QCA_WLAN_TWT_RESUME
|
||||||
|
*
|
||||||
|
* Return: 0 on success, negative value on failure
|
||||||
|
*/
|
||||||
|
static int hdd_twt_get_capabilities(struct hdd_adapter *adapter,
|
||||||
|
struct nlattr *twt_param_attr)
|
||||||
|
{
|
||||||
|
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||||
|
struct hdd_station_ctx *hdd_sta_ctx;
|
||||||
|
QDF_STATUS status;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = wlan_hdd_validate_context(hdd_ctx);
|
||||||
|
if (ret < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (adapter->device_mode != QDF_STA_MODE &&
|
||||||
|
adapter->device_mode != QDF_P2P_CLIENT_MODE) {
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
||||||
|
if (hdd_sta_ctx->conn_info.conn_state != eConnectionState_Associated) {
|
||||||
|
hdd_err_rl("Invalid state, vdev %d mode %d state %d",
|
||||||
|
adapter->vdev_id, adapter->device_mode,
|
||||||
|
hdd_sta_ctx->conn_info.conn_state);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdd_is_roaming_in_progress(hdd_ctx))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
status = hdd_twt_pack_get_capabilities_resp(adapter);
|
||||||
|
if (QDF_IS_STATUS_ERROR(status))
|
||||||
|
hdd_err_rl("TWT: Get capabilities failed");
|
||||||
|
|
||||||
|
return qdf_status_to_os_return(status);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hdd_twt_resume_session - Process TWT resume operation
|
* hdd_twt_resume_session - Process TWT resume operation
|
||||||
* in the received vendor command and send it to firmware
|
* in the received vendor command and send it to firmware
|
||||||
@@ -2114,22 +2241,23 @@ static int hdd_twt_configure(struct hdd_adapter *adapter,
|
|||||||
|
|
||||||
id = QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION;
|
id = QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION;
|
||||||
twt_oper_attr = tb[id];
|
twt_oper_attr = tb[id];
|
||||||
|
twt_oper = nla_get_u8(twt_oper_attr);
|
||||||
|
|
||||||
if (!twt_oper_attr) {
|
if (!twt_oper_attr) {
|
||||||
hdd_err("TWT parameters NOT specified");
|
hdd_err("TWT operation NOT specified");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
id = QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS;
|
id = QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS;
|
||||||
twt_param_attr = tb[id];
|
twt_param_attr = tb[id];
|
||||||
|
|
||||||
if (!twt_param_attr) {
|
if (!twt_param_attr &&
|
||||||
|
twt_oper != QCA_WLAN_TWT_GET_CAPABILITIES) {
|
||||||
hdd_err("TWT parameters NOT specified");
|
hdd_err("TWT parameters NOT specified");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
twt_oper = nla_get_u8(twt_oper_attr);
|
hdd_debug("TWT Operation 0x%x", twt_oper);
|
||||||
hdd_debug("twt: TWT Operation 0x%x", twt_oper);
|
|
||||||
|
|
||||||
switch (twt_oper) {
|
switch (twt_oper) {
|
||||||
case QCA_WLAN_TWT_SET:
|
case QCA_WLAN_TWT_SET:
|
||||||
@@ -2150,6 +2278,9 @@ static int hdd_twt_configure(struct hdd_adapter *adapter,
|
|||||||
case QCA_WLAN_TWT_NUDGE:
|
case QCA_WLAN_TWT_NUDGE:
|
||||||
ret = hdd_twt_nudge_session(adapter, twt_param_attr);
|
ret = hdd_twt_nudge_session(adapter, twt_param_attr);
|
||||||
break;
|
break;
|
||||||
|
case QCA_WLAN_TWT_GET_CAPABILITIES:
|
||||||
|
ret = hdd_twt_get_capabilities(adapter, twt_param_attr);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
hdd_err("Invalid TWT Operation");
|
hdd_err("Invalid TWT Operation");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
@@ -2204,6 +2335,7 @@ __wlan_hdd_cfg80211_wifi_twt_config(struct wiphy *wiphy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
errno = hdd_twt_configure(adapter, tb);
|
errno = hdd_twt_configure(adapter, tb);
|
||||||
|
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user