qcacld-3.0: Add ARP debug stats

Change to collect arp packet stats along with
existing hdd stats to debug arp packet related
issues.

Change-Id: Idce70799bd3698dc8a8ecd8cfc8ef7d9bf1f5764
CRs-Fixed: 2019787
This commit is contained in:
Sravan Kumar Kairam 2017-02-24 12:27:27 +05:30 • committed by snandini
commit c1ae71c4cd
7 changed files with 158 additions and 14 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@ -565,4 +565,7 @@ bool cds_is_group_addr(uint8_t *mac_addr)
return false;
}
uint32_t cds_get_arp_stats_gw_ip(void);
void cds_incr_arp_stats_tx_tgt_delivered(void);
void cds_incr_arp_stats_tx_tgt_acked(void);
#endif /* if !defined __CDS_API_H */

View file

@ -2769,3 +2769,71 @@ cds_print_htc_credit_history(uint32_t count, qdf_abstract_print *print,
print, print_priv);
}
#endif
/**
* cds_get_arp_stats_gw_ip() - get arp stats track IP
*
* Return: ARP stats IP to track
*/
uint32_t cds_get_arp_stats_gw_ip(void)
{
struct hdd_context *hdd_ctx;
hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
if (!hdd_ctx) {
cds_err("Hdd Context is Null");
return 0;
}
return hdd_ctx->track_arp_ip;
}
/**
* cds_incr_arp_stats_tx_tgt_delivered() - increment ARP stats
*
* Return: none
*/
void cds_incr_arp_stats_tx_tgt_delivered(void)
{
struct hdd_context *hdd_ctx;
struct hdd_adapter *adapter = NULL;
hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
if (!hdd_ctx) {
cds_err("Hdd Context is Null");
return;
}
hdd_for_each_adapter(hdd_ctx, adapter) {
if (QDF_STA_MODE == adapter->device_mode)
break;
}
if (adapter)
adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent++;
}
/**
* cds_incr_arp_stats_tx_tgt_acked() - increment ARP stats
*
* Return: none
*/
void cds_incr_arp_stats_tx_tgt_acked(void)
{
struct hdd_context *hdd_ctx;
struct hdd_adapter *adapter = NULL;
hdd_ctx = (struct hdd_context *) (gp_cds_context->pHDDContext);
if (!hdd_ctx) {
cds_err("Hdd Context is Null");
return;
}
hdd_for_each_adapter(hdd_ctx, adapter) {
if (QDF_STA_MODE == adapter->device_mode)
break;
}
if (adapter)
adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt++;
}

View file

