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/07/25 17:18:59 UTC

[1/4] incubator-mynewt-core git commit: MYNEWT_83: Use fixed buffer for reception.

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/phyrx_no_mbuf [created] a621643fd


MYNEWT_83: Use fixed buffer for reception.

On the nrf51, copying the fixed buffer was taking too long for certain
operations. The code changes associated with this commit are due to
this issue.


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/a621643f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/a621643f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/a621643f

Branch: refs/heads/phyrx_no_mbuf
Commit: a621643fd32f326cf09a85fe80f9e4e2415bcf06
Parents: 525bd31
Author: William San Filippo <wi...@runtime.io>
Authored: Mon Jul 25 10:16:41 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Mon Jul 25 10:17:47 2016 -0700

----------------------------------------------------------------------
 net/nimble/controller/src/ble_ll.c           | 16 ++++-----
 net/nimble/controller/src/ble_ll_conn.c      | 41 +++++++++++++----------
 net/nimble/controller/src/ble_ll_conn_priv.h |  3 +-
 net/nimble/controller/src/ble_ll_resolv.c    | 25 +++++++++++---
 net/nimble/controller/src/ble_ll_scan.c      |  4 +--
 5 files changed, 57 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a621643f/net/nimble/controller/src/ble_ll.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll.c b/net/nimble/controller/src/ble_ll.c
index b13f9cf..f8bc94a 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -797,23 +797,23 @@ ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
         }
     }
 
-    /* Get an mbuf and copy data into it */
-    if (badpkt) {
-        rxpdu = NULL;
-    } else {
-        rxpdu = ble_phy_rxpdu_get(rxbuf, len + BLE_LL_PDU_HDR_LEN);
-    }
-
     /* Hand packet to the appropriate state machine (if crc ok) */
+    rxpdu = NULL;
     switch (BLE_MBUF_HDR_RX_STATE(rxhdr)) {
     case BLE_LL_STATE_ADV:
+        if (!badpkt) {
+            rxpdu = ble_phy_rxpdu_get(rxbuf, len + BLE_LL_PDU_HDR_LEN);
+        }
         rc = ble_ll_adv_rx_isr_end(pdu_type, rxpdu, crcok);
         break;
     case BLE_LL_STATE_SCANNING:
+        if (!badpkt) {
+            rxpdu = ble_phy_rxpdu_get(rxbuf, len + BLE_LL_PDU_HDR_LEN);
+        }
         rc = ble_ll_scan_rx_isr_end(rxpdu, crcok);
         break;
     case BLE_LL_STATE_INITIATING:
-        rc = ble_ll_init_rx_isr_end(rxpdu, crcok);
+        rc = ble_ll_init_rx_isr_end(rxbuf, crcok, rxhdr);
         break;
     default:
         rc = -1;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a621643f/net/nimble/controller/src/ble_ll_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_conn.c b/net/nimble/controller/src/ble_ll_conn.c
index 3ccff15..16c08fe 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -2197,7 +2197,8 @@ ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr)
  *       > 0: Do not disable PHY as that has already been done.
  */
 int
-ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
+ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
+                       struct ble_mbuf_hdr *ble_hdr)
 {
     int rc;
     int resolved;
@@ -2210,24 +2211,18 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
     uint8_t *adv_addr;
     uint8_t *peer;
     uint8_t *init_addr;
-    uint8_t *rxbuf;
     uint8_t pyld_len;
     uint8_t inita_is_rpa;
     uint32_t endtime;
-    struct ble_mbuf_hdr *ble_hdr;
+    struct os_mbuf *rxpdu;
     struct ble_ll_conn_sm *connsm;
 
     /*
      * We have to restart receive if we cant hand up pdu. We return 0 so that
      * the phy does not get disabled.
      */
-    if (!rxpdu) {
-        ble_phy_disable();
-        ble_phy_rx();
-        return 0;
-    }
-
     rc = -1;
+    pyld_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
     if (!crcok) {
         goto init_rx_isr_exit;
     }
@@ -2236,10 +2231,7 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
     connsm = g_ble_ll_conn_create_sm;
 
     /* Only interested in ADV IND or ADV DIRECT IND */
-    rxbuf = rxpdu->om_data;
     pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
-    pyld_len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
-
     inita_is_rpa = 0;
 
     switch (pdu_type) {
@@ -2287,7 +2279,6 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
         }
 
         index = -1;
-        ble_hdr = BLE_MBUF_HDR_PTR(rxpdu);
         peer = adv_addr;
         peer_addr_type = addr_type;
 
@@ -2305,7 +2296,7 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
                 resolved = 1;
             } else {
                 if (chk_wl) {
-                    return -1;
+                    goto init_rx_isr_exit;
                 }
             }
         }
@@ -2314,12 +2305,12 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
         /* Check filter policy */
         if (chk_wl) {
             if (!ble_ll_whitelist_match(peer, peer_addr_type, resolved)) {
-                return -1;
+                goto init_rx_isr_exit;
             }
         } else {
             /* Must match the connection address */
             if (!ble_ll_conn_is_peer_adv(addr_type, adv_addr, index)) {
-                return -1;
+                goto init_rx_isr_exit;
             }
         }
         ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_DEVMATCH;
@@ -2332,7 +2323,7 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
             if ((index < 0) ||
                 !ble_ll_resolv_rpa(init_addr,
                                    g_ble_ll_resolv_list[index].rl_local_irk)) {
-                return -1;
+                goto init_rx_isr_exit;
             }
         }
 
@@ -2346,6 +2337,8 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
             if (!rc) {
                 CONN_F_CONN_REQ_TXD(connsm) = 1;
                 STATS_INC(ble_ll_conn_stats, conn_req_txd);
+            } else {
+                ble_ll_sched_rmv_elem(&connsm->conn_sch);
             }
         } else {
             /* Count # of times we could not set schedule */
@@ -2354,9 +2347,23 @@ ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
     }
 
 init_rx_isr_exit:
+    /*
+     * We have to restart receive if we cant hand up pdu. We return 0 so that
+     * the phy does not get disabled.
+     */
+    rxpdu = ble_phy_rxpdu_get(rxbuf, pyld_len + BLE_LL_PDU_HDR_LEN);
+    if (rxpdu == NULL) {
+        ble_phy_disable();
+        ble_phy_rx();
+        rc = 0;
+    } else {
+        ble_ll_rx_pdu_in(rxpdu);
+    }
+
     if (rc) {
         ble_ll_state_set(BLE_LL_STATE_STANDBY);
     }
+
     return rc;
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a621643f/net/nimble/controller/src/ble_ll_conn_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_conn_priv.h b/net/nimble/controller/src/ble_ll_conn_priv.h
index 99bbf68..8f9d9d0 100644
--- a/net/nimble/controller/src/ble_ll_conn_priv.h
+++ b/net/nimble/controller/src/ble_ll_conn_priv.h
@@ -110,7 +110,8 @@ int ble_ll_conn_rx_isr_start(struct ble_mbuf_hdr *rxhdr, uint32_t aa);
 int ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr);
 void ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr);
 void ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr);
-int ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok);
+int ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
+                           struct ble_mbuf_hdr *ble_hdr);
 void ble_ll_conn_wfr_timer_exp(void);
 int ble_ll_conn_is_lru(struct ble_ll_conn_sm *s1, struct ble_ll_conn_sm *s2);
 uint32_t ble_ll_conn_get_ce_end_time(void);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a621643f/net/nimble/controller/src/ble_ll_resolv.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_resolv.c b/net/nimble/controller/src/ble_ll_resolv.c
