wlan: Add support to send beacon miss penalty count

Add vendor command support to set beacon miss penalty count
to firmware.

Change-Id: I81c9890988c479dbdee51c972bbaa658a99d8b8f
CRs-Fixed: 970725
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index dfd9250..3c2f719 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -1096,6 +1096,9 @@
     QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM,
     QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR,
     QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME,
+    QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT,
+    QCA_WLAN_VENDOR_ATTR_CONFIG_TX_RATE,
+    QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS,
     /* keep last */
     QCA_WLAN_VENDOR_ATTR_CONFIG_LAST,
     QCA_WLAN_VENDOR_ATTR_CONFIG_MAX =
@@ -1130,6 +1133,7 @@
 /* WIFI CONFIG Parameter defines */
 #define WIFI_CONFIG_SET_AVG_STATS_FACTOR 0x0001  /* Average stats factor */
 #define WIFI_CONFIG_SET_GUARD_TIME      0x0002  /* Guard Time */
+#define WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT 0x0001 /* BCNMISS_PENALTY_COUNT */
 
 /* Add more features here */
 enum qca_wlan_vendor_attr_set_no_dfs_flag
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index d175bc9..23c114d 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -7212,6 +7212,8 @@
 #define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
 #define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
 #define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
+#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
+        QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
 
 /**
  * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
@@ -7238,12 +7240,15 @@
     hdd_station_ctx_t *pHddStaCtx;
     struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
     tpSetWifiConfigParams pReq;
+    tModifyRoamParamsReqParams modifyRoamParamsReq;
     eHalStatus status;
     int ret_val;
     static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
                         [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
                         [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
-                       [PARAM_GUARD_TIME] = { .type = NLA_U32},
+                        [PARAM_GUARD_TIME] = { .type = NLA_U32},
+                        [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
+                                             { .type = NLA_U32},
     };
 
     ENTER();
@@ -7260,11 +7265,6 @@
 
     pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
 
-    if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
-                hddLog(LOGE, FL("Not in Connected state!"));
-                return -ENOTSUPP;
-    }
-
     if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
                hddLog(LOGE, FL("Invalid ATTR"));
                return -EINVAL;
@@ -7279,7 +7279,29 @@
         return -EINVAL;
     }
 
-   pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
+    if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
+        modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
+        modifyRoamParamsReq.value =
+        nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
+
+        if (eHAL_STATUS_SUCCESS !=
+                sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
+        {
+            hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
+            ret_val = -EINVAL;
+        }
+        return ret_val;
+    }
+
+    /* Moved this down in order to provide provision to set beacon
+     * miss penalty count irrespective of connection state.
+     */
+    if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
+                hddLog(LOGE, FL("Not in Connected state!"));
+                return -ENOTSUPP;
+    }
+
+    pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
 
     if (!pReq) {
       VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 47ca7fd..6399687 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -5865,4 +5865,10 @@
    tSirMacAddr  bssId;
 } tSetWifiConfigParams, *tpSetWifiConfigParams;
 
+typedef struct {
+   tANI_U8   param;
+   tANI_U32  value;
+} tModifyRoamParamsReqParams, * tpModifyRoamParamsReqParams;
+
+
 #endif /* __SIR_API_H */
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index f6f08fc..1bb4a91 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -738,6 +738,7 @@
 #define SIR_HAL_START_OEM_DATA_REQ_IND_NEW   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 281)
 #define SIR_HAL_START_OEM_DATA_RSP_IND_NEW   (SIR_HAL_ITC_MSG_TYPES_BEGIN + 282)
 #define SIR_HAL_ANTENNA_DIVERSITY_SELECTION_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 283)
+#define SIR_HAL_MODIFY_ROAM_PARAMS_IND     (SIR_HAL_ITC_MSG_TYPES_BEGIN + 284)
 #define SIR_HAL_MSG_TYPES_END              (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
 
 // CFG message types
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 8ee0d3c..d0f8341 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -3846,4 +3846,6 @@
                                       tCsrAntennaIndexCallback callback,
                                       void *pContext, tANI_U8 sessionId);
 
