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
このコミットが含まれているのは:
Sravan Kumar Kairam
2017-02-24 12:27:27 +05:30
committed by snandini
コミット c1ae71c4cd
7個のファイルの変更158行の追加14行の削除

ファイルの表示

@@ -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. * 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; 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 */ #endif /* if !defined __CDS_API_H */

ファイルの表示

@@ -2769,3 +2769,71 @@ cds_print_htc_credit_history(uint32_t count, qdf_abstract_print *print,
print, print_priv); print, print_priv);
} }
#endif #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++;
}

ファイルの表示

@@ -629,6 +629,26 @@ static inline void ol_tx_timestamp(ol_txrx_pdev_handle pdev,
} }
#endif #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 * WARNING: ol_tx_inspect_handler()'s bahavior is similar to that of
* ol_tx_completion_handler(). * 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); 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) { if (tx_desc->pkt_type != OL_TX_FRM_TSO) {
packetdump_cb = pdev->ol_tx_packetdump_cb; packetdump_cb = pdev->ol_tx_packetdump_cb;
if (packetdump_cb) if (packetdump_cb)

ファイルの表示

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

ファイルの表示

@@ -12508,6 +12508,7 @@ static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
} }
arp_stats_params.flag = true; arp_stats_params.flag = true;
arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]); arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
} else { } else {
arp_stats_params.flag = false; 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, 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, nla_put_u16(skb, COUNT_TO_LOWER_MAC,
adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent) || adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent) ||
nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC, 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, nla_put_u16(skb, COUNT_TX_SUCCESS,
adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt) || adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt) ||
nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC, nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt) || adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt) ||
nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC, 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, nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
adapter->hdd_stats.hdd_arp_stats.rx_delivered) || adapter->hdd_stats.hdd_arp_stats.rx_delivered) ||
nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP, 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) if (adapter->dad)
nla_put_flag(skb, AP_LINK_DAD); nla_put_flag(skb, AP_LINK_DAD);
hdd_ctx->track_arp_ip = 0;
cfg80211_vendor_cmd_reply(skb); cfg80211_vendor_cmd_reply(skb);
return err; return err;
} }

ファイルの表示

@@ -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", hdd_notice("rsp->ba_session_establishment_status :%x",
rsp->ba_session_establishment_status); 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.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->dad |= rsp->dad_detected;
adapter->con_status = rsp->connect_status; adapter->con_status = rsp->connect_status;

ファイルの表示

@@ -582,8 +582,9 @@ static int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
bool pkt_proto_logged = false; bool pkt_proto_logged = false;
#ifdef QCA_PKT_PROTO_TRACE #ifdef QCA_PKT_PROTO_TRACE
uint8_t proto_type = 0; uint8_t proto_type = 0;
#endif
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
#endif /* QCA_PKT_PROTO_TRACE */ bool is_arp;
#ifdef QCA_WIFI_FTM #ifdef QCA_WIFI_FTM
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { 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_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; 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]; ++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
goto drop_pkt_and_release_skb; goto drop_pkt_and_release_skb;
} }
netif_trans_update(dev); netif_trans_update(dev);
return NETDEV_TX_OK; return NETDEV_TX_OK;
@@ -812,6 +829,11 @@ drop_pkt_accounting:
++adapter->stats.tx_dropped; ++adapter->stats.tx_dropped;
++adapter->hdd_stats.tx_rx_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; 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; struct qdf_mac_addr *mac_addr;
bool wake_lock = false; bool wake_lock = false;
bool proto_pkt_logged = false; bool proto_pkt_logged = false;
bool track_arp = false;
/* Sanity check on inputs */ /* Sanity check on inputs */
if (unlikely((NULL == context) || (NULL == rxBuf))) { 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, QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
"%s: skb %pK skb->len %d\n", __func__, skb, skb->len); "%s: skb %pK skb->len %d\n", __func__, skb, skb->len);
#endif #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); sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
if ((sta_ctx->conn_info.proxyARPService) && if ((sta_ctx->conn_info.proxyARPService) &&
@@ -1360,15 +1397,25 @@ QDF_STATUS hdd_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
else else
rxstat = netif_rx_ni(skb); rxstat = netif_rx_ni(skb);
if (NET_RX_SUCCESS == rxstat) if (NET_RX_SUCCESS == rxstat) {
++adapter->hdd_stats.tx_rx_stats. ++adapter->hdd_stats.tx_rx_stats.
rx_delivered[cpu_index]; rx_delivered[cpu_index];
else if (track_arp)
++adapter->hdd_stats.hdd_arp_stats.
rx_delivered;
} else {
++adapter->hdd_stats.tx_rx_stats. ++adapter->hdd_stats.tx_rx_stats.
rx_refused[cpu_index]; rx_refused[cpu_index];
if (track_arp)
++adapter->hdd_stats.hdd_arp_stats.
rx_refused;
}
} else { } else {
++adapter->hdd_stats.tx_rx_stats. ++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;
} }
} }