index 4d91685..b4d58b0 100644
--- a/net/nimble/controller/src/ble_ll_resolv.c
+++ b/net/nimble/controller/src/ble_ll_resolv.c
@@ -340,6 +340,9 @@ ble_ll_resolv_gen_priv_addr(struct ble_ll_resolv_entry *rl, int local,
 {
     uint8_t *irk;
     uint8_t *prand;
+    uint32_t *irk32;
+    uint32_t *key32;
+    uint32_t *pt32;
     struct ble_encryption_block ecb;
 
     assert(rl != NULL);
@@ -356,13 +359,27 @@ ble_ll_resolv_gen_priv_addr(struct ble_ll_resolv_entry *rl, int local,
         irk = rl->rl_peer_irk;
     }
 
-    memcpy(ecb.key, irk, BLE_ENC_BLOCK_SIZE);
-    memset(ecb.plain_text, 0, BLE_ENC_BLOCK_SIZE);
-    swap_buf(&ecb.plain_text[13], prand, 3);
+    irk32 = (uint32_t *)irk;
+    key32 = (uint32_t *)&ecb.key[0];
+    key32[0] = irk32[0];
+    key32[1] = irk32[1];
+    key32[2] = irk32[2];
+    key32[3] = irk32[3];
+    pt32 = (uint32_t *)&ecb.plain_text[0];
+    pt32[0] = 0;
+    pt32[1] = 0;
+    pt32[2] = 0;
+    ecb.plain_text[12] = 0;
+    ecb.plain_text[13] = prand[2];
+    ecb.plain_text[14] = prand[1];
+    ecb.plain_text[15] = prand[0];
 
     /* Calculate hash */
     ble_hw_encrypt_block(&ecb);
-    swap_buf(addr, ecb.cipher_text + 13, 3);
+
+    addr[0] = ecb.cipher_text[15];
+    addr[1] = ecb.cipher_text[14];
+    addr[2] = ecb.cipher_text[13];
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a621643f/net/nimble/controller/src/ble_ll_scan.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_scan.c b/net/nimble/controller/src/ble_ll_scan.c
index bd4fb93..19b1060 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -988,7 +988,7 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
 
     /* If whitelist enabled, check to see if device is in the white list */
     if (chk_wl && !ble_ll_whitelist_match(peer, peer_addr_type, resolved)) {
-        return -1;
+        goto scan_rx_isr_exit;
     }
     ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_DEVMATCH;
 
@@ -996,7 +996,7 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
     if (chk_send_req) {
         /* Dont send scan request if we have sent one to this advertiser */
         if (ble_ll_scan_have_rxd_scan_rsp(peer, peer_addr_type)) {
-            return -1;
+            goto scan_rx_isr_exit;
         }
 
         /* Better not be a scan response pending */


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

Posted by we...@apache.org.
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/525bd318
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/525bd318
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/525bd318

Branch: refs/heads/phyrx_no_mbuf
Commit: 525bd3183d78eaccb7b4370f18089685c93ca411
Parents: 0888ff9
Author: William San Filippo <wi...@runtime.io>
Authored: Mon Jul 25 10:06:41 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Mon Jul 25 10:17:47 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/525bd318/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;
 


[4/4] incubator-mynewt-core git commit: Fix error in comment regarding how to calculate pin index from the port and port pin number

Posted by we...@apache.org.
Fix error in comment regarding how to calculate pin index from the port and port pin number


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/58bc260b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/58bc260b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/58bc260b

Branch: refs/heads/phyrx_no_mbuf
Commit: 58bc260b62fce36f6543497b5c5ac11b1f2d3ff4
Parents: 52e40bd
Author: William San Filippo <wi...@runtime.io>
Authored: Tue Jul 19 20:19:58 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Mon Jul 25 10:17:47 2016 -0700

----------------------------------------------------------------------
 hw/mcu/stm/stm32f4xx/src/hal_gpio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/58bc260b/hw/mcu/stm/stm32f4xx/src/hal_gpio.c
----------------------------------------------------------------------
diff --git a/hw/mcu/stm/stm32f4xx/src/hal_gpio.c b/hw/mcu/stm/stm32f4xx/src/hal_gpio.c
index 56b457e..f5707dd 100644
--- a/hw/mcu/stm/stm32f4xx/src/hal_gpio.c
+++ b/hw/mcu/stm/stm32f4xx/src/hal_gpio.c
@@ -59,7 +59,7 @@
  *          - Multiply by 16.
  *          - Add port pin number.
  *
- *      Ex: PD11 = (4 * 16) + 11 = 75.
+ *      Ex: PE11 = (4 * 16) + 11 = 75.
  *          PA0 = (0 * 16) + 0 = 0
  */
 #define GPIO_INDEX(pin)     ((pin) & 0x0F)


[2/4] incubator-mynewt-core git commit: MYNEWT-83: Use a fixed buffer for reception for controller stack

Posted by we...@apache.org.
MYNEWT-83: Use a fixed buffer for reception for controller stack

The nimble stack was using mbufs for reception and now uses a
static buffer. The reason behind the change is that we wanted
to be able to receive a frame even though no mbufs were available.
This would allow transmit packets to receive ACKs and thus free
up transmit buffers waiting on connection queues.

There were a number of code changes associated with the phy API.
Implemented a more efficient copy routine to copy words from
the static rx buffer into mbufs. Note that this is not yet done
for transmit frames as we are not sure we could guarantee that
the data pointer is aligned.


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/0888ff9a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/0888ff9a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/0888ff9a

Branch: refs/heads/phyrx_no_mbuf
Commit: 0888ff9aace82f300fe3900db9358b57f551a01d
Parents: 58bc260
Author: William San Filippo <wi...@runtime.io>
Authored: Wed Jul 20 04:19:57 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Mon Jul 25 10:17:47 2016 -0700

----------------------------------------------------------------------
 .../controller/include/controller/ble_ll.h      |  11 +-
 .../controller/include/controller/ble_ll_scan.h |   2 +-
 .../controller/include/controller/ble_phy.h     |   7 +
 net/nimble/controller/src/ble_ll.c              |  64 ++----
 net/nimble/controller/src/ble_ll_conn.c         |  77 +++----
 net/nimble/controller/src/ble_ll_conn_priv.h    |   2 +-
 net/nimble/controller/src/ble_ll_scan.c         |   6 +-
 net/nimble/controller/src/ble_ll_sched.c        |  14 +-
 net/nimble/drivers/nrf51/src/ble_phy.c          | 215 ++++++++++++------
 net/nimble/drivers/nrf52/src/ble_phy.c          | 217 +++++++++++++------
 net/nimble/include/nimble/nimble_opt.h          |   4 +-
 11 files changed, 383 insertions(+), 236 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0888ff9a/net/nimble/controller/include/controller/ble_ll.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll.h b/net/nimble/controller/include/controller/ble_ll.h
index 81cba53..aa5770c 100644
--- a/net/nimble/controller/include/controller/ble_ll.h
+++ b/net/nimble/controller/include/controller/ble_ll.h
@@ -312,12 +312,13 @@ int ble_ll_is_our_devaddr(uint8_t *addr, int addr_type);
 void ble_ll_acl_data_in(struct os_mbuf *txpkt);
 
 /*--- PHY interfaces ---*/
+struct ble_mbuf_hdr;
+
 /* Called by the PHY when a packet has started */
-int ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan);
+int ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *hdr);
 
 /* Called by the PHY when a packet reception ends */
-struct ble_mbuf_hdr;
-int ble_ll_rx_end(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *ble_hdr);
+int ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr);
 
 /*--- Controller API ---*/
 void ble_ll_mbuf_init(struct os_mbuf *m, uint8_t pdulen, uint8_t hdr);
@@ -331,6 +332,9 @@ uint8_t ble_ll_state_get(void);
 /* Send an event to LL task */
 void ble_ll_event_send(struct os_event *ev);
 
+/* Hand received pdu's to LL task  */
+void ble_ll_rx_pdu_in(struct os_mbuf *rxpdu);
+
 /* Set random address */
 int ble_ll_set_random_addr(uint8_t *addr);
 
@@ -382,6 +386,7 @@ int ble_ll_rand_start(void);
 #define BLE_LL_LOG_ID_CONN_END          (30)
 #define BLE_LL_LOG_ID_ADV_TXBEG         (50)
 #define BLE_LL_LOG_ID_ADV_TXDONE        (60)
