You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by we...@apache.org on 2016/08/12 00:51:24 UTC

[02/10] incubator-mynewt-core git commit: MYNEWT-83: use fixed buffer for reception. Get native arch building

MYNEWT-83: use fixed buffer for reception. Get native arch building


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/7c8cca9f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/7c8cca9f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/7c8cca9f

Branch: refs/heads/develop
Commit: 7c8cca9f88ebf86717b2941c4484065ffb2a2438
Parents: 580f5b6
Author: William San Filippo <wi...@runtime.io>
Authored: Mon Jul 25 10:06:41 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Thu Aug 11 17:38:54 2016 -0700

----------------------------------------------------------------------
 net/nimble/drivers/native/src/ble_phy.c | 184 +++++++++++++++++++++------
 1 file changed, 142 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c8cca9f/net/nimble/drivers/native/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/native/src/ble_phy.c b/net/nimble/drivers/native/src/ble_phy.c
index e2c9f25..4eb5d97 100644
--- a/net/nimble/drivers/native/src/ble_phy.c
+++ b/net/nimble/drivers/native/src/ble_phy.c
@@ -18,24 +18,32 @@
  */
 
 #include <stdint.h>
+#include <string.h>
 #include <assert.h>
 #include "os/os.h"
-#include "nimble/ble.h"             /* XXX: needed for ble mbuf header.*/
+#include "ble/xcvr.h"
+#include "nimble/ble.h"
+#include "nimble/nimble_opt.h"
 #include "controller/ble_phy.h"
 #include "controller/ble_ll.h"
 
 /* BLE PHY data structure */
 struct ble_phy_obj
 {
+    uint8_t phy_stats_initialized;
     int8_t  phy_txpwr_dbm;
     uint8_t phy_chan;
     uint8_t phy_state;
     uint8_t phy_transition;
     uint8_t phy_rx_started;
+    uint8_t phy_encrypted;
     uint8_t phy_privacy;
+    uint8_t phy_tx_pyld_len;
+    uint32_t phy_aar_scratch;
     uint32_t phy_access_address;
-    struct os_mbuf *rxpdu;
+    struct ble_mbuf_hdr rxhdr;
     void *txend_arg;
+    uint8_t *rxdptr;
     ble_phy_tx_end_func txend_cb;
 };
 struct ble_phy_obj g_ble_phy_data;
@@ -75,6 +83,42 @@ static struct xcvr_data g_xcvr_data;
 #define BLE_XCVR_TX_PWR_MAX_DBM     (30)
 #define BLE_XCVR_TX_PWR_MIN_DBM     (-20)
 
+/* Statistics */
+STATS_SECT_START(ble_phy_stats)
+    STATS_SECT_ENTRY(phy_isrs)
+    STATS_SECT_ENTRY(tx_good)
+    STATS_SECT_ENTRY(tx_fail)
+    STATS_SECT_ENTRY(tx_late)
+    STATS_SECT_ENTRY(tx_bytes)
+    STATS_SECT_ENTRY(rx_starts)
+    STATS_SECT_ENTRY(rx_aborts)
+    STATS_SECT_ENTRY(rx_valid)
+    STATS_SECT_ENTRY(rx_crc_err)
+    STATS_SECT_ENTRY(rx_late)
+    STATS_SECT_ENTRY(no_bufs)
+    STATS_SECT_ENTRY(radio_state_errs)
+    STATS_SECT_ENTRY(rx_hw_err)
+    STATS_SECT_ENTRY(tx_hw_err)
+STATS_SECT_END
+STATS_SECT_DECL(ble_phy_stats) ble_phy_stats;
+
+STATS_NAME_START(ble_phy_stats)
+    STATS_NAME(ble_phy_stats, phy_isrs)
+    STATS_NAME(ble_phy_stats, tx_good)
+    STATS_NAME(ble_phy_stats, tx_fail)
+    STATS_NAME(ble_phy_stats, tx_late)
+    STATS_NAME(ble_phy_stats, tx_bytes)
+    STATS_NAME(ble_phy_stats, rx_starts)
+    STATS_NAME(ble_phy_stats, rx_aborts)
+    STATS_NAME(ble_phy_stats, rx_valid)
+    STATS_NAME(ble_phy_stats, rx_crc_err)
+    STATS_NAME(ble_phy_stats, rx_late)
+    STATS_NAME(ble_phy_stats, no_bufs)
+    STATS_NAME(ble_phy_stats, radio_state_errs)
+    STATS_NAME(ble_phy_stats, rx_hw_err)
+    STATS_NAME(ble_phy_stats, tx_hw_err)
+STATS_NAME_END(ble_phy_stats)
+
 /* XXX: TODO:
 
  * 1) Test the following to make sure it works: suppose an event is already
@@ -95,28 +139,104 @@ ble_xcvr_clear_irq(uint32_t mask)
 }
 
 /**
- * ble phy rxpdu get
+ * Copies the data from the phy receive buffer into a mbuf chain.
+ *
  *
- * Gets a mbuf for PDU reception.
+ * @param dptr Pointer to receive buffer
+ * @param len Length of receive buffer to copy.
  *
- * @return struct os_mbuf* Pointer to retrieved mbuf or NULL if none available
+ * @return struct os_mbuf* Pointer to mbuf. NULL if no mbuf available.
  */
-static struct os_mbuf *
-ble_phy_rxpdu_get(void)
+struct os_mbuf *
+ble_phy_rxpdu_get(uint8_t *dptr, uint16_t len)
 {
+    uint16_t rem_bytes;
+    uint16_t mb_bytes;
+    uint16_t copylen;
+    uint32_t *dst;
+    uint32_t *src;
     struct os_mbuf *m;
+    struct os_mbuf *n;
+    struct os_mbuf *p;
+    struct ble_mbuf_hdr *ble_hdr;
+    struct os_mbuf_pkthdr *pkthdr;
 
-    m = g_ble_phy_data.rxpdu;
-    if (m == NULL) {
-        m = os_msys_get_pkthdr(BLE_MBUF_PAYLOAD_SIZE, sizeof(struct ble_mbuf_hdr));
-        if (!m) {
-            ++g_ble_phy_stats.no_bufs;
-        } else {
-            g_ble_phy_data.rxpdu = m;
+    /* Better be aligned */
+    assert(((uint32_t)dptr & 3) == 0);
+
+    p = os_msys_get_pkthdr(len, sizeof(struct ble_mbuf_hdr));
+    if (!p) {
+        STATS_INC(ble_phy_stats, no_bufs);
+        return NULL;
+    }
+
+    /*
+     * Fill in the mbuf pkthdr first. NOTE: first mbuf in chain will have data
+     * pre-pended to it so we adjust m_data by a word.
+     */
+    p->om_data += 4;
+    dst = (uint32_t *)(p->om_data);
+    src = (uint32_t *)dptr;
+
+    rem_bytes = len;
+    mb_bytes = (p->om_omp->omp_databuf_len - p->om_pkthdr_len - 4);
+    copylen = min(mb_bytes, rem_bytes);
+    copylen &= 0xFFFC;
+    rem_bytes -= copylen;
+    mb_bytes -= copylen;
+    p->om_len = copylen;
+    while (copylen > 0) {
+        *dst = *src;
+        ++dst;
+        ++src;
+        copylen -= 4;
+    }
+
+    /* Copy remaining bytes */
+    m = p;
+    while (rem_bytes > 0) {
+        /* If there are enough bytes in the mbuf, copy them and leave */
+        if (rem_bytes <= mb_bytes) {
+            memcpy(m->om_data + m->om_len, src, rem_bytes);
+            m->om_len += rem_bytes;
+            break;
+        }
+
+        n = os_msys_get(rem_bytes, 0);
+        if (!n) {
+            os_mbuf_free_chain(p);
+            STATS_INC(ble_phy_stats, no_bufs);
+            return NULL;
+        }
+
+        /* Chain new mbuf to existing chain */
+        SLIST_NEXT(m, om_next) = n;
+        m = n;
+
+        mb_bytes = m->om_omp->omp_databuf_len;
+        copylen = min(mb_bytes, rem_bytes);
+        copylen &= 0xFFFC;
+        rem_bytes -= copylen;
+        mb_bytes -= copylen;
+        m->om_len = copylen;
+        dst = (uint32_t *)m->om_data;
+        while (copylen > 0) {
+            *dst = *src;
+            ++dst;
+            ++src;
+            copylen -= 4;
         }
     }
 
-    return m;
+    /* Set packet length */
+    pkthdr = OS_MBUF_PKTHDR(p);
+    pkthdr->omp_len = len;
+
+    /* Copy ble header */
+    ble_hdr = BLE_MBUF_HDR_PTR(p);
+    memcpy(ble_hdr, &g_ble_phy_data.rxhdr, sizeof(struct ble_mbuf_hdr));
+
+    return p;
 }
 
 void
@@ -126,7 +246,6 @@ ble_phy_isr(void)
     uint8_t crcok;
     uint8_t transition;
     uint32_t irq_en;
-    struct os_mbuf *rxpdu;
     struct ble_mbuf_hdr *ble_hdr;
 
     /* Check for disabled event. This only happens for transmits now */
@@ -139,14 +258,9 @@ ble_phy_isr(void)
 
         transition = g_ble_phy_data.phy_transition;
         if (transition == BLE_PHY_TRANSITION_TX_RX) {
-            /* Packet pointer needs to be reset. */
-            if (g_ble_phy_data.rxpdu != NULL) {
-                g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
-            } else {
-                /* Disable the phy */
-                /* XXX: count no bufs? */
-                ble_phy_disable();
-            }
+            /* Disable the phy */
+            /* XXX: count no bufs? */
+            ble_phy_disable();
         } else {
             /* Better not be going from rx to tx! */
             assert(transition == BLE_PHY_TRANSITION_NONE);
@@ -158,11 +272,9 @@ ble_phy_isr(void)
 
         ble_xcvr_clear_irq(BLE_XCVR_IRQ_F_RX_START);
 
-        /* Better have a PDU! */
-        assert(g_ble_phy_data.rxpdu != NULL);
-
         /* Call Link Layer receive start function */
-        rc = ble_ll_rx_start(g_ble_phy_data.rxpdu, g_ble_phy_data.phy_chan);
+        rc = ble_ll_rx_start(g_ble_phy_data.rxdptr, g_ble_phy_data.phy_chan,
+                             &g_ble_phy_data.rxhdr);
         if (rc >= 0) {
             /* XXX: set rx end enable isr */
         } else {
@@ -182,7 +294,7 @@ ble_phy_isr(void)
         ble_xcvr_clear_irq(BLE_XCVR_IRQ_F_RX_END);
 
         /* Construct BLE header before handing up */
-        ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+        ble_hdr = &g_ble_phy_data.rxhdr;
         ble_hdr->rxinfo.flags = 0;
         ble_hdr->rxinfo.rssi = -77;    /* XXX: dummy rssi */
         ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan;
@@ -197,9 +309,7 @@ ble_phy_isr(void)
         }
 
         /* Call Link Layer receive payload function */
-        rxpdu = g_ble_phy_data.rxpdu;
-        g_ble_phy_data.rxpdu = NULL;
-        rc = ble_ll_rx_end(rxpdu, ble_hdr);
+        rc = ble_ll_rx_end(g_ble_phy_data.rxdptr, ble_hdr);
         if (rc < 0) {
             /* Disable the PHY. */
             ble_phy_disable();
@@ -239,11 +349,6 @@ ble_phy_rx(void)
         return BLE_PHY_ERR_RADIO_STATE;
     }
 
-    /* If no pdu, get one */
-    if (ble_phy_rxpdu_get() == NULL) {
-        return BLE_PHY_ERR_NO_BUFS;
-    }
-
     g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
 
     return 0;
@@ -348,11 +453,6 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
     }
 
 
-    /* Enable shortcuts for transmit start/end. */
-    if (end_trans == BLE_PHY_TRANSITION_TX_RX) {
-        ble_phy_rxpdu_get();
-    }
-
     /* Set the PHY transition */
     g_ble_phy_data.phy_transition = end_trans;