FM: notify tx thread when Host received credits from SOC.

if Host have credits then enqueue_fm_tx_cmd thread will notify tx thread
and tx thread will dequeue the cmd and send to soc.
else tx thread will be notified when Host receive the credit.



Change-Id: I5d7f1aef3c714714fa5d6f2e87cde166540a9c2e
Signed-off-by: himta ram <hram@codeaurora.org>
diff --git a/fm_hci/fm_hci.cpp b/fm_hci/fm_hci.cpp
index 0b442f1..105535a 100644
--- a/fm_hci/fm_hci.cpp
+++ b/fm_hci/fm_hci.cpp
@@ -99,12 +99,10 @@
 
     ALOGI("%s: putting lock before enqueue ", __func__);
     hci.rx_cond_mtx.lock();
-    ALOGI("%s: pushing event to que before notify", __func__);
     hci.rx_event_queue.push(hdr);
-    ALOGI("%s:before notify to waiting thred", __func__);
-    hci.rx_cond.notify_all();
-    ALOGI("%s:after notify to waiting thred", __func__);
     hci.rx_cond_mtx.unlock();
+    ALOGI("%s:notify to waiting thred", __func__);
+    hci.rx_cond.notify_all();
     ALOGI("%s: FM-Event ENQUEUED SUCCESSFULLY", __func__);
 
     return FM_HC_STATUS_SUCCESS;
@@ -138,22 +136,39 @@
         evt_buf = hci.rx_event_queue.front();
         hci.rx_event_queue.pop();
 
-        hci.credit_mtx.lock();
         if (evt_buf->evt_code == FM_CMD_COMPLETE) {
-            ALOGI("%s: %d Credits got from the SOC", __func__, evt_buf->params[0]);
-            hci.command_credits += evt_buf->params[0];
-            hci.cmd_credits_cond.notify_all();
+            ALOGI("%s: FM_CMD_COMPLETE: current_credits %d, %d Credits got from the SOC", __func__, hci.command_credits, evt_buf->params[0]);
+            if (hci.command_credits == 0) {
+                hci.command_credits += evt_buf->params[0];
+                ALOGI(" dequeue_fm_rx_event: wait for tx_cond_lock ");
+                hci.tx_cond_mtx.lock();
+                ALOGI(" dequeue_fm_rx_event: Notifying tx_cond_lock ");
+                hci.tx_cond.notify_all();
+                ALOGI(" dequeue_fm_rx_event: UNLOCKING tx_cond_lock ");
+                hci.tx_cond_mtx.unlock();
+            } else {
+                hci.command_credits += evt_buf->params[0];
+            }
+
         } else if (evt_buf->evt_code == FM_CMD_STATUS) {
-            ALOGI("%s: %d Credits got from the SOC", __func__, evt_buf->params[1]);
-            hci.command_credits += evt_buf->params[1];
-            hci.cmd_credits_cond.notify_all();
+            ALOGI("%s: FM_CMD_STATUS: current_credits %d, %d Credits got from the SOC", __func__, hci.command_credits, evt_buf->params[1]);
+            if (hci.command_credits == 0) {
+                hci.command_credits += evt_buf->params[1];
+                ALOGI(" dequeue_fm_rx_event: wait for tx_cond_lock ");
+                hci.tx_cond_mtx.lock();
+                ALOGI(" dequeue_fm_rx_event: Notifying tx_cond_lock ");
+                hci.tx_cond.notify_all();
+                ALOGI(" dequeue_fm_rx_event: UNLOCKING tx_cond_lock ");
+                hci.tx_cond_mtx.unlock();
+            } else {
+                hci.command_credits += evt_buf->params[1];
+            }
         } else if (evt_buf->evt_code == FM_HW_ERR_EVENT) {
             ALOGI("%s: FM H/w Err Event Recvd. Event Code: 0x%x", __func__, evt_buf->evt_code);
         } else {
             ALOGE("%s: Not CS/CC Event: Recvd. Event Code: 0x%x", __func__, evt_buf->evt_code);
         }
 