+#define BLE_LL_LOG_ID_SCHED             (80)
 
 #ifdef BLE_LL_LOG
 void ble_ll_log(uint8_t id, uint8_t arg8, uint16_t arg16, uint32_t arg32);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0888ff9a/net/nimble/controller/include/controller/ble_ll_scan.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_ll_scan.h b/net/nimble/controller/include/controller/ble_ll_scan.h
index 7dafcee..3b935f4 100644
--- a/net/nimble/controller/include/controller/ble_ll_scan.h
+++ b/net/nimble/controller/include/controller/ble_ll_scan.h
@@ -96,7 +96,7 @@ void ble_ll_scan_init(void);
 void ble_ll_scan_reset(void);
 
 /* Called when Link Layer starts to receive a PDU and is in scanning state */
-int ble_ll_scan_rx_isr_start(uint8_t pdu_type, struct os_mbuf *rxpdu);
+int ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint8_t *rxflags);
 
 /* Called when Link Layer has finished receiving a PDU while scanning */
 int ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0888ff9a/net/nimble/controller/include/controller/ble_phy.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/include/controller/ble_phy.h b/net/nimble/controller/include/controller/ble_phy.h
index 1333c19..74f349a 100644
--- a/net/nimble/controller/include/controller/ble_phy.h
+++ b/net/nimble/controller/include/controller/ble_phy.h
@@ -97,6 +97,13 @@ int ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans);
 /* Place the PHY into receive mode */
 int ble_phy_rx(void);
 
+/*
+ * Retrieve the received PDU from the PHY. This returns an mbuf with
+ * the most recently received PDU in it. It also contains the ble_hdr
+ * as well
+ */
+struct os_mbuf *ble_phy_rxpdu_get(uint8_t *dptr, uint16_t mblen);
+
 /* Get an RSSI reading */
 int ble_phy_rssi_get(void);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0888ff9a/net/nimble/controller/src/ble_ll.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll.c b/net/nimble/controller/src/ble_ll.c
index 3a09e3e..b13f9cf 100644
--- a/net/nimble/controller/src/ble_ll.c
+++ b/net/nimble/controller/src/ble_ll.c
@@ -662,25 +662,21 @@ ble_ll_acl_data_in(struct os_mbuf *txpkt)
  *   > 0: Continue to receive frame and go from rx to tx when done
  */
 int
-ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan)
+ble_ll_rx_start(uint8_t *rxbuf, uint8_t chan, struct ble_mbuf_hdr *rxhdr)
 {
     int rc;
     uint8_t pdu_type;
-    uint8_t *rxbuf;
-    struct ble_mbuf_hdr *ble_hdr;
 
-    ble_ll_log(BLE_LL_LOG_ID_RX_START, chan, 0, (uint32_t)rxpdu);
+    ble_ll_log(BLE_LL_LOG_ID_RX_START, chan, 0, rxhdr->beg_cputime);
 
     /* Check channel type */
-    rxbuf = rxpdu->om_data;
     if (chan < BLE_PHY_NUM_DATA_CHANS) {
         /*
          * Data channel pdu. We should be in CONNECTION state with an
          * ongoing connection
          */
         if (g_ble_ll_data.ll_state == BLE_LL_STATE_CONNECTION) {
-            ble_hdr = BLE_MBUF_HDR_PTR(rxpdu);
-            rc = ble_ll_conn_rx_isr_start(ble_hdr, ble_phy_access_addr_get());
+            rc = ble_ll_conn_rx_isr_start(rxhdr, ble_phy_access_addr_get());
         } else {
             STATS_INC(ble_ll_stats, bad_ll_state);
             rc = 0;
@@ -704,7 +700,7 @@ ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan)
         }
         break;
     case BLE_LL_STATE_SCANNING:
-        rc = ble_ll_scan_rx_isr_start(pdu_type, rxpdu);
+        rc = ble_ll_scan_rx_isr_start(pdu_type, &rxhdr->rxinfo.flags);
         break;
     case BLE_LL_STATE_CONNECTION:
         /* Should not occur */
@@ -726,8 +722,8 @@ ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan)
  *
  * NOTE: Called from interrupt context!
  *
- * @param rxpdu Pointer to received PDU
- *        ble_hdr Pointer to BLE header of received mbuf
+ * @param rxbuf Pointer to received PDU data
+ *        rxhdr Pointer to BLE header of received mbuf
  *
  * @return int
  *       < 0: Disable the phy after reception.
@@ -735,7 +731,7 @@ ble_ll_rx_start(struct os_mbuf *rxpdu, uint8_t chan)
  *       > 0: Do not disable PHY as that has already been done.
  */
 int
-ble_ll_rx_end(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *ble_hdr)
+ble_ll_rx_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
 {
     int rc;
     int badpkt;
@@ -743,40 +739,23 @@ ble_ll_rx_end(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *ble_hdr)
     uint8_t len;
     uint8_t chan;
     uint8_t crcok;
-    uint16_t mblen;
-    uint8_t *rxbuf;
-
-    /* Set the rx buffer pointer to the start of the received data */
-    rxbuf = rxpdu->om_data;
+    struct os_mbuf *rxpdu;
 
     /* Get channel and CRC status from BLE header */
-    chan = ble_hdr->rxinfo.channel;
-    crcok = BLE_MBUF_HDR_CRC_OK(ble_hdr);
+    chan = rxhdr->rxinfo.channel;
+    crcok = BLE_MBUF_HDR_CRC_OK(rxhdr);
 
     ble_ll_log(BLE_LL_LOG_ID_RX_END, rxbuf[0],
-               ((uint16_t)ble_hdr->rxinfo.flags << 8) | rxbuf[1],
-               (BLE_MBUF_HDR_PTR(rxpdu))->beg_cputime);
+               ((uint16_t)rxhdr->rxinfo.flags << 8) | rxbuf[1],
+               rxhdr->beg_cputime);
 
     /* Check channel type */
     if (chan < BLE_PHY_NUM_DATA_CHANS) {
-        /* Set length in the received PDU */
-        mblen = rxbuf[1] + BLE_LL_PDU_HDR_LEN;
-        OS_MBUF_PKTHDR(rxpdu)->omp_len = mblen;
-        rxpdu->om_len = mblen;
-
-        /*
-         * NOTE: this looks a bit odd, and it is, but for now we place the
-         * received PDU on the Link Layer task before calling the rx end
-         * function. We do this to guarantee connection event end ordering
-         * and receive PDU processing.
-         */
-        ble_ll_rx_pdu_in(rxpdu);
-
         /*
          * Data channel pdu. We should be in CONNECTION state with an
          * ongoing connection.
          */
-        rc = ble_ll_conn_rx_isr_end(rxpdu);
+        rc = ble_ll_conn_rx_isr_end(rxbuf, rxhdr);
         return rc;
     }
 
@@ -784,14 +763,9 @@ ble_ll_rx_end(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *ble_hdr)
     pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
     len = rxbuf[1] & BLE_ADV_PDU_HDR_LEN_MASK;
 
-    /* Setup the mbuf lengths */
-    mblen = len + BLE_LL_PDU_HDR_LEN;
-    OS_MBUF_PKTHDR(rxpdu)->omp_len = mblen;
-    rxpdu->om_len = mblen;
-
     /* If the CRC checks, make sure lengths check! */
+    badpkt = 0;
     if (crcok) {
-        badpkt = 0;
         switch (pdu_type) {
         case BLE_ADV_PDU_TYPE_SCAN_REQ:
         case BLE_ADV_PDU_TYPE_ADV_DIRECT_IND:
@@ -820,14 +794,18 @@ ble_ll_rx_end(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *ble_hdr)
         /* If this is a malformed packet, just kill it here */
         if (badpkt) {
             STATS_INC(ble_ll_stats, rx_adv_malformed_pkts);
-            os_mbuf_free_chain(rxpdu);
-            rxpdu = NULL;
         }
     }
 
+    /* Get an mbuf and copy data into it */
+    if (badpkt) {
+        rxpdu = NULL;
+    } else {
+        rxpdu = ble_phy_rxpdu_get(rxbuf, len + BLE_LL_PDU_HDR_LEN);
+    }
 
     /* Hand packet to the appropriate state machine (if crc ok) */
-    switch (BLE_MBUF_HDR_RX_STATE(ble_hdr)) {
+    switch (BLE_MBUF_HDR_RX_STATE(rxhdr)) {
     case BLE_LL_STATE_ADV:
         rc = ble_ll_adv_rx_isr_end(pdu_type, rxpdu, crcok);
         break;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0888ff9a/net/nimble/controller/src/ble_ll_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_conn.c b/net/nimble/controller/src/ble_ll_conn.c
index 811b51f..3ccff15 100644
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@ -218,13 +218,13 @@ STATS_NAME_END(ble_ll_conn_stats)
  * Called to determine if the received PDU is an empty PDU or not.
  */
 static int
-ble_ll_conn_is_empty_pdu(struct os_mbuf *rxpdu)
+ble_ll_conn_is_empty_pdu(uint8_t *rxbuf)
 {
     int rc;
     uint8_t llid;
 
-    llid = rxpdu->om_data[0] & BLE_LL_DATA_HDR_LLID_MASK;
-    if ((llid == BLE_LL_LLID_DATA_FRAG) && (rxpdu->om_data[1] == 0)) {
+    llid = rxbuf[0] & BLE_LL_DATA_HDR_LLID_MASK;
+    if ((llid == BLE_LL_LLID_DATA_FRAG) && (rxbuf[1] == 0)) {
         rc = 1;
     } else {
         rc = 0;
@@ -287,7 +287,7 @@ ble_ll_conn_get_ce_end_time(void)
  *  standby and set the current state machine pointer to NULL.
  */
 static void
-ble_ll_conn_current_sm_over(void)
+ble_ll_conn_current_sm_over(struct ble_ll_conn_sm *connsm)
 {
     /* Disable the PHY */
     ble_phy_disable();
@@ -300,6 +300,15 @@ ble_ll_conn_current_sm_over(void)
 
     /* Set current LL connection to NULL */
     g_ble_ll_conn_cur_sm = NULL;
+
+    /*
+     * NOTE: the connection state machine may be NULL if we are calling
+     * this when we are ending the connection. In that case, there is no
+     * need to post to the LL the connection event end event
+     */
+    if (connsm) {
+        ble_ll_event_send(&connsm->conn_ev_end);
+    }
 }
 
 /**
@@ -573,11 +582,8 @@ ble_ll_conn_wfr_timer_exp(void)
     struct ble_ll_conn_sm *connsm;
 
     connsm = g_ble_ll_conn_cur_sm;
-    ble_ll_conn_current_sm_over();
-    if (connsm) {
-        ble_ll_event_send(&connsm->conn_ev_end);
-        STATS_INC(ble_ll_conn_stats, wfr_expirations);
-    }
+    ble_ll_conn_current_sm_over(connsm);
+    STATS_INC(ble_ll_conn_stats, wfr_expirations);
 }
 
 /**
@@ -594,10 +600,8 @@ ble_ll_conn_wait_txend(void *arg)
 {
     struct ble_ll_conn_sm *connsm;
 
-    ble_ll_conn_current_sm_over();
-
     connsm = (struct ble_ll_conn_sm *)arg;
-    ble_ll_event_send(&connsm->conn_ev_end);
+    ble_ll_conn_current_sm_over(connsm);
 }
 
 #if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
@@ -631,8 +635,7 @@ ble_ll_conn_txend_encrypt(void *arg)
 
     connsm = (struct ble_ll_conn_sm *)arg;
     CONN_F_ENCRYPTED(connsm) = 1;
-    ble_ll_conn_current_sm_over();
-    ble_ll_event_send(&connsm->conn_ev_end);
+    ble_ll_conn_current_sm_over(connsm);
 }
 
 static void
@@ -642,8 +645,7 @@ ble_ll_conn_rxend_unencrypt(void *arg)
 
     connsm = (struct ble_ll_conn_sm *)arg;
     CONN_F_ENCRYPTED(connsm) = 0;
-    ble_ll_conn_current_sm_over();
-    ble_ll_event_send(&connsm->conn_ev_end);
+    ble_ll_conn_current_sm_over(connsm);
 }
 
 static void
@@ -2377,7 +2379,7 @@ ble_ll_conn_timeout(struct ble_ll_conn_sm *connsm, uint8_t ble_err)
     was_current = 0;
     OS_ENTER_CRITICAL(sr);
     if (g_ble_ll_conn_cur_sm == connsm) {
-        ble_ll_conn_current_sm_over();
+        ble_ll_conn_current_sm_over(NULL);
         was_current = 1;
     }
     OS_EXIT_CRITICAL(sr);
@@ -2449,7 +2451,6 @@ ble_ll_conn_rx_isr_start(struct ble_mbuf_hdr *rxhdr, uint32_t aa)
             connsm->anchor_point = connsm->last_anchor_point;
         }
     }
-
     return 1;
 }
 
@@ -2601,7 +2602,7 @@ conn_rx_data_pdu_end:
  *       > 0: Do not disable PHY as that has already been done.
  */
 int
-ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu)
+ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr)
 {
     int rc;
     int is_ctrl;
@@ -2617,7 +2618,7 @@ ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu)
     uint32_t endtime;
     struct os_mbuf *txpdu;
     struct ble_ll_conn_sm *connsm;
-    struct ble_mbuf_hdr *rxhdr;
+    struct os_mbuf *rxpdu;
     struct ble_mbuf_hdr *txhdr;
 
     /*
@@ -2632,9 +2633,8 @@ ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu)
     }
 
     /* Set the handle in the ble mbuf header */
-    rxhdr = BLE_MBUF_HDR_PTR(rxpdu);
-    hdr_byte = rxpdu->om_data[0];
-    rx_pyld_len = rxpdu->om_data[1];
+    hdr_byte = rxbuf[0];
+    rx_pyld_len = rxbuf[1];
 
     /*
      * Check the packet CRC. A connection event can continue even if the
@@ -2661,15 +2661,13 @@ ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu)
         /* Reset consecutively received bad crcs (since this one was good!) */
         connsm->cons_rxd_bad_crc = 0;
 
-        /* Check for valid LLID before proceeding. */
+        /*
+         * Check for valid LLID before proceeding. We have seen some weird
+         * things with the PHY where the CRC is OK but we dont have a valid
+         * LLID. This should really never happen but if it does we will just
+         * bail. An error stat will get incremented at the LL.
+         */
         if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == 0) {
-            /*
-             * XXX: for now, just exit since we dont trust the length
-             * and may erroneously adjust anchor. Once we fix the anchor
-             * point issue we need to decide what to do on bad llid. Note
-             * that an error stat gets counted at the LL
-             */
-            reply = 0;
             goto conn_exit;
         }
 
@@ -2685,7 +2683,7 @@ ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu)
         if ((hdr_sn && conn_nesn) || (!hdr_sn && !conn_nesn)) {
             connsm->next_exp_seqnum ^= 1;
 #if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
-            if (CONN_F_ENCRYPTED(connsm) && !ble_ll_conn_is_empty_pdu(rxpdu)) {
+            if (CONN_F_ENCRYPTED(connsm) && !ble_ll_conn_is_empty_pdu(rxbuf)) {
                 ++connsm->enc_data.rx_pkt_cntr;
             }
 #endif
@@ -2778,13 +2776,13 @@ chk_rx_terminate_ind:
         is_ctrl = 0;
         if ((hdr_byte & BLE_LL_DATA_HDR_LLID_MASK) == BLE_LL_LLID_CTRL) {
             is_ctrl = 1;
-            opcode = rxpdu->om_data[2];
+            opcode = rxbuf[2];
         }
 
         /* If we received a terminate IND, we must set some flags */
         if (is_ctrl && (opcode == BLE_LL_CTRL_TERMINATE_IND)) {
             connsm->csmflags.cfbit.terminate_ind_rxd = 1;
-            connsm->rxd_disconnect_reason = rxpdu->om_data[3];
+            connsm->rxd_disconnect_reason = rxbuf[3];
             reply = 1;
         } else if (connsm->conn_role == BLE_LL_CONN_ROLE_MASTER) {
             reply = CONN_F_LAST_TXD_MD(connsm) || (hdr_byte & BLE_LL_DATA_HDR_MD_MASK);
@@ -2810,12 +2808,15 @@ chk_rx_terminate_ind:
     }
 
 conn_exit:
+    /* Copy the received pdu and hand it up */
+    rxpdu = ble_phy_rxpdu_get(rxbuf, rxbuf[1] + BLE_LL_PDU_HDR_LEN);
+    if (rxpdu) {
+        ble_ll_rx_pdu_in(rxpdu);
+    }
+
     /* Send link layer a connection end event if over */
     if (rc) {
-        ble_ll_conn_current_sm_over();
-        if (connsm) {
-            ble_ll_event_send(&connsm->conn_ev_end);
-        }
+        ble_ll_conn_current_sm_over(connsm);
     }
 
     return rc;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0888ff9a/net/nimble/controller/src/ble_ll_conn_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_conn_priv.h b/net/nimble/controller/src/ble_ll_conn_priv.h
index 218ecbc..99bbf68 100644
--- a/net/nimble/controller/src/ble_ll_conn_priv.h
+++ b/net/nimble/controller/src/ble_ll_conn_priv.h
@@ -107,7 +107,7 @@ void ble_ll_conn_event_end(void *arg);
 void ble_ll_conn_tx_pkt_in(struct os_mbuf *om, uint16_t handle, uint16_t len);
 void ble_ll_conn_spvn_timeout(void *arg);
 int ble_ll_conn_rx_isr_start(struct ble_mbuf_hdr *rxhdr, uint32_t aa);
-int ble_ll_conn_rx_isr_end(struct os_mbuf *rxpdu);
+int ble_ll_conn_rx_isr_end(uint8_t *rxbuf, struct ble_mbuf_hdr *rxhdr);
 void ble_ll_conn_rx_data_pdu(struct os_mbuf *rxpdu, struct ble_mbuf_hdr *hdr);
 void ble_ll_init_rx_pkt_in(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr);
 int ble_ll_init_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0888ff9a/net/nimble/controller/src/ble_ll_scan.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_scan.c b/net/nimble/controller/src/ble_ll_scan.c
index c926846..bd4fb93 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -837,11 +837,10 @@ ble_ll_scan_event_proc(void *arg)
  *  1: we may send a response to this frame.
  */
 int
-ble_ll_scan_rx_isr_start(uint8_t pdu_type, struct os_mbuf *rxpdu)
+ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint8_t *rxflags)
 {
     int rc;
     struct ble_ll_scan_sm *scansm;
-    struct ble_mbuf_hdr *ble_hdr;
 
     rc = 0;
     scansm = &g_ble_ll_scan_sm;
@@ -863,8 +862,7 @@ ble_ll_scan_rx_isr_start(uint8_t pdu_type, struct os_mbuf *rxpdu)
          */
         if (scansm->scan_rsp_pending) {
             if (pdu_type == BLE_ADV_PDU_TYPE_SCAN_RSP) {
-                ble_hdr = BLE_MBUF_HDR_PTR(rxpdu);
-                ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_SCAN_RSP_CHK;
+                *rxflags |= BLE_MBUF_HDR_F_SCAN_RSP_CHK;
             } else {
                 ble_ll_scan_req_backoff(scansm, 0);
             }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0888ff9a/net/nimble/controller/src/ble_ll_sched.c
----------------------------------------------------------------------
diff --git a/net/nimble/controller/src/ble_ll_sched.c b/net/nimble/controller/src/ble_ll_sched.c
index 5b79217..90cb510 100644
--- a/net/nimble/controller/src/ble_ll_sched.c
+++ b/net/nimble/controller/src/ble_ll_sched.c
@@ -32,6 +32,10 @@
 /* XXX: this is temporary. Not sure what I want to do here */
 struct cpu_timer g_ble_ll_sched_timer;
 
+#if (BLE_LL_SCHED_DEBUG == 1)
+int32_t g_ble_ll_sched_max_late;
+#endif
+
 /* XXX: TODO:
  *  1) Add some accounting to the schedule code to see how late we are
  *  (min/max?)
@@ -645,6 +649,7 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch)
         } else {
             STATS_INC(ble_ll_stats, sched_state_conn_errs);
             ble_ll_conn_event_halt();
+            return -1;
         }
     }
 
@@ -663,12 +668,19 @@ ble_ll_sched_execute_item(struct ble_ll_sched_item *sch)
 void
 ble_ll_sched_run(void *arg)
 {
+    int32_t dt;
     struct ble_ll_sched_item *sch;
 
     /* Look through schedule queue */
     while ((sch = TAILQ_FIRST(&g_ble_ll_sched_q)) != NULL) {
         /* Make sure we have passed the start time of the first event */
-        if ((int32_t)(cputime_get32() - sch->start_time) >= 0) {
+        dt = (int32_t)(cputime_get32() - sch->start_time);
+        if (dt >= 0) {
+#if (BLE_LL_SCHED_DEBUG == 1)
+            if (dt > g_ble_ll_sched_max_late) {
+                g_ble_ll_sched_max_late = dt;
+            }
+#endif
             /* Remove schedule item and execute the callback */
             TAILQ_REMOVE(&g_ble_ll_sched_q, sch, link);
             sch->enqueued = 0;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0888ff9a/net/nimble/drivers/nrf51/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf51/src/ble_phy.c b/net/nimble/drivers/nrf51/src/ble_phy.c
index 0c05011..15a2da7 100644
--- a/net/nimble/drivers/nrf51/src/ble_phy.c
+++ b/net/nimble/drivers/nrf51/src/ble_phy.c
@@ -38,7 +38,7 @@
 /*
  * XXX: Maximum possible transmit time is 1 msec for a 60ppm crystal
  * and 16ms for a 30ppm crystal! We need to limit PDU size based on
- * crystal accuracy
+ * crystal accuracy. Look at this in the spec.
  */
 
 /* XXX: private header file? */
@@ -82,9 +82,10 @@ struct ble_phy_obj
     uint8_t phy_encrypted;
     uint8_t phy_privacy;
     uint8_t phy_tx_pyld_len;
+    uint8_t *rxdptr;
     uint32_t phy_aar_scratch;
     uint32_t phy_access_address;
-    struct os_mbuf *rxpdu;
+    struct ble_mbuf_hdr rxhdr;
     void *txend_arg;
     ble_phy_tx_end_func txend_cb;
 };
@@ -92,7 +93,8 @@ struct ble_phy_obj g_ble_phy_data;
 
 /* XXX: if 27 byte packets desired we can make this smaller */
 /* Global transmit/receive buffer */
-static uint32_t g_ble_phy_txrx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
+static uint32_t g_ble_phy_tx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
+static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
 
 #if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
 /* Make sure word-aligned for faster copies */
@@ -183,33 +185,104 @@ struct nrf_ccm_data g_nrf_ccm_data;
 #endif
 
 /**
- * ble phy rxpdu get
+ * Copies the data from the phy receive buffer into a mbuf chain.
  *
- * Gets a mbuf for PDU reception.
  *
- * @return struct os_mbuf* Pointer to retrieved mbuf or NULL if none available
+ * @param dptr Pointer to receive buffer
+ * @param len Length of receive buffer to copy.
+ *
+ * @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;
+
+    /* 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;
+    }
 
-    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) {
+    /* 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);
-        } else {
-            /*
-             * NOTE: we add two bytes to the data pointer as we will prepend
-             * two bytes if we hand this received pdu up to host.
-             */
-            m->om_data += 2;
-            g_ble_phy_data.rxpdu = m;
+            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;
 }
 
 /**
@@ -241,11 +314,16 @@ nrf_wait_disabled(void)
 static void
 ble_phy_rx_xcvr_setup(void)
 {
+    uint8_t *dptr;
+
+    dptr = (uint8_t *)&g_ble_phy_rx_buf[0];
+
 #if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
     if (g_ble_phy_data.phy_encrypted) {
+        dptr += 3;
         NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
         NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-        NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+        NRF_CCM->OUTPTR = (uint32_t)dptr;
         NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
         NRF_CCM->MODE = CCM_MODE_MODE_Decryption;
         NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
@@ -254,20 +332,22 @@ ble_phy_rx_xcvr_setup(void)
         NRF_CCM->EVENTS_ENDCRYPT = 0;
         NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
     } else {
-        NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+        NRF_RADIO->PACKETPTR = (uint32_t)dptr;
     }
 #else
-    NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+    NRF_RADIO->PACKETPTR = (uint32_t)dptr;
 #endif
 
 #if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1)
     if (g_ble_phy_data.phy_privacy) {
+        dptr += 3;
+        NRF_RADIO->PACKETPTR = (uint32_t)dptr;
         NRF_RADIO->PCNF0 = (6 << RADIO_PCNF0_LFLEN_Pos) |
                            (2 << RADIO_PCNF0_S1LEN_Pos) |
                            (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
         NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Enabled;
         NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
-        NRF_AAR->ADDRPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+        NRF_AAR->ADDRPTR = (uint32_t)dptr;
         NRF_AAR->SCRATCHPTR = (uint32_t)&g_ble_phy_data.phy_aar_scratch;
         NRF_AAR->EVENTS_END = 0;
         NRF_AAR->EVENTS_RESOLVED = 0;
@@ -289,6 +369,7 @@ ble_phy_rx_xcvr_setup(void)
     /* Reset the rx started flag. Used for the wait for response */
     g_ble_phy_data.phy_rx_started = 0;
     g_ble_phy_data.phy_state = BLE_PHY_STATE_RX;
+    g_ble_phy_data.rxdptr = dptr;
 
     /* I want to know when 1st byte received (after address) */
     NRF_RADIO->BCC = 8; /* in bits */
@@ -313,16 +394,28 @@ ble_phy_rx_xcvr_setup(void)
 static void
 ble_phy_tx_end_isr(void)
 {
+    uint8_t was_encrypted;
     uint8_t transition;
     uint8_t txlen;
     uint32_t wfr_time;
+    uint32_t txstart;
+
+    /*
+     * Read captured tx start time. This is not the actual transmit start
+     * time but it is the time at which the address event occurred
+     * (after transmission of access address)
+     */
+    txstart = NRF_TIMER0->CC[1];
+
+    /* If this transmission was encrypted we need to remember it */
+    was_encrypted = g_ble_phy_data.phy_encrypted;
 
     /* Better be in TX state! */
     assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
 
     /* Log the event */
-    ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
-               g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[1]);
+    ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_tx_buf[0] >> 8) & 0xFF,
+               was_encrypted, txstart);
 
     /* Clear events and clear interrupt on disabled event */
     NRF_RADIO->EVENTS_DISABLED = 0;
@@ -335,7 +428,7 @@ ble_phy_tx_end_isr(void)
      * XXX: not sure what to do. We had a HW error during transmission.
      * For now I just count a stat but continue on like all is good.
      */
-    if (g_ble_phy_data.phy_encrypted) {
+    if (was_encrypted) {
         if (NRF_CCM->EVENTS_ERROR) {
             STATS_INC(ble_phy_stats, tx_hw_err);
             NRF_CCM->EVENTS_ERROR = 0;
@@ -343,26 +436,25 @@ ble_phy_tx_end_isr(void)
     }
 #endif
 
+    /* Call transmit end callback */
+    if (g_ble_phy_data.txend_cb) {
+        g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
+    }
+
     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) {
-            ble_phy_rx_xcvr_setup();
-        } else {
-            /* Disable the phy */
-            STATS_INC(ble_phy_stats, no_bufs);
-            ble_phy_disable();
-        }
+        ble_phy_rx_xcvr_setup();
 
         /*
          * Enable the wait for response timer. Note that cc #1 on
          * timer 0 contains the transmit start time
          */
         txlen = g_ble_phy_data.phy_tx_pyld_len;
-        if (txlen && g_ble_phy_data.phy_encrypted) {
+        if (txlen && was_encrypted) {
             txlen += BLE_LL_DATA_MIC_LEN;
         }
-        wfr_time = NRF_TIMER0->CC[1] - BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
+        wfr_time = txstart - BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
         wfr_time += BLE_TX_DUR_USECS_M(txlen);
         wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
         ble_ll_wfr_enable(wfr_time);
@@ -371,22 +463,14 @@ ble_phy_tx_end_isr(void)
         NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
         assert(transition == BLE_PHY_TRANSITION_NONE);
     }
-
-    /* Call transmit end callback */
-    if (g_ble_phy_data.txend_cb) {
-        g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
-    }
 }
 
 static void
 ble_phy_rx_end_isr(void)
 {
     int rc;
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
     uint8_t *dptr;
-#endif
     uint8_t crcok;
-    struct os_mbuf *rxpdu;
     struct ble_mbuf_hdr *ble_hdr;
 
     /* Clear events and clear interrupt */
@@ -397,12 +481,12 @@ ble_phy_rx_end_isr(void)
     NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
 
     /* Set RSSI and CRC status flag in header */
-    ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+    ble_hdr = &g_ble_phy_data.rxhdr;
     assert(NRF_RADIO->EVENTS_RSSIEND != 0);
     ble_hdr->rxinfo.rssi = -1 * NRF_RADIO->RSSISAMPLE;
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
-    dptr = g_ble_phy_data.rxpdu->om_data;
-#endif
+
+    dptr = g_ble_phy_data.rxdptr;
+
     /* Count PHY crc errors and valid packets */
     crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
     if (!crcok) {
@@ -441,10 +525,6 @@ ble_phy_rx_end_isr(void)
 #endif
     }
 
-    /* Call Link Layer receive payload function */
-    rxpdu = g_ble_phy_data.rxpdu;
-    g_ble_phy_data.rxpdu = NULL;
-
 #if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1) || (BLE_LL_CFG_FEAT_LL_PRIVACY == 1)
     if (g_ble_phy_data.phy_encrypted || g_ble_phy_data.phy_privacy) {
         /*
@@ -454,10 +534,10 @@ ble_phy_rx_end_isr(void)
          */
         dptr[2] = dptr[1];
         dptr[1] = dptr[0];
-        rxpdu->om_data += 1;
+        ++dptr;
     }
 #endif
-    rc = ble_ll_rx_end(rxpdu, ble_hdr);
+    rc = ble_ll_rx_end(dptr, ble_hdr);
     if (rc < 0) {
         ble_phy_disable();
     }
@@ -474,8 +554,6 @@ ble_phy_rx_start_isr(void)
     NRF_RADIO->EVENTS_ADDRESS = 0;
     NRF_RADIO->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk;
 
-    assert(g_ble_phy_data.rxpdu != NULL);
-
     /* Wait to get 1st byte of frame */
     while (1) {
         state = NRF_RADIO->STATE;
@@ -495,7 +573,7 @@ ble_phy_rx_start_isr(void)
     }
 
     /* Initialize flags, channel and state in ble header at rx start */
-    ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+    ble_hdr = &g_ble_phy_data.rxhdr;
     ble_hdr->rxinfo.flags = ble_ll_state_get();
     ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan;
     ble_hdr->rxinfo.handle = 0;
@@ -503,7 +581,8 @@ ble_phy_rx_start_isr(void)
         BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
 
     /* 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) {
         /* Set rx started flag and enable rx end ISR */
         g_ble_phy_data.phy_rx_started = 1;
@@ -672,11 +751,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;
-    }
-
     /* Make sure all interrupts are disabled */
     NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
 
@@ -855,7 +929,7 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
 
         NRF_CCM->SHORTS = 1;
         NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-        NRF_CCM->OUTPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
+        NRF_CCM->OUTPTR = (uint32_t)&g_ble_phy_tx_buf[0];
         NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
         NRF_CCM->EVENTS_ERROR = 0;
         NRF_CCM->MODE = CCM_MODE_MODE_Encryption;
@@ -872,7 +946,7 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
         NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
 #endif
         /* RAM representation has S0 and LENGTH fields (2 bytes) */
-        dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
+        dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
         dptr[0] = ble_hdr->txinfo.hdr_byte;
         dptr[1] = payload_len;
         dptr += 2;
@@ -887,13 +961,13 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
 #endif
 
     /* RAM representation has S0 and LENGTH fields (2 bytes) */
-    dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
+    dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
     dptr[0] = ble_hdr->txinfo.hdr_byte;
     dptr[1] = payload_len;
     dptr += 2;
 #endif
 
-    NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
+    NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_tx_buf[0];
 
     /* Clear the ready, end and disabled events */
     NRF_RADIO->EVENTS_READY = 0;
@@ -903,13 +977,10 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
     /* Enable shortcuts for transmit start/end. */
     shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk;
     if (end_trans == BLE_PHY_TRANSITION_TX_RX) {
-        /* If we are going into receive after this, try to get a buffer. */
-        if (ble_phy_rxpdu_get()) {
-            shortcuts |= RADIO_SHORTS_DISABLED_RXEN_Msk;
-        }
+        shortcuts |= RADIO_SHORTS_DISABLED_RXEN_Msk;
     }
-    NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
     NRF_RADIO->SHORTS = shortcuts;
+    NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
 
     /* Set transmitted payload length */
     g_ble_phy_data.phy_tx_pyld_len = payload_len;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0888ff9a/net/nimble/drivers/nrf52/src/ble_phy.c
----------------------------------------------------------------------
diff --git a/net/nimble/drivers/nrf52/src/ble_phy.c b/net/nimble/drivers/nrf52/src/ble_phy.c
index 541ece9..8ffab96 100644
--- a/net/nimble/drivers/nrf52/src/ble_phy.c
+++ b/net/nimble/drivers/nrf52/src/ble_phy.c
@@ -39,7 +39,7 @@
 /*
  * XXX: Maximum possible transmit time is 1 msec for a 60ppm crystal
  * and 16ms for a 30ppm crystal! We need to limit PDU size based on
- * crystal accuracy
+ * crystal accuracy. Look at this in the spec.
  */
 
 /* XXX: private header file? */
@@ -79,7 +79,7 @@ struct ble_phy_obj
     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;
     ble_phy_tx_end_func txend_cb;
 };
@@ -87,7 +87,8 @@ struct ble_phy_obj g_ble_phy_data;
 
 /* XXX: if 27 byte packets desired we can make this smaller */
 /* Global transmit/receive buffer */
-static uint32_t g_ble_phy_txrx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
+static uint32_t g_ble_phy_tx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
+static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
 
 #if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
 /* Make sure word-aligned for faster copies */
@@ -185,33 +186,104 @@ struct nrf_ccm_data g_nrf_ccm_data;
 #endif
 
 /**
- * ble phy rxpdu get
+ * Copies the data from the phy receive buffer into a mbuf chain.
  *
- * Gets a mbuf for PDU reception.
  *
- * @return struct os_mbuf* Pointer to retrieved mbuf or NULL if none available
+ * @param dptr Pointer to receive buffer
+ * @param len Length of receive buffer to copy.
+ *
+ * @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) {
+    /* 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);
-        } else {
-            /*
-             * NOTE: we add two bytes to the data pointer as we will prepend
-             * two bytes if we hand this received pdu up to host.
-             */
-            m->om_data += 2;
-            g_ble_phy_data.rxpdu = m;
+            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;
 }
 
 /**
@@ -243,11 +315,16 @@ nrf_wait_disabled(void)
 static void
 ble_phy_rx_xcvr_setup(void)
 {
+    uint8_t *dptr;
+
+    dptr = (uint8_t *)&g_ble_phy_rx_buf[0];
+    dptr += 3;
+
 #if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
     if (g_ble_phy_data.phy_encrypted) {
         NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
         NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-        NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+        NRF_CCM->OUTPTR = (uint32_t)dptr;
         NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
         NRF_CCM->MODE = CCM_MODE_LENGTH_Msk | CCM_MODE_MODE_Decryption;
         NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
@@ -256,17 +333,17 @@ ble_phy_rx_xcvr_setup(void)
         NRF_CCM->EVENTS_ENDCRYPT = 0;
         NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
     } else {
-        NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+        NRF_RADIO->PACKETPTR = (uint32_t)dptr;
     }
 #else
-    NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+    NRF_RADIO->PACKETPTR = (uint32_t)dptr;
 #endif
 
 #if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1)
     if (g_ble_phy_data.phy_privacy) {
         NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Enabled;
         NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
-        NRF_AAR->ADDRPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+        NRF_AAR->ADDRPTR = (uint32_t)dptr;
         NRF_AAR->SCRATCHPTR = (uint32_t)&g_ble_phy_data.phy_aar_scratch;
         NRF_AAR->EVENTS_END = 0;
         NRF_AAR->EVENTS_RESOLVED = 0;
@@ -308,16 +385,28 @@ ble_phy_rx_xcvr_setup(void)
 static void
 ble_phy_tx_end_isr(void)
 {
+    uint8_t was_encrypted;
     uint8_t transition;
     uint8_t txlen;
     uint32_t wfr_time;
+    uint32_t txstart;
+
+    /*
+     * Read captured tx start time. This is not the actual transmit start
+     * time but it is the time at which the address event occurred
+     * (after transmission of access address)
+     */
+    txstart = NRF_TIMER0->CC[1];
+
+    /* If this transmission was encrypted we need to remember it */
+    was_encrypted = g_ble_phy_data.phy_encrypted;
 
     /* Better be in TX state! */
     assert(g_ble_phy_data.phy_state == BLE_PHY_STATE_TX);
 
     /* Log the event */
-    ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_txrx_buf[0] >> 8) & 0xFF,
-               g_ble_phy_data.phy_encrypted, NRF_TIMER0->CC[1]);
+    ble_ll_log(BLE_LL_LOG_ID_PHY_TXEND, (g_ble_phy_tx_buf[0] >> 8) & 0xFF,
+               was_encrypted, txstart);
 
     /* Clear events and clear interrupt on disabled event */
     NRF_RADIO->EVENTS_DISABLED = 0;
@@ -330,7 +419,7 @@ ble_phy_tx_end_isr(void)
      * XXX: not sure what to do. We had a HW error during transmission.
      * For now I just count a stat but continue on like all is good.
      */
-    if (g_ble_phy_data.phy_encrypted) {
+    if (was_encrypted) {
         if (NRF_CCM->EVENTS_ERROR) {
             STATS_INC(ble_phy_stats, tx_hw_err);
             NRF_CCM->EVENTS_ERROR = 0;
@@ -338,26 +427,25 @@ ble_phy_tx_end_isr(void)
     }
 #endif
 
+    /* Call transmit end callback */
+    if (g_ble_phy_data.txend_cb) {
+        g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
+    }
+
     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) {
-            ble_phy_rx_xcvr_setup();
-        } else {
-            /* Disable the phy */
-            STATS_INC(ble_phy_stats, no_bufs);
-            ble_phy_disable();
-        }
+        ble_phy_rx_xcvr_setup();
 
         /*
          * Enable the wait for response timer. Note that cc #1 on
          * timer 0 contains the transmit start time
          */
         txlen = g_ble_phy_data.phy_tx_pyld_len;
-        if (txlen && g_ble_phy_data.phy_encrypted) {
+        if (txlen && was_encrypted) {
             txlen += BLE_LL_DATA_MIC_LEN;
         }
-        wfr_time = NRF_TIMER0->CC[1] - BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
+        wfr_time = txstart - BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
         wfr_time += BLE_TX_DUR_USECS_M(txlen);
         wfr_time += cputime_usecs_to_ticks(BLE_LL_WFR_USECS);
         ble_ll_wfr_enable(wfr_time);
@@ -366,11 +454,6 @@ ble_phy_tx_end_isr(void)
         NRF_PPI->CHENCLR = PPI_CHEN_CH20_Msk;
         assert(transition == BLE_PHY_TRANSITION_NONE);
     }
-
-    /* Call transmit end callback */
-    if (g_ble_phy_data.txend_cb) {
-        g_ble_phy_data.txend_cb(g_ble_phy_data.txend_arg);
-    }
 }
 
 static void
@@ -379,7 +462,6 @@ ble_phy_rx_end_isr(void)
     int rc;
     uint8_t *dptr;
     uint8_t crcok;
-    struct os_mbuf *rxpdu;
     struct ble_mbuf_hdr *ble_hdr;
 
     /* Clear events and clear interrupt */
@@ -390,11 +472,12 @@ ble_phy_rx_end_isr(void)
     NRF_PPI->CHENCLR = PPI_CHEN_CH21_Msk;
 
     /* Set RSSI and CRC status flag in header */
-    ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+    ble_hdr = &g_ble_phy_data.rxhdr;
     assert(NRF_RADIO->EVENTS_RSSIEND != 0);
     ble_hdr->rxinfo.rssi = -1 * NRF_RADIO->RSSISAMPLE;
 
-    dptr = g_ble_phy_data.rxpdu->om_data;
+    dptr = (uint8_t *)&g_ble_phy_rx_buf[0];
+    dptr += 3;
 
     /* Count PHY crc errors and valid packets */
     crcok = (uint8_t)NRF_RADIO->CRCSTATUS;
@@ -434,10 +517,6 @@ ble_phy_rx_end_isr(void)
 #endif
     }
 
-    /* Call Link Layer receive payload function */
-    rxpdu = g_ble_phy_data.rxpdu;
-    g_ble_phy_data.rxpdu = NULL;
-
     /*
      * XXX: This is a horrible ugly hack to deal with the RAM S1 byte
      * that is not sent over the air but is present here. Simply move the
@@ -445,9 +524,7 @@ ble_phy_rx_end_isr(void)
      */
     dptr[2] = dptr[1];
     dptr[1] = dptr[0];
