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
Cette révision appartient à :

révisé par
snandini

Parent
fccdc9cc8a
révision
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;
|
||||
case WMI_HOST_DEL_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:
|
||||
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,
|
||||
struct nlattr *twt_param_attr)
|
||||
{
|
||||
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
struct hdd_station_ctx *hdd_sta_ctx = NULL;
|
||||
struct wmi_twt_add_dialog_param params = {0};
|
||||
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;
|
||||
}
|
||||
|
||||
if (hdd_is_roaming_in_progress(hdd_ctx))
|
||||
return -EBUSY;
|
||||
|
||||
qdf_mem_copy(params.peer_macaddr,
|
||||
hdd_sta_ctx->conn_info.bssid.bytes,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
@@ -2014,6 +2022,125 @@ hdd_send_twt_resume_dialog_cmd(struct hdd_context *hdd_ctx,
|
||||
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
|
||||
* 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;
|
||||
twt_oper_attr = tb[id];
|
||||
twt_oper = nla_get_u8(twt_oper_attr);
|
||||
|
||||
if (!twt_oper_attr) {
|
||||
hdd_err("TWT parameters NOT specified");
|
||||
hdd_err("TWT operation NOT specified");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
id = QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS;
|
||||
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");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
twt_oper = nla_get_u8(twt_oper_attr);
|
||||
hdd_debug("twt: TWT Operation 0x%x", twt_oper);
|
||||
hdd_debug("TWT Operation 0x%x", twt_oper);
|
||||
|
||||
switch (twt_oper) {
|
||||
case QCA_WLAN_TWT_SET:
|
||||
@@ -2150,6 +2278,9 @@ static int hdd_twt_configure(struct hdd_adapter *adapter,
|
||||
case QCA_WLAN_TWT_NUDGE:
|
||||
ret = hdd_twt_nudge_session(adapter, twt_param_attr);
|
||||
break;
|
||||
case QCA_WLAN_TWT_GET_CAPABILITIES:
|
||||
ret = hdd_twt_get_capabilities(adapter, twt_param_attr);
|
||||
break;
|
||||
default:
|
||||
hdd_err("Invalid TWT Operation");
|
||||
ret = -EINVAL;
|
||||
@@ -2204,6 +2335,7 @@ __wlan_hdd_cfg80211_wifi_twt_config(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
errno = hdd_twt_configure(adapter, tb);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur