wlan: Send ARP at lowest rate and using WQ5

ARP are sent on last RA data rate.

Instead send ARP at lowest phy rate and use WQ5.

Change-Id: Ic7cda54579a83cc0c7e407f56852cb63f29a347f
CRs-Fixed: 646276
diff --git a/CORE/HDD/inc/wlan_hdd_tx_rx.h b/CORE/HDD/inc/wlan_hdd_tx_rx.h
index 58f85c6..4907b97 100644
--- a/CORE/HDD/inc/wlan_hdd_tx_rx.h
+++ b/CORE/HDD/inc/wlan_hdd_tx_rx.h
@@ -52,6 +52,8 @@
 #ifdef FEATURE_WLAN_WAPI
 #define HDD_ETHERTYPE_WAI                  ( 0x88b4 )
 #endif
+#define HDD_ETHERTYPE_ARP                  ( 0x0806 )
+#define HDD_ETHERTYPE_ARP_SIZE               42
 
 #define HDD_80211_HEADER_LEN      24
 #define HDD_80211_HEADER_QOS_CTL  2
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index 980a7fe..966c016 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -1046,9 +1046,10 @@
     
     vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET,
                           &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );
-    if (VOS_IS_STATUS_SUCCESS( vosStatus ) )
+    if ( VOS_IS_STATUS_SUCCESS( vosStatus ) )
     {
-       if (pBuffer && vos_be16_to_cpu( *(unsigned short*)pBuffer ) == HDD_ETHERTYPE_802_1_X )
+       if ( pBuffer && *(unsigned short*)pBuffer ==
+                             vos_cpu_to_be16(HDD_ETHERTYPE_802_1_X) )
        {
           fEAPOL = VOS_TRUE;
        }
@@ -1057,6 +1058,35 @@
    return fEAPOL;
 }
 
+/**============================================================================
+  @brief hdd_IsARP() - Checks the packet is ARP or not.
+
+  @param pVosPacket : [in] pointer to vos packet
+  @return         : VOS_TRUE if the packet is ARP
+                  : VOS_FALSE otherwise
+  ===========================================================================*/
+
+v_BOOL_t hdd_IsARP( vos_pkt_t *pVosPacket )
+{
+    VOS_STATUS vosStatus  = VOS_STATUS_SUCCESS;
+    v_BOOL_t   fIsARP     = VOS_FALSE;
+    void       *pBuffer   = NULL;
+
+
+    vosStatus = vos_pkt_peek_data( pVosPacket,
+                           (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET,
+                          &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE );
+    if ( VOS_IS_STATUS_SUCCESS( vosStatus ) )
+    {
+       if ( pBuffer && *(unsigned short*)pBuffer ==
+                                 vos_cpu_to_be16(HDD_ETHERTYPE_ARP) )
+       {
+          fIsARP = VOS_TRUE;
+       }
+    }
+
+   return fIsARP;
+}
 
 #ifdef FEATURE_WLAN_WAPI // Need to update this function
 /**============================================================================
@@ -1079,7 +1109,8 @@
 
     if (VOS_IS_STATUS_SUCCESS( vosStatus ) )
     {
-       if (pBuffer && vos_be16_to_cpu( *((unsigned short*)pBuffer)) == HDD_ETHERTYPE_WAI)
+       if ( pBuffer && *(unsigned short*)pBuffer ==
+                               vos_cpu_to_be16(HDD_ETHERTYPE_WAI) )
        {
           fIsWAI = VOS_TRUE;
        }
@@ -1187,6 +1218,7 @@
    v_TIME_t timestamp;
    WLANTL_ACEnumType newAc;
    v_SIZE_t size = 0;
+   v_U16_t packet_size;
    tANI_U8   acAdmitted, i;
    v_U8_t proto_type = 0;
 
@@ -1388,6 +1420,10 @@
       }
    }
 
+   vos_pkt_get_packet_length( pVosPacket,&packet_size );
+   if( HDD_ETHERTYPE_ARP_SIZE == packet_size )
+      pPktMetaInfo->ucIsArp = hdd_IsARP( pVosPacket ) ? 1 : 0;
+
 #ifdef FEATURE_WLAN_WAPI
    // Override usIsEapol value when its zero for WAPI case
       pPktMetaInfo->ucIsWai = hdd_IsWAIPacket( pVosPacket ) ? 1 : 0;
diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h
index 33fe42d..e0d54cf 100644
--- a/CORE/TL/inc/wlan_qct_tl.h
+++ b/CORE/TL/inc/wlan_qct_tl.h
@@ -407,6 +407,8 @@
 
   /* STA has more packets to send */
   v_BOOL_t  bMorePackets;
+  /* notifying TL if this is an ARP frame or not */
+  v_U8_t    ucIsArp;
 }WLANTL_MetaInfoType;
 
 /*---------------------------------------------------------------------------
diff --git a/CORE/TL/src/wlan_qct_tl.c b/CORE/TL/src/wlan_qct_tl.c
index cffc7f5..76ff134 100644
--- a/CORE/TL/src/wlan_qct_tl.c
+++ b/CORE/TL/src/wlan_qct_tl.c
@@ -7404,6 +7404,12 @@
     ucTxFlag = ucTxFlag | HAL_TDLS_PEER_STA_MASK;
   }
 #endif /* FEATURE_WLAN_TDLS */
+  if( tlMetaInfo.ucIsArp )
+  {
+    /*Send ARP at lowest Phy rate and through WQ5 */
+    ucTxFlag |= HAL_USE_BD_RATE_MASK;
+    ucTxFlag |= HAL_USE_FW_IN_TX_PATH;
+  }
 
   vosStatus = (VOS_STATUS)WDA_DS_BuildTxPacketInfo( pvosGCtx, 
                      vosDataBuff , &vDestMacAddr,
diff --git a/CORE/WDA/inc/legacy/wlan_qct_hal.h b/CORE/WDA/inc/legacy/wlan_qct_hal.h
index d540589..f9263a9 100644
--- a/CORE/WDA/inc/legacy/wlan_qct_hal.h
+++ b/CORE/WDA/inc/legacy/wlan_qct_hal.h
@@ -338,6 +338,7 @@
 #define HAL_TDLS_PEER_STA_MASK              0x80 //bit 7 set for TDLS peer station 
 #endif
 
+#define HAL_USE_BD_RATE_MASK                0x1000
 #define HAL_USE_FW_IN_TX_PATH               0x200 //bit 9 to send via WQ5
 /*==========================================================================
 
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h b/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
index 4bceaee..fcffa68 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_dp.h
@@ -117,7 +117,7 @@
 
 #define WDI_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames
 
-
+#define WDI_USE_BD_RATE_MASK              0x1000
 #define WDI_USE_FW_IN_TX_PATH             0x200 //bit 9 used to route the frames to Work Queue 5
 
 /*Macro for getting the size of the TX BD*/
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi_dp.c b/CORE/WDI/CP/src/wlan_qct_wdi_dp.c
index 91c9ed2..1b809f8 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi_dp.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi_dp.c
@@ -551,6 +551,12 @@
            pBd->bdRate = WDI_BDRATE_CTRL_FRAME;
         }
 #endif
+
+        if(ucTxFlag & WDI_USE_BD_RATE_MASK)
+        {
+            pBd->bdRate = WDI_BDRATE_BCDATA_FRAME;
+        }
+
         pBd->rmf    = WDI_RMF_DISABLED;     
 
         /* sanity: Might already be set by caller, but enforce it here again */