-    rxpdu->om_data += 1;
-
-    rc = ble_ll_rx_end(rxpdu, ble_hdr);
+    rc = ble_ll_rx_end(dptr + 1, ble_hdr);
     if (rc < 0) {
         ble_phy_disable();
     }
@@ -464,8 +541,6 @@ ble_phy_rx_start_isr(void)
     NRF_RADIO->EVENTS_ADDRESS = 0;
     NRF_RADIO->INTENCLR = RADIO_INTENCLR_ADDRESS_Msk;
 
-    assert(g_ble_phy_data.rxpdu != NULL);
-
     /* Wait to get 1st byte of frame */
     while (1) {
         state = NRF_RADIO->STATE;
@@ -485,7 +560,7 @@ ble_phy_rx_start_isr(void)
     }
 
     /* Initialize flags, channel and state in ble header at rx start */
-    ble_hdr = BLE_MBUF_HDR_PTR(g_ble_phy_data.rxpdu);
+    ble_hdr = &g_ble_phy_data.rxhdr;
     ble_hdr->rxinfo.flags = ble_ll_state_get();
     ble_hdr->rxinfo.channel = g_ble_phy_data.phy_chan;
     ble_hdr->rxinfo.handle = 0;
@@ -493,7 +568,9 @@ ble_phy_rx_start_isr(void)
         BLE_TX_LEN_USECS_M(NRF_RX_START_OFFSET);
 
     /* 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((uint8_t *)&g_ble_phy_rx_buf[0] + 3,
+                         g_ble_phy_data.phy_chan,
+                         &g_ble_phy_data.rxhdr);
     if (rc >= 0) {
         /* Set rx started flag and enable rx end ISR */
         g_ble_phy_data.phy_rx_started = 1;