+eHalStatus sme_setBcnMissPenaltyCount(tHalHandle hHal,
+                                      tModifyRoamParamsReqParams *params);
 #endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 9ef481e..e7b78c9 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -13858,3 +13858,48 @@
     }
     return eHAL_STATUS_FAILURE;
 }
+
+eHalStatus sme_setBcnMissPenaltyCount(tHalHandle hHal,
+                            tModifyRoamParamsReqParams *pModifyRoamReqParams)
+{
+    tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+    eHalStatus status = eHAL_STATUS_SUCCESS;
+    VOS_STATUS vosStatus;
+    tModifyRoamParamsReqParams *pMsg;
+    vos_msg_t msg;
+
+    status = sme_AcquireGlobalLock(&pMac->sme);
+    if (HAL_STATUS_SUCCESS(status))
+    {
+        pMsg = (tModifyRoamParamsReqParams*)vos_mem_malloc(sizeof(*pMsg));
+        if (NULL == pMsg)
+        {
+            smsLog(pMac, LOGE, FL("failed to allocated memory"));
+            sme_ReleaseGlobalLock( &pMac->sme );
+            return eHAL_STATUS_FAILURE;
+        }
+        if (NULL == pModifyRoamReqParams)
+        {
+            smsLog(pMac, LOGE, FL("Invalid memory"));
+            vos_mem_free(pMsg);
+            sme_ReleaseGlobalLock( &pMac->sme );
+            return eHAL_STATUS_FAILURE;
+        }
+        pMsg->param = pModifyRoamReqParams->param;
+        pMsg->value = pModifyRoamReqParams->value;
+        vos_mem_zero(&msg, sizeof(vos_msg_t));
+        msg.type = WDA_MODIFY_ROAM_PARAMS_IND;
+        msg.reserved = 0;
+        msg.bodyptr = pMsg;
+        vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &msg);
+        if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
+        {
+           status = eHAL_STATUS_FAILURE;
+           vos_mem_free(pMsg);
+        }
+        sme_ReleaseGlobalLock( &pMac->sme );
+        return status;
+    }
+
+    return eHAL_STATUS_FAILURE;
+}
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index ff3ecf6..b007db4 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -1320,6 +1320,8 @@
 #define WDA_START_OEM_DATA_RSP_IND_NEW         SIR_HAL_START_OEM_DATA_RSP_IND_NEW
 #endif
 
+#define WDA_MODIFY_ROAM_PARAMS_IND             SIR_HAL_MODIFY_ROAM_PARAMS_IND
+
 #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames
 
 #define halTxFrame(hHal, pFrmBuf, frmLen, frmType, txDir, tid, pCompFunc, pData, txFlag) \
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index 1f3be35..d54811b 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -286,6 +286,8 @@
 v_VOID_t WDA_ProcessAntennaDiversitySelectionReq(tWDA_CbContext *pWDA,
                                    tSirAntennaDiversitySelectionReq *pData);
 
+VOS_STATUS WDA_ProcessBcnMissPenaltyCount(tWDA_CbContext *pWDA,
+                                   tModifyRoamParamsReqParams *params);
 /*
  * FUNCTION: WDA_ProcessNanRequest
  * Process NAN request
@@ -15381,6 +15383,12 @@
                              (tSirAntennaDiversitySelectionReq *)pMsg->bodyptr);
          break;
       }
+      case WDA_MODIFY_ROAM_PARAMS_IND:
+      {
+         WDA_ProcessBcnMissPenaltyCount(pWDA,
+                             (tModifyRoamParamsReqParams *)pMsg->bodyptr);
+         break;
+      }
       default:
       {
          VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
@@ -20890,4 +20898,38 @@
    return;
 }
 
+/*
+ * FUNCTION: WDA_ProcessBcnMissPenaltyCount
+ * Request to WDI.
+ */
+VOS_STATUS WDA_ProcessBcnMissPenaltyCount(tWDA_CbContext *pWDA,
+                                          tModifyRoamParamsReqParams *params)
+{
+    WDI_Status status;
+
+    VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                 FL("---> %s"), __func__);
+
+    if (NULL == params)
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                 FL("tModifyRoamParamsReqParams is received NULL"));
+        return VOS_STATUS_E_NOMEM;
+    }
+
+    status = WDI_SetBcnMissPenaltyCount((WDI_ModifyRoamParamsReqType *)params);
+    if (WDI_STATUS_PENDING == status)
+    {
+        VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+                 FL("pending status received "));
+    }
+    else if (WDI_STATUS_SUCCESS_SYNC != status)
+    {
+       VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+               FL("Failure status %d"), status);
+    }
+    vos_mem_free(params);
+    return CONVERT_WDI2VOS_STATUS(status) ;
+}
+
 #endif
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index d6618ce..73e582e 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -6257,6 +6257,16 @@
     wpt_uint32 wificonfigset_status;
 }WDI_WifconfigSetRsp;
 
+/**
+ * struct WDI_ModifyRoamParamsReqType - Modified roam parameter details.
+ *
+ */
+
+typedef struct {
+   wpt_uint8  param;
+   wpt_uint32   value;
+}WDI_ModifyRoamParamsReqType;
+
 /*----------------------------------------------------------------------------
  *   WDI callback types
  *--------------------------------------------------------------------------*/
@@ -11895,5 +11905,17 @@
   wpt_uint32 reserved
 );
 
+/**
+ @brief WDI_SetBcnMissPenaltyCount
+    This API is called to send modified roam parameters to FW
 
+ @param params: pointer to request params
+ @see
+ @return SUCCESS or FAIL
+*/
+WDI_Status
+WDI_SetBcnMissPenaltyCount
+(
+    WDI_ModifyRoamParamsReqType *params
+);
 #endif /* #ifndef WLAN_QCT_WDI_H */
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
index db378ef..0714914 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
@@ -538,6 +538,7 @@
   /*Keep adding the indications to the max request
     such that we keep them separate */
   WDI_ANTENNA_DIVERSITY_SELECTION_REQ,
+  WDI_MODIFY_ROAM_PARAMS_IND,
   WDI_MAX_UMAC_IND
 
 }WDI_RequestEnumType;
@@ -6476,5 +6477,20 @@
   WDI_EventInfoType*     pEventData
 );
 
+/**
+ @brief Process set modified roam params command
+
+ @param  pWDICtx:         pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessBcnMissPenaltyCount
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+);
 #endif /*WLAN_QCT_WDI_I_H*/
 
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index 8bd3f8e..eacf58f 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -549,6 +549,7 @@
   NULL,
 #endif /* FEATURE_OEM_DATA_SUPPORT */
   WDI_ProcessGetCurrentAntennaIndex,          /* WDI_ANTENNA_DIVERSITY_SELECTION_REQ  */
+  WDI_ProcessBcnMissPenaltyCount,             /* WDI_MODIFY_ROAM_PARAMS_IND */
 };
 
 
@@ -1235,6 +1236,7 @@
     CASE_RETURN_STRING( WDI_STOP_RSSI_MONITOR_REQ );
     CASE_RETURN_STRING( WDI_START_OEM_DATA_REQ_IND_NEW );
     CASE_RETURN_STRING( WDI_ANTENNA_DIVERSITY_SELECTION_REQ );
+    CASE_RETURN_STRING( WDI_MODIFY_ROAM_PARAMS_IND );
     default:
         return "Unknown WDI MessageId";
   }
@@ -24579,6 +24581,8 @@
        return WLAN_HAL_START_OEM_DATA_REQ_IND_NEW;
   case WDI_ANTENNA_DIVERSITY_SELECTION_REQ:
        return WLAN_HAL_ANTENNA_DIVERSITY_SELECTION_REQ;
+  case WDI_MODIFY_ROAM_PARAMS_IND:
+       return WLAN_HAL_MODIFY_ROAM_PARAMS_IND;
   default:
     return WLAN_HAL_MSG_MAX;
   }
@@ -36840,4 +36844,117 @@
 
   return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
 }
