wlan: Add changes to collect Arp packet stats

Add changes to collect arp packet stats along
with existing hdd stats to debug the arp packet
related issues.

Change-Id: I3574d512744bcdd0021f8a57d2f9f70e1b154458
CRs-Fixed: 1115366
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index 9a42301..fad7736 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -819,6 +819,7 @@
    hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
    v_BOOL_t txSuspended = VOS_FALSE;
    struct sk_buff *skb1;
+   v_BOOL_t arp_pkt;
 
    if (NULL == pHddCtx) {
        VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
@@ -835,6 +836,15 @@
        return NETDEV_TX_BUSY;
    }
 
+   arp_pkt = vos_is_arp_pkt(skb, false);
+
+   if (arp_pkt)
+   {
+       ++pAdapter->hdd_stats.hddArpStats.txCount;
+       VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                 "%s :ARP packet received form net_dev", __func__);
+   }
+
    //Get TL Q index corresponding to Qdisc queue index/AC.
    qid = hdd_QdiscAcToTlAC[skb->queue_mapping];
    ac  = qid;
@@ -852,6 +862,15 @@
          VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO,
                 FL("Tx frame in not associated state in %d context"),
                     pAdapter->device_mode);
+
+         if (arp_pkt)
+         {
+            ++pAdapter->hdd_stats.hddArpStats.txDropped;
+            pAdapter->hdd_stats.hddArpStats.reason = HDD_TX_FRAME_IN_NOT_ASSOCIATED_STATE;
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+            "%s :Tx frame in not associated state, ARP packet Dropped ",
+            __func__);
+         }
          ++pAdapter->stats.tx_dropped;
          ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
          ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
@@ -895,6 +914,15 @@
          VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                     "%s: WLANTL_STAPktPending() returned error code %d",
                     __func__, status);
+
+         if (arp_pkt)
+         {
+            ++pAdapter->hdd_stats.hddArpStats.txDropped;
+            pAdapter->hdd_stats.hddArpStats.reason = HDD_WLANTL_STAPKTPENDING_RETURNED_ERROR_CODE;
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+            "%s:ARP Packet Dropped WLANTL_STAPktPending returned error %d",
+            __func__, status);
+         }
          ++pAdapter->stats.tx_dropped;
          ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
          ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
@@ -984,6 +1012,14 @@
    if ( !VOS_IS_STATUS_SUCCESS( status ) )
    {
       VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s:Insert Tx queue failed. Pkt dropped", __func__);
+
+      if (arp_pkt)
+      {
+          ++pAdapter->hdd_stats.hddArpStats.txDropped;
+          pAdapter->hdd_stats.hddArpStats.reason = HDD_INSERT_TX_QUEUE_FAILED;
+          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                    "%s:Insert Tx queue failed. ARP packet dropped", __func__);
+      }
       ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
       ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
       ++pAdapter->stats.tx_dropped;
@@ -1045,6 +1081,15 @@
             skb1 = pktNode->skb;
             kfree_skb(skb1);
          }
+
+         if (arp_pkt)
+         {
+           ++pAdapter->hdd_stats.hddArpStats.txDropped;
+           pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILED_TO_SIGNAL_TL;
+           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+           "%s: ARP packet Dropped : Failed to signal TL for QId=%d",
+           __func__, qid );
+         }
          ++pAdapter->stats.tx_dropped;
          ++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
          ++pAdapter->hdd_stats.hddTxRxStats.txXmitDroppedAC[qid];
@@ -1956,6 +2001,7 @@
    tANI_U8   acAdmitted, i;
    v_U8_t proto_type = 0;
    WLANTL_ACEnumType actualAC;
+   v_BOOL_t arp_pkt;
 
    //Sanity check on inputs
    if ( ( NULL == vosContext ) || 
@@ -2093,10 +2139,20 @@
       vos_pkt_return_packet(pVosPacket);
       return VOS_STATUS_E_FAILURE;
    }
+   arp_pkt = vos_is_arp_pkt(skb, false);
    //Attach skb to VOS packet.
    status = vos_pkt_set_os_packet( pVosPacket, skb );
    if (status != VOS_STATUS_SUCCESS)
    {
+
+      if (arp_pkt)
+      {
+          ++pAdapter->hdd_stats.hddArpStats.txDropped;
+          pAdapter->hdd_stats.hddArpStats.reason = HDD_ERROR_ATTACHING_SKB;
+          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                 "%s :Error attaching skb,ARP packet droped", __func__);
+      }
+
       VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: Error attaching skb", __func__);
       vos_pkt_return_packet(pVosPacket);
       ++pAdapter->stats.tx_dropped;