@@ -589,6 +666,7 @@ ble_phy_init(void)
                        RADIO_PCNF0_S1INCL_Msk                       |
                        (NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos)        |
                        (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos);
+
     /* XXX: should maxlen be 251 for encryption? */
     NRF_RADIO->PCNF1 = NRF_MAXLEN |
                        (RADIO_PCNF1_ENDIAN_Little <<  RADIO_PCNF1_ENDIAN_Pos) |
@@ -664,11 +742,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;
-    }
-
     /* Make sure all interrupts are disabled */
     NRF_RADIO->INTENCLR = NRF_RADIO_IRQ_MASK_ALL;
 
@@ -809,6 +882,7 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
 {
     int rc;
     uint8_t *dptr;
+    uint8_t *pktptr;
     uint8_t payload_len;
     uint32_t state;
     uint32_t shortcuts;
@@ -829,9 +903,11 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
 #if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
     if (g_ble_phy_data.phy_encrypted) {
         dptr = (uint8_t *)&g_ble_phy_enc_buf[0];
+        ++dptr;
+        pktptr = (uint8_t *)&g_ble_phy_tx_buf[0];
         NRF_CCM->SHORTS = 1;
-        NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
-        NRF_CCM->OUTPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
+        NRF_CCM->INPTR = (uint32_t)dptr;
+        NRF_CCM->OUTPTR = (uint32_t)pktptr;
         NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
         NRF_CCM->EVENTS_ERROR = 0;
         NRF_CCM->MODE = CCM_MODE_LENGTH_Msk;
@@ -843,13 +919,17 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
         NRF_PPI->CHENCLR = PPI_CHEN_CH23_Msk;
         NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
 #endif
-        dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
+        dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
+        ++dptr;
+        pktptr = dptr;
     }
 #else
 #if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1)
     NRF_PPI->CHENCLR = PPI_CHEN_CH23_Msk;
 #endif
-    dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
+    dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
+    ++dptr;
+    pktptr = dptr;
 #endif
 
     /* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
@@ -857,7 +937,7 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
     dptr[1] = payload_len;
     dptr[2] = 0;
     dptr += 3;
-    NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
+    NRF_RADIO->PACKETPTR = (uint32_t)pktptr;
 
     /* Clear the ready, end and disabled events */
     NRF_RADIO->EVENTS_READY = 0;
@@ -867,13 +947,10 @@ ble_phy_tx(struct os_mbuf *txpdu, uint8_t end_trans)
     /* Enable shortcuts for transmit start/end. */
     shortcuts = RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_READY_START_Msk;
     if (end_trans == BLE_PHY_TRANSITION_TX_RX) {
-        /* If we are going into receive after this, try to get a buffer. */
-        if (ble_phy_rxpdu_get()) {
-            shortcuts |= RADIO_SHORTS_DISABLED_RXEN_Msk;
-        }
+        shortcuts |= RADIO_SHORTS_DISABLED_RXEN_Msk;
     }
-    NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
     NRF_RADIO->SHORTS = shortcuts;
+    NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
 
     /* Set transmitted payload length */
     g_ble_phy_data.phy_tx_pyld_len = payload_len;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0888ff9a/net/nimble/include/nimble/nimble_opt.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/nimble_opt.h b/net/nimble/include/nimble/nimble_opt.h
index 319c08d..2fd8228 100644
--- a/net/nimble/include/nimble/nimble_opt.h
+++ b/net/nimble/include/nimble/nimble_opt.h
@@ -355,9 +355,7 @@
 #endif
 
 /*
- * This option allows a controller to send/receive LE pings. Currently,
- * this feature is not implemented by the controller so turning it on or off
- * has no effect.
+ * This option allows a controller to send/receive LE pings.
  */
 #ifndef BLE_LL_CFG_FEAT_LE_PING
 #define  BLE_LL_CFG_FEAT_LE_PING                (1)