+
+/**
+ @brief Process Set beacon miss penalty count command
+
+ @param  pWDICtx:         pointer to the WLAN DAL context
+         pEventData:      pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessBcnMissPenaltyCount
+(
+  WDI_ControlBlockType*  pWDICtx,
+  WDI_EventInfoType*     pEventData
+)
+{
+  wpt_uint8*  pSendBuffer = NULL;
+  wpt_uint16  usDataOffset = 0;
+  wpt_uint16  usSendSize = 0;
+  tHalModifyRoamParamsIndParams halModifyRoamParams;
+  WDI_ModifyRoamParamsReqType *modifyRoamParams;
+  WDI_Status wdiStatus = WDI_STATUS_SUCCESS;
+
+  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+  WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_INFO,
+               "%s", __func__);
+  /*-------------------------------------------------------------------------
+    Sanity check
+  -------------------------------------------------------------------------*/
+  if (( NULL == pEventData ) || ( NULL == pEventData->pEventData ))
+  {
+      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+             "%s: Invalid parameters", __func__);
+      WDI_ASSERT(0);
+      return WDI_STATUS_E_FAILURE;
+  }
+
+  /*-----------------------------------------------------------------------
+    Get message buffer
+  -----------------------------------------------------------------------*/
+
+  if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
+                                     WDI_MODIFY_ROAM_PARAMS_IND,
+                                     sizeof(tHalModifyRoamParamsIndParams),
+                          &pSendBuffer, &usDataOffset, &usSendSize))||
+       ( usSendSize < (usDataOffset + sizeof(tHalModifyRoamParamsIndParams) )))
+  {
+      WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_FATAL,
+              "Unable to get send buffer for Modify roam req params %p ",
+               pEventData);
+      WDI_ASSERT(0);
+      return WDI_STATUS_E_FAILURE;
+  }
+
+  modifyRoamParams = (WDI_ModifyRoamParamsReqType *)pEventData->pEventData;
+  halModifyRoamParams.param = modifyRoamParams->param;
+  halModifyRoamParams.value = modifyRoamParams->value;
+  wpalMemoryCopy( pSendBuffer+usDataOffset, &halModifyRoamParams,
+                  sizeof(halModifyRoamParams));
+  pWDICtx->pReqStatusUserData = NULL;
+  pWDICtx->pfncRspCB = NULL;
+
+  /*-------------------------------------------------------------------------
+    Send WDI_MODIFY_ROAM_PARAMS_IND to HAL
+  -------------------------------------------------------------------------*/
+  wdiStatus =  WDI_SendIndication( pWDICtx, pSendBuffer, usSendSize);
+  return (wdiStatus != WDI_STATUS_SUCCESS) ? wdiStatus:WDI_STATUS_SUCCESS_SYNC;
+
+}
+
+/**
+ @brief WDI_SetBcnMissPenaltyCount
+
+ @param params: Req parameter for the FW
+
+ @return SUCCESS or FAIL
+*/
+
+WDI_Status
+WDI_SetBcnMissPenaltyCount
+(
+    WDI_ModifyRoamParamsReqType *params
+)
+{
+  WDI_EventInfoType      wdiEventData;
+
+  /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+  /*------------------------------------------------------------------------
+   Sanity Check
+  ------------------------------------------------------------------------*/
+  if ( eWLAN_PAL_FALSE == gWDIInitialized )
+  {
+      WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+                 "WDI API call before module is initialized - Fail request");
+      return WDI_STATUS_E_NOT_ALLOWED;
+  }
+
+  /*------------------------------------------------------------------------
+    Fill in Event data and post to the Main FSM
+  ------------------------------------------------------------------------*/
+  wdiEventData.wdiRequest      = WDI_MODIFY_ROAM_PARAMS_IND;
+  wdiEventData.pEventData      = (void *)params;
+  wdiEventData.uEventDataSize  = sizeof(*params);
+  wdiEventData.pCBfnc          = NULL;
+  wdiEventData.pUserData       = NULL;
+
+  return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+
+} /* WDI_SetBcnMissPenaltyCount */
+
 #endif