qcacld-3.0: Get deleted remote station info in SAP case
Add support to get information of deleted station in case of SAP. Change-Id: Id61ae1b36b923898237d55aa8c57d2e49815c8af CRs-Fixed: 2126240
This commit is contained in:

committed by
snandini

parent
2e01abcc20
commit
f79fbdfd01
@@ -815,7 +815,7 @@ struct hdd_station_info {
|
||||
bool sgi_enable;
|
||||
bool tx_stbc;
|
||||
bool rx_stbc;
|
||||
uint8_t ch_width;
|
||||
tSirMacHTChannelWidth ch_width;
|
||||
uint8_t mode;
|
||||
uint8_t max_supp_idx;
|
||||
uint8_t max_ext_idx;
|
||||
|
@@ -4960,32 +4960,384 @@ static inline int32_t remote_station_put_u64(struct sk_buff *skb,
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hdd_get_station_remote() - get remote peer's info
|
||||
* hdd_add_survey_info_sap_get_len - get data length used in
|
||||
* hdd_add_survey_info_sap()
|
||||
*
|
||||
* This function calculates the data length used in hdd_add_survey_info_sap()
|
||||
*
|
||||
* Return: total data length used in hdd_add_survey_info_sap()
|
||||
*/
|
||||
static uint32_t hdd_add_survey_info_sap_get_len(void)
|
||||
{
|
||||
return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_survey_info - add survey info attribute
|
||||
* @skb: pointer to response skb buffer
|
||||
* @stainfo: station information
|
||||
* @idx: attribute type index for nla_next_start()
|
||||
*
|
||||
* This function adds survey info attribute to response skb buffer
|
||||
*
|
||||
* Return : 0 on success and errno on failure
|
||||
*/
|
||||
static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
|
||||
struct hdd_station_info *stainfo,
|
||||
int idx)
|
||||
{
|
||||
struct nlattr *nla_attr;
|
||||
|
||||
nla_attr = nla_nest_start(skb, idx);
|
||||
if (!nla_attr)
|
||||
goto fail;
|
||||
if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
|
||||
stainfo->freq)) {
|
||||
hdd_err("put fail");
|
||||
goto fail;
|
||||
}
|
||||
nla_nest_end(skb, nla_attr);
|
||||
return 0;
|
||||
fail:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_tx_bitrate_sap_get_len - get data length used in
|
||||
* hdd_add_tx_bitrate_sap()
|
||||
*
|
||||
* This function calculates the data length used in hdd_add_tx_bitrate_sap()
|
||||
*
|
||||
* Return: total data length used in hdd_add_tx_bitrate_sap()
|
||||
*/
|
||||
static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
|
||||
{
|
||||
return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_tx_bitrate_sap - add vhs nss info attribute
|
||||
* @skb: pointer to response skb buffer
|
||||
* @stainfo: station information
|
||||
* @idx: attribute type index for nla_next_start()
|
||||
*
|
||||
* This function adds vht nss attribute to response skb buffer
|
||||
*
|
||||
* Return : 0 on success and errno on failure
|
||||
*/
|
||||
static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
|
||||
struct hdd_station_info *stainfo,
|
||||
int idx)
|
||||
{
|
||||
struct nlattr *nla_attr;
|
||||
|
||||
nla_attr = nla_nest_start(skb, idx);
|
||||
if (!nla_attr)
|
||||
goto fail;
|
||||
|
||||
if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
|
||||
stainfo->nss)) {
|
||||
hdd_err("put fail");
|
||||
goto fail;
|
||||
}
|
||||
nla_nest_end(skb, nla_attr);
|
||||
return 0;
|
||||
fail:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_sta_info_sap_get_len - get data length used in
|
||||
* hdd_add_sta_info_sap()
|
||||
*
|
||||
* This function calculates the data length used in hdd_add_sta_info_sap()
|
||||
*
|
||||
* Return: total data length used in hdd_add_sta_info_sap()
|
||||
*/
|
||||
static uint32_t hdd_add_sta_info_sap_get_len(void)
|
||||
{
|
||||
return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
|
||||
hdd_add_tx_bitrate_sap_get_len());
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_sta_info_sap - add sta signal info attribute
|
||||
* @skb: pointer to response skb buffer
|
||||
* @stainfo: station information
|
||||
* @idx: attribute type index for nla_next_start()
|
||||
*
|
||||
* This function adds sta signal attribute to response skb buffer
|
||||
*
|
||||
* Return : 0 on success and errno on failure
|
||||
*/
|
||||
static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
|
||||
struct hdd_station_info *stainfo, int idx)
|
||||
{
|
||||
struct nlattr *nla_attr;
|
||||
|
||||
nla_attr = nla_nest_start(skb, idx);
|
||||
if (!nla_attr)
|
||||
goto fail;
|
||||
|
||||
if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, rssi)) {
|
||||
hdd_err("put fail");
|
||||
goto fail;
|
||||
}
|
||||
if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE))
|
||||
goto fail;
|
||||
|
||||
nla_nest_end(skb, nla_attr);
|
||||
return 0;
|
||||
fail:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_link_standard_info_sap_get_len - get data length used in
|
||||
* hdd_add_link_standard_info_sap()
|
||||
*
|
||||
* This function calculates the data length used in
|
||||
* hdd_add_link_standard_info_sap()
|
||||
*
|
||||
* Return: total data length used in hdd_add_link_standard_info_sap()
|
||||
*/
|
||||
static uint32_t hdd_add_link_standard_info_sap_get_len(void)
|
||||
{
|
||||
return ((NLA_HDRLEN) +
|
||||
hdd_add_survey_info_sap_get_len() +
|
||||
hdd_add_sta_info_sap_get_len() +
|
||||
(sizeof(uint32_t) + NLA_HDRLEN));
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_link_standard_info_sap - add add link info attribut
|
||||
* @skb: pointer to response skb buffer
|
||||
* @stainfo: station information
|
||||
* @idx: attribute type index for nla_next_start()
|
||||
*
|
||||
* This function adds link info attribut to response skb buffer
|
||||
*
|
||||
* Return : 0 on success and errno on failure
|
||||
*/
|
||||
static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
|
||||
struct hdd_station_info *stainfo,
|
||||
int idx)
|
||||
{
|
||||
struct nlattr *nla_attr;
|
||||
|
||||
nla_attr = nla_nest_start(skb, idx);
|
||||
if (!nla_attr)
|
||||
goto fail;
|
||||
if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
|
||||
goto fail;
|
||||
if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
|
||||
goto fail;
|
||||
|
||||
if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
|
||||
hdd_err("Reason code put fail");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
nla_nest_end(skb, nla_attr);
|
||||
return 0;
|
||||
fail:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_ap_standard_info_sap_get_len - get data length used in
|
||||
* hdd_add_ap_standard_info_sap()
|
||||
* @stainfo: station information
|
||||
*
|
||||
* This function calculates the data length used in
|
||||
* hdd_add_ap_standard_info_sap()
|
||||
*
|
||||
* Return: total data length used in hdd_add_ap_standard_info_sap()
|
||||
*/
|
||||
static uint32_t hdd_add_ap_standard_info_sap_get_len(
|
||||
struct hdd_station_info *stainfo)
|
||||
{
|
||||
uint32_t len;
|
||||
|
||||
len = NLA_HDRLEN;
|
||||
if (stainfo->vht_present)
|
||||
len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
|
||||
if (stainfo->ht_present)
|
||||
len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_add_ap_standard_info_sap - add HT and VHT info attributes
|
||||
* @skb: pointer to response skb buffer
|
||||
* @stainfo: station information
|
||||
* @idx: attribute type index for nla_next_start()
|
||||
*
|
||||
* This function adds HT and VHT info attributes to response skb buffer
|
||||
*
|
||||
* Return : 0 on success and errno on failure
|
||||
*/
|
||||
static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
|
||||
struct hdd_station_info *stainfo,
|
||||
int idx)
|
||||
{
|
||||
struct nlattr *nla_attr;
|
||||
|
||||
nla_attr = nla_nest_start(skb, idx);
|
||||
if (!nla_attr)
|
||||
goto fail;
|
||||
|
||||
if (stainfo->vht_present) {
|
||||
if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
|
||||
sizeof(stainfo->vht_caps),
|
||||
&stainfo->vht_caps)) {
|
||||
hdd_err("put fail");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (stainfo->ht_present) {
|
||||
if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
|
||||
sizeof(stainfo->ht_caps),
|
||||
&stainfo->ht_caps)) {
|
||||
hdd_err("put fail");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
nla_nest_end(skb, nla_attr);
|
||||
return 0;
|
||||
fail:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_decode_ch_width - decode channel band width based
|
||||
* @ch_width: encoded enum value holding channel band width
|
||||
*
|
||||
* This function decodes channel band width from the given encoded enum value.
|
||||
*
|
||||
* Returns: decoded channel band width.
|
||||
*/
|
||||
static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
|
||||
{
|
||||
switch (ch_width) {
|
||||
case 0:
|
||||
return 20;
|
||||
case 1:
|
||||
return 40;
|
||||
case 2:
|
||||
return 80;
|
||||
case 3:
|
||||
case 4:
|
||||
return 160;
|
||||
default:
|
||||
hdd_debug("invalid enum: %d", ch_width);
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_get_cached_station_remote() - get cached(deleted) peer's info
|
||||
* @hdd_ctx: hdd context
|
||||
* @adapter: hostapd interface
|
||||
* @mac_addr: mac address of requested peer
|
||||
*
|
||||
* This function collect and indicate the remote peer's info
|
||||
* This function collect and indicate the cached(deleted) peer's info
|
||||
*
|
||||
* Return: 0 on success, otherwise error value
|
||||
*/
|
||||
static int hdd_get_station_remote(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr)
|
||||
|
||||
static int hdd_get_cached_station_remote(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr)
|
||||
{
|
||||
struct hdd_station_info *stainfo = hdd_get_stainfo(adapter->sta_info,
|
||||
mac_addr);
|
||||
struct hdd_station_info *stainfo = hdd_get_stainfo(
|
||||
adapter->cache_sta_info,
|
||||
mac_addr);
|
||||
struct sk_buff *skb = NULL;
|
||||
struct sir_peer_info_ext peer_info;
|
||||
uint32_t nl_buf_len;
|
||||
bool txrx_rate = true;
|
||||
uint32_t nl_buf_len = NLMSG_HDRLEN;
|
||||
uint8_t channel_width;
|
||||
|
||||
if (!stainfo) {
|
||||
hdd_err("peer " MAC_ADDRESS_STR " not found",
|
||||
MAC_ADDR_ARRAY(mac_addr.bytes));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nl_buf_len += hdd_add_link_standard_info_sap_get_len() +
|
||||
hdd_add_ap_standard_info_sap_get_len(stainfo) +
|
||||
(sizeof(stainfo->mode) + NLA_HDRLEN) +
|
||||
(sizeof(stainfo->ch_width) + NLA_HDRLEN) +
|
||||
(sizeof(stainfo->tx_rate) + NLA_HDRLEN) +
|
||||
(sizeof(stainfo->rx_rate) + NLA_HDRLEN);
|
||||
|
||||
skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
|
||||
if (!skb) {
|
||||
hdd_err(FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
|
||||
LINK_INFO_STANDARD_NL80211_ATTR)) {
|
||||
hdd_err("link standard put fail");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hdd_add_ap_standard_info_sap(skb, stainfo,
|
||||
AP_INFO_STANDARD_NL80211_ATTR)) {
|
||||
hdd_err("ap standard put fail");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* upper layer expects decoded channel BW */
|
||||
channel_width = hdd_decode_ch_width(stainfo->ch_width);
|
||||
|
||||
if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE,
|
||||
hdd_convert_dot11mode(
|
||||
stainfo->mode)) ||
|
||||
nla_put_u8(skb, REMOTE_CH_WIDTH, channel_width)) {
|
||||
hdd_err("remote ch put fail");
|
||||
goto fail;
|
||||
}
|
||||
if (nla_put_u32(skb, REMOTE_LAST_TX_RATE, stainfo->tx_rate)) {
|
||||
hdd_err("tx rate put fail");
|
||||
goto fail;
|
||||
}
|
||||
if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, stainfo->rx_rate)) {
|
||||
hdd_err("rx rate put fail");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
qdf_mem_zero(stainfo, sizeof(*stainfo));
|
||||
|
||||
return cfg80211_vendor_cmd_reply(skb);
|
||||
fail:
|
||||
if (skb)
|
||||
kfree_skb(skb);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_get_cached_station_remote() - get connected peer's info
|
||||
* @hdd_ctx: hdd context
|
||||
* @adapter: hostapd interface
|
||||
* @mac_addr: mac address of requested peer
|
||||
*
|
||||
* This function collect and indicate the connected peer's info
|
||||
*
|
||||
* Return: 0 on success, otherwise error value
|
||||
*/
|
||||
static int hdd_get_connected_station_info(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr,
|
||||
struct hdd_station_info *stainfo)
|
||||
{
|
||||
struct sk_buff *skb = NULL;
|
||||
uint32_t nl_buf_len;
|
||||
struct sir_peer_info_ext peer_info;
|
||||
bool txrx_rate = true;
|
||||
|
||||
nl_buf_len = NLMSG_HDRLEN;
|
||||
nl_buf_len += (sizeof(stainfo->max_phy_rate) + NLA_HDRLEN) +
|
||||
(sizeof(stainfo->tx_packets) + NLA_HDRLEN) +
|
||||
@@ -5082,6 +5434,43 @@ fail:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_get_station_remote() - get remote peer's info
|
||||
* @hdd_ctx: hdd context
|
||||
* @adapter: hostapd interface
|
||||
* @mac_addr: mac address of requested peer
|
||||
*
|
||||
* This function collect and indicate the remote peer's info
|
||||
*
|
||||
* Return: 0 on success, otherwise error value
|
||||
*/
|
||||
static int hdd_get_station_remote(struct hdd_context *hdd_ctx,
|
||||
struct hdd_adapter *adapter,
|
||||
struct qdf_mac_addr mac_addr)
|
||||
{
|
||||
struct hdd_station_info *stainfo = hdd_get_stainfo(adapter->sta_info,
|
||||
mac_addr);
|
||||
int status = 0;
|
||||
bool is_associated = false;
|
||||
|
||||
if (!stainfo) {
|
||||
status = hdd_get_cached_station_remote(hdd_ctx, adapter,
|
||||
mac_addr);
|
||||
return status;
|
||||
}
|
||||
|
||||
is_associated = hdd_is_peer_associated(adapter, &mac_addr);
|
||||
if (!is_associated) {
|
||||
status = hdd_get_cached_station_remote(hdd_ctx, adapter,
|
||||
mac_addr);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = hdd_get_connected_station_info(hdd_ctx, adapter,
|
||||
mac_addr, stainfo);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
|
||||
* @wiphy: corestack handler
|
||||
|
Reference in New Issue
Block a user