@@ -2108,6 +2164,16 @@
    //Just being paranoid. To be removed later
    if(pVosPacket == NULL)
    {
+
+      if (arp_pkt)
+      {
+          ++pAdapter->hdd_stats.hddArpStats.txDropped;
+          pAdapter->hdd_stats.hddArpStats.reason = HDD_VOS_PACKET_RETURNED_BY_VOSS_IS_NULL;
+          VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+          "%s :VOS packet returned by VOSS is NULL,ARP packet droped",
+          __func__);
+      }
+
       VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,"%s: VOS packet returned by VOSS is NULL", __func__);
       ++pAdapter->stats.tx_dropped;
       ++pAdapter->hdd_stats.hddTxRxStats.txFetchDequeueError;
@@ -2166,6 +2232,12 @@
    if( HDD_ETHERTYPE_ARP_SIZE == packet_size )
       pPktMetaInfo->ucIsArp = hdd_IsARP( pVosPacket ) ? 1 : 0;
 
+   if(pPktMetaInfo->ucIsArp)
+   {
+      VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                 "%s :STA TX ARP Received in TL ",__func__);
+   }
+
 #ifdef FEATURE_WLAN_WAPI
    // Override usIsEapol value when its zero for WAPI case
    pPktMetaInfo->ucIsWai = hdd_IsWAIPacket( pVosPacket ) ? 1 : 0;
@@ -2587,6 +2659,7 @@
    vos_pkt_t* pVosPacket;
    vos_pkt_t* pNextVosPacket;
    v_U8_t proto_type = 0;
+   v_BOOL_t arp_pkt;
 
    //Sanity check on inputs
    if ( ( NULL == vosContext ) || 
@@ -2627,6 +2700,14 @@
       // both "success" and "empty" are acceptable results
       if (!((status == VOS_STATUS_SUCCESS) || (status == VOS_STATUS_E_EMPTY)))
       {
+
+        if(hdd_IsARP(pVosPacket))
+        {
+            ++pAdapter->hdd_stats.hddArpStats.rxDropped;
+            pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILURE_WALKING_PACKET_CHAIN;
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+            "%s: ARP packet Drop: Failure walking packet chain", __func__);
+        }
          ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
          VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                          "%s: Failure walking packet chain", __func__);
@@ -2637,6 +2718,15 @@
       status = vos_pkt_get_os_packet( pVosPacket, (v_VOID_t **)&skb, VOS_FALSE );
       if(!VOS_IS_STATUS_SUCCESS( status ))
       {
+
+        if(hdd_IsARP(pVosPacket))
+        {
+            ++pAdapter->hdd_stats.hddArpStats.rxDropped;
+            pAdapter->hdd_stats.hddArpStats.reason = HDD_FAILURE_EXTRACTING_SKB_FROM_VOS_PKT;
+            VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+             "%s: ARP packet Dropped: Failure extracting skb from vos pkt",
+             __func__);
+        }
          ++pAdapter->hdd_stats.hddTxRxStats.rxDropped;
          VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_ERROR,
                                 "%s: Failure extracting skb from vos pkt", __func__);
@@ -2698,6 +2788,15 @@
          }
       }
 
+      arp_pkt = vos_is_arp_pkt(skb, false);
+
+      if (arp_pkt)
+      {
+         ++pAdapter->hdd_stats.hddArpStats.rxCount;
+         VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                   "%s :STA RX ARP received",__func__);
+      }
+
       if (pHddCtx->rx_wow_dump) {
           if (!(VOS_PKT_PROTO_TYPE_ARP & proto_type) &&
               !(VOS_PKT_PROTO_TYPE_EAPOL & proto_type))
@@ -2737,11 +2836,28 @@
 
       if (NET_RX_SUCCESS == rxstat)
       {
+
+        if (arp_pkt)
+        {
+           ++pAdapter->hdd_stats.hddArpStats.rxDelivered;
+           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+                     "STA RX ARP packet Delivered to net stack");
+        }
+
          ++pAdapter->hdd_stats.hddTxRxStats.rxDelivered;
          ++pAdapter->hdd_stats.hddTxRxStats.pkt_rx_count;
       }
       else
       {
+
+        if (arp_pkt)
+        {
+           ++pAdapter->hdd_stats.hddArpStats.rxRefused;
+           pAdapter->hdd_stats.hddArpStats.reason = HDD_STA_RX_ARP_PACKET_REFUSED_IN_NET_STACK;
+           VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+                     "%s :STA RX ARP packet Refused in net stack", __func__);
+        }
+
          ++pAdapter->hdd_stats.hddTxRxStats.rxRefused;
       }
       // now process the next packet in the chain