-        hci.credit_mtx.unlock();
         if (hci.cb && hci.cb->process_event) {
             ALOGI("%s: processing the event", __func__);
             hci.cb->process_event(NULL, (uint8_t *)evt_buf);
@@ -180,18 +195,23 @@
 *******************************************************************************/
 static int enqueue_fm_tx_cmd(struct fm_command_header_t *hdr)
 {
-    ALOGI("%s:  opcode 0x%x len:%d tx_processing %d", __func__,  hdr->opcode, hdr->len, hci.is_tx_processing);
+    ALOGI("%s:  opcode 0x%x len:%d ", __func__,  hdr->opcode, hdr->len);
 
     hci.tx_queue_mtx.lock();
     hci.tx_cmd_queue.push(hdr);
     hci.tx_queue_mtx.unlock();
 
-    if (hci.is_tx_processing == false) {
-        ALOGI("%s:  notifying tx_processing %d", __func__,hci.is_tx_processing);
+    ALOGI("%s:  notifying credits %d", __func__, hci.command_credits);
+    if (hci.command_credits > 0) {
+        ALOGI(" enqueue_fm_tx_cmd: wait for tx_cond_lock ");
+        hci.tx_cond_mtx.lock();
+        ALOGI(" enqueue_fm_tx_cmd: Notifying tx_cond_lock ");
         hci.tx_cond.notify_all();
+        ALOGI(" enqueue_fm_tx_cmd: UNLOCK tx_cond_lock ");
+        hci.tx_cond_mtx.unlock();
     }
 
-    ALOGI("%s: FM-CMD ENQUEUED SUCCESSFULLY", __func__);
+    ALOGI("%s: FM-CMD ENQUEUED SUCCESSFULLY  credits %d", __func__, hci.command_credits);
 
     return FM_HC_STATUS_SUCCESS;
 }
@@ -215,17 +235,18 @@
 
     ALOGI("%s", __func__);
 
-    while (1) {
+    while (1) 
+    {
+       ALOGI(" dequeue_fm_tx_cmd:  command credits %d ", hci.command_credits);
+       if (hci.command_credits == 0) {
+          return;
+       }
         hci.tx_queue_mtx.lock();
-        ALOGI("%s inside while(1) %d", __func__,hci.tx_cmd_queue.empty());
+        ALOGI("%s is_que_empty %d", __func__,hci.tx_cmd_queue.empty());
         if(hci.tx_cmd_queue.empty()){
             ALOGI(" %s No more FM CMDs are available in the Queue",__func__);
-            hci.is_tx_processing = false;
             hci.tx_queue_mtx.unlock();
             return;
-        } else {
-            ALOGI("%s tx_processing", __func__);
-            hci.is_tx_processing = true;
         }
 
         hdr = hci.tx_cmd_queue.front();
@@ -233,19 +254,12 @@
         hci.tx_queue_mtx.unlock();
         ALOGI("%s: packet popped %d credits", __func__,hci.command_credits);
 
-        Lock lk(hci.credit_mtx);
-        while (hci.command_credits == 0) {
-            ALOGI("%s: waiting for credits", __func__);
-            hci.cmd_credits_cond.wait(lk);
-            ALOGI("%s: %d Credits Remaining", __func__, hci.command_credits);
-            if (hci.command_credits) {
-                 break;
-            }
-        }
+
         hci.command_credits--;
         hci_transmit(hdr);
         ALOGI("%s: packet transmitted %d credits", __func__,hci.command_credits);
     }
+    ALOGI(" %s outside while(1), credits %d ", __func__, hci.command_credits);
 }
 
 
@@ -266,19 +280,11 @@
     ALOGI("%s: ##### starting hci_tx_thread Worker thread!!! #####", __func__);
     hci.is_tx_thread_running = true;
 
+    Lock lk(hci.tx_cond_mtx);
     while (hci.state != FM_RADIO_DISABLING && hci.state != FM_RADIO_DISABLED) {
         //wait  for tx cmd
-        ALOGV("%s: acquiring lock %d credits!!!" , __func__,hci.command_credits);
-        Lock lk(hci.tx_cond_mtx);
-        if(hci.tx_cmd_queue.empty())
-        {
-          ALOGI("%s: before wait %d credits!!!" , __func__,hci.command_credits);
-          hci.tx_cond.wait(lk);
-        }
-        else
-        {
-          ALOGI("%s:queue is not empty dont wait" , __func__);
-        }
+        ALOGI("%s: before wait %d credits!!!" , __func__,hci.command_credits);
+        hci.tx_cond.wait(lk);
         ALOGV("%s: after wait dequeueing the tx cmd!!!" , __func__);
         dequeue_fm_tx_cmd();
     }
@@ -361,9 +367,7 @@
     int ret;
 
     ALOGI("%s:stop_tx_thread ++", __func__);
-    if (hci.is_tx_processing == false) {
-        hci.tx_cond.notify_all();
-    }
+    hci.tx_cond.notify_all();
 
     hci.tx_thread_.join();
     ALOGI("%s:stop_tx_thread --", __func__);
@@ -634,7 +638,6 @@
 
     hci.cb = hci_hal->cb;
     hci.command_credits = 1;
-    hci.is_tx_processing = false;
     hci.is_tx_thread_running = false;
     hci.is_rx_thread_running = false;
     hci.state = FM_RADIO_DISABLED;
diff --git a/fm_hci/fm_hci.h b/fm_hci/fm_hci.h
index 73e1290..8470519 100644
--- a/fm_hci/fm_hci.h
+++ b/fm_hci/fm_hci.h
@@ -42,9 +42,6 @@
         std::condition_variable on_cond;
         std::mutex on_mtx;
 
-        bool is_tx_processing;
-        bool is_rx_processing;
-
         bool is_tx_thread_running;
         bool is_rx_thread_running;
 
@@ -56,7 +53,6 @@
 
         std::mutex tx_queue_mtx;
 
-        std::mutex credit_mtx;
         std::condition_variable cmd_credits_cond;
 
         std::queue<struct fm_command_header_t *> tx_cmd_queue;