@ -629,6 +629,26 @@ static inline void ol_tx_timestamp(ol_txrx_pdev_handle pdev,
}
#endif
/**
* ol_tx_update_arp_stats() - update ARP packet TX stats
* @netbuf: buffer
*
*
* Return: none
*/
static void ol_tx_update_arp_stats(qdf_nbuf_t netbuf,
enum htt_tx_status status)
{
uint32_t tgt_ip = cds_get_arp_stats_gw_ip();
if (tgt_ip == qdf_nbuf_get_arp_tgt_ip(netbuf)) {
if (status != htt_tx_status_download_fail)
cds_incr_arp_stats_tx_tgt_delivered();
if (status == htt_tx_status_ok)
cds_incr_arp_stats_tx_tgt_acked();
}
}
/**
* WARNING: ol_tx_inspect_handler()'s bahavior is similar to that of
* ol_tx_completion_handler().
@ -680,6 +700,12 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev,
QDF_NBUF_UPDATE_TX_PKT_COUNT(netbuf, QDF_NBUF_TX_PKT_FREE);
if (QDF_NBUF_CB_GET_PACKET_TYPE(netbuf) ==
QDF_NBUF_CB_PACKET_TYPE_ARP) {
if (qdf_nbuf_data_is_arp_req(netbuf))
ol_tx_update_arp_stats(netbuf, status);
}
if (tx_desc->pkt_type != OL_TX_FRM_TSO) {
packetdump_cb = pdev->ol_tx_packetdump_cb;
if (packetdump_cb)

View file

@ -478,15 +478,14 @@ struct hdd_pmf_stats {
#endif
struct hdd_arp_stats_s {
uint16_t tx_count;
uint16_t rx_count;
uint16_t tx_arp_req_count;
uint16_t rx_arp_rsp_count;
uint16_t tx_dropped;
uint16_t rx_dropped;
uint16_t rx_delivered;
uint16_t rx_refused;
uint16_t tx_host_fw_sent;
uint16_t rx_host_drop_reorder;
uint16_t tx_fw_cnt;
uint16_t rx_fw_cnt;
uint16_t tx_ack_cnt;
};
@ -1712,6 +1711,7 @@ struct hdd_context {
qdf_wake_lock_t monitor_mode_wakelock;
bool lte_coex_ant_share;
int sscan_pid;
uint32_t track_arp_ip;
};
/**

View file

@ -12508,6 +12508,7 @@ static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
}
arp_stats_params.flag = true;
arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
} else {
arp_stats_params.flag = false;
}
@ -12686,17 +12687,17 @@ static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
}
if (nla_put_u16(skb, COUNT_FROM_NETDEV,
adapter->hdd_stats.hdd_arp_stats.tx_count) ||
adapter->hdd_stats.hdd_arp_stats.tx_arp_req_count) ||
nla_put_u16(skb, COUNT_TO_LOWER_MAC,
adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent) ||
nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
adapter->hdd_stats.hdd_arp_stats.tx_fw_cnt) ||
adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent) ||
nla_put_u16(skb, COUNT_TX_SUCCESS,
adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt) ||
nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt) ||
nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
adapter->hdd_stats.hdd_arp_stats.rx_count) ||
adapter->hdd_stats.hdd_arp_stats.rx_arp_rsp_count) ||
nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
adapter->hdd_stats.hdd_arp_stats.rx_delivered) ||
nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
@ -12711,6 +12712,7 @@ static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
if (adapter->dad)
nla_put_flag(skb, AP_LINK_DAD);
hdd_ctx->track_arp_ip = 0;
cfg80211_vendor_cmd_reply(skb);
return err;
}

View file

@ -10648,9 +10648,7 @@ static void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp)
hdd_notice("rsp->ba_session_establishment_status :%x",
rsp->ba_session_establishment_status);
adapter->hdd_stats.hdd_arp_stats.tx_fw_cnt = rsp->arp_req_enqueue;
adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd;
adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt = rsp->arp_req_tx_success;
adapter->dad |= rsp->dad_detected;
adapter->con_status = rsp->connect_status;

View file

@ -582,8 +582,9 @@ static int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
bool pkt_proto_logged = false;
#ifdef QCA_PKT_PROTO_TRACE
uint8_t proto_type = 0;
#endif
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
#endif /* QCA_PKT_PROTO_TRACE */
bool is_arp;
#ifdef QCA_WIFI_FTM
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
@ -603,7 +604,22 @@ static int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
wlan_hdd_classify_pkt(skb);
wlan_hdd_latency_opt(adapter, skb);
if (QDF_NBUF_CB_GET_PACKET_TYPE(skb) == QDF_NBUF_CB_PACKET_TYPE_ARP) {
is_arp = true;
if (qdf_nbuf_data_is_arp_req(skb) &&
(hdd_ctx->track_arp_ip == qdf_nbuf_get_arp_tgt_ip(skb))) {
++adapter->hdd_stats.hdd_arp_stats.tx_arp_req_count;
QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
QDF_TRACE_LEVEL_INFO_HIGH,
"%s : ARP packet", __func__);
}
}
if (cds_is_driver_recovering()) {
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_WARN,
"Recovery in progress, dropping the packet");
goto drop_pkt;
}
STAId = HDD_WLAN_INVALID_STA_ID;
@ -785,6 +801,7 @@ static int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
goto drop_pkt_and_release_skb;
}
netif_trans_update(dev);
return NETDEV_TX_OK;
@ -812,6 +829,11 @@ drop_pkt_accounting:
++adapter->stats.tx_dropped;
++adapter->hdd_stats.tx_rx_stats.tx_dropped;
if (is_arp) {
++adapter->hdd_stats.hdd_arp_stats.tx_dropped;
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
"%s : ARP packet dropped", __func__);
}
return NETDEV_TX_OK;
}
@ -1226,6 +1248,7 @@ QDF_STATUS hdd_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
struct qdf_mac_addr *mac_addr;
bool wake_lock = false;
bool proto_pkt_logged = false;
bool track_arp = false;
/* Sanity check on inputs */
if (unlikely((NULL == context) || (NULL == rxBuf))) {
@ -1262,6 +1285,20 @@ QDF_STATUS hdd_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
"%s: skb %pK skb->len %d\n", __func__, skb, skb->len);
#endif
if (QDF_NBUF_CB_PACKET_TYPE_ARP ==
QDF_NBUF_CB_GET_PACKET_TYPE(skb)) {
if (qdf_nbuf_data_is_arp_rsp(skb) &&
(hdd_ctx->track_arp_ip ==
qdf_nbuf_get_arp_src_ip(skb))) {
++adapter->hdd_stats.hdd_arp_stats.
rx_arp_rsp_count;
QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
QDF_TRACE_LEVEL_INFO,
"%s: ARP packet received",
__func__);
track_arp = true;
}
}
sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
if ((sta_ctx->conn_info.proxyARPService) &&
@ -1360,15 +1397,25 @@ QDF_STATUS hdd_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
else
rxstat = netif_rx_ni(skb);
if (NET_RX_SUCCESS == rxstat)
if (NET_RX_SUCCESS == rxstat) {
++adapter->hdd_stats.tx_rx_stats.
rx_delivered[cpu_index];
else
if (track_arp)
++adapter->hdd_stats.hdd_arp_stats.
rx_delivered;
} else {
++adapter->hdd_stats.tx_rx_stats.
rx_refused[cpu_index];
if (track_arp)
++adapter->hdd_stats.hdd_arp_stats.
rx_refused;
}
} else {
++adapter->hdd_stats.tx_rx_stats.
rx_delivered[cpu_index];
rx_delivered[cpu_index];
if (track_arp)
++adapter->hdd_stats.hdd_arp_stats.
rx_delivered;
}
}