diff --git a/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig b/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig index 562af07892c..70d46fd3d8e 100644 --- a/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig +++ b/configs/clicker2-stm32/mrf24j40-6lowpan/defconfig @@ -1145,7 +1145,7 @@ CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef CONFIG_MAC802154_HPWORK=y # CONFIG_MAC802154_LPWORK is not set CONFIG_MAC802154_NNOTIF=48 -CONFIG_IEEE802154_NTXDESC=32 +CONFIG_MAC802154_NTXDESC=32 CONFIG_IEEE802154_IND_PREALLOC=32 CONFIG_IEEE802154_IND_IRQRESERVE=10 CONFIG_IEEE802154_MACDEV=y diff --git a/configs/clicker2-stm32/mrf24j40-mac/defconfig b/configs/clicker2-stm32/mrf24j40-mac/defconfig index 00102b8a385..1cef0e395c8 100644 --- a/configs/clicker2-stm32/mrf24j40-mac/defconfig +++ b/configs/clicker2-stm32/mrf24j40-mac/defconfig @@ -985,7 +985,7 @@ CONFIG_WIRELESS_IEEE802154=y CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef CONFIG_MAC802154_HPWORK=y CONFIG_MAC802154_NNOTIF=6 -CONFIG_IEEE802154_NTXDESC=3 +CONFIG_MAC802154_NTXDESC=3 CONFIG_IEEE802154_IND_PREALLOC=20 CONFIG_IEEE802154_IND_IRQRESERVE=10 CONFIG_IEEE802154_MACDEV=y diff --git a/configs/sim/sixlowpan/defconfig b/configs/sim/sixlowpan/defconfig index 3c2ac60369b..01751fb2436 100644 --- a/configs/sim/sixlowpan/defconfig +++ b/configs/sim/sixlowpan/defconfig @@ -711,7 +711,7 @@ CONFIG_WIRELESS=y CONFIG_WIRELESS_IEEE802154=y CONFIG_IEEE802154_DEFAULT_EADDR=0x00fade00deadbeef CONFIG_MAC802154_HPWORK=y -CONFIG_IEEE802154_NTXDESC=3 +CONFIG_MAC802154_NTXDESC=3 CONFIG_IEEE802154_IND_PREALLOC=20 CONFIG_IEEE802154_IND_IRQRESERVE=10 # CONFIG_IEEE802154_MACDEV is not set diff --git a/drivers/wireless/ieee802154/at86rf23x.c b/drivers/wireless/ieee802154/at86rf23x.c index 2da26d3da94..3e4cd0ce11a 100644 --- a/drivers/wireless/ieee802154/at86rf23x.c +++ b/drivers/wireless/ieee802154/at86rf23x.c @@ -1533,22 +1533,22 @@ FAR struct ieee802154_radio_s *at86rf23x_init(FAR struct spi_dev_s *spi, /* Configure the Pan id */ - //at86rf23x_setpanid (&dev->ieee, IEEE802154_PAN_DEFAULT); + //at86rf23x_setpanid(&dev->ieee, IEEE802154_PAN_DEFAULT); /* Configure the Short Addr */ - //at86rf23x_setsaddr (&dev->ieee, IEEE802154_SADDR_UNSPEC); + //at86rf23x_setsaddr(&dev->ieee, IEEE802154_SADDR_UNSPEC); /* Configure the IEEE Addr */ - //at86rf23x_seteaddr (&dev->ieee, IEEE802154_EADDR_UNSPEC); + //at86rf23x_seteaddr(&dev->ieee, IEEE802154_EADDR_UNSPEC); /* Default device params at86rf23x defaults to energy detect only */ cca.use_ed = 1; cca.use_cs = 0; - cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED - * threshold -69 dBm */ + cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED + * threshold -69 dBm */ at86rf23x_setcca(&dev->ieee, &cca); /* Put the Device to RX ON Mode */ diff --git a/drivers/wireless/ieee802154/mrf24j40.c b/drivers/wireless/ieee802154/mrf24j40.c index 89ff1e69c19..6d6f814066b 100644 --- a/drivers/wireless/ieee802154/mrf24j40.c +++ b/drivers/wireless/ieee802154/mrf24j40.c @@ -247,6 +247,11 @@ static int mrf24j40_req_rxenable(FAR struct ieee802154_radio_s *radio, * Private Data ****************************************************************************/ +static const uint8_t g_allones[8] = +{ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + /**************************************************************************** * Radio Interface Functions ****************************************************************************/ @@ -1880,15 +1885,15 @@ FAR struct ieee802154_radio_s *mrf24j40_init(FAR struct spi_dev_s *spi, mrf24j40_initialize(dev); mrf24j40_setchannel(dev, 11); - mrf24j40_setpanid (dev, 0xFFFF); - mrf24j40_setsaddr (dev, 0xFFFF); - mrf24j40_seteaddr (dev, (uint8_t*)"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); + mrf24j40_setpanid(dev, g_allones); + mrf24j40_setsaddr(dev, g_allones); + mrf24j40_seteaddr(dev, g_allones); /* Default device params */ cca.use_ed = 1; cca.use_cs = 0; - cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED threshold -69 dBm */ + cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED threshold -69 dBm */ mrf24j40_setcca(dev, &cca); mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL); diff --git a/include/nuttx/net/ieee802154.h b/include/nuttx/net/ieee802154.h index 736141a3515..eba830024da 100644 --- a/include/nuttx/net/ieee802154.h +++ b/include/nuttx/net/ieee802154.h @@ -78,6 +78,10 @@ #define SIXLOWPAN_MAC_STDFRAME 127 +/* Space for a two byte FCS must be reserved at the end of the frame */ + +#define SIXLOWPAN_MAC_FCSSIZE 2 + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c index db420cbdd39..ed6d2d82edd 100644 --- a/net/sixlowpan/sixlowpan_framelist.c +++ b/net/sixlowpan/sixlowpan_framelist.c @@ -73,6 +73,18 @@ # error IOBs must be large enough to hold full IEEE802.14.5 frame #endif +/* A IOB must also be big enought to hold the maximum MAC header (25 bytes?) + * plus the FCS and have some amount of space left for the payload. + */ + +#if CONFIG_NET_6LOWPAN_FRAMELEN < (SIXLOWPAN_MAC_FCSSIZE + 25) +# error CONFIG_NET_6LOWPAN_FRAMELEN too small to hold a IEEE802.14.5 frame +#endif + +/* We must reserve space at the end of the frame for a 2-byte FCS */ + +#define SIXLOWPAN_FRAMELEN (CONFIG_NET_6LOWPAN_FRAMELEN - SIXLOWPAN_MAC_FCSSIZE) + /* There must be at least enough IOBs to hold the full MTU. Probably still * won't work unless there are a few more. */ @@ -371,7 +383,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* Check if we need to fragment the packet into several frames */ - if (buflen > (CONFIG_NET_6LOWPAN_FRAMELEN - g_frame_hdrlen)) + if (buflen > (SIXLOWPAN_FRAMELEN - g_frame_hdrlen)) { #ifdef CONFIG_NET_6LOWPAN_FRAG /* qhead will hold the generated frame list; frames will be @@ -429,7 +441,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, * bytes. */ - paysize = (CONFIG_NET_6LOWPAN_FRAMELEN - g_frame_hdrlen) & ~7; + paysize = (SIXLOWPAN_FRAMELEN - g_frame_hdrlen) & ~7; memcpy(fptr + g_frame_hdrlen, buf, paysize); /* Set outlen to what we already sent from the IP payload */ @@ -501,7 +513,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* Copy payload and enqueue */ /* Check for the last fragment */ - paysize = (CONFIG_NET_6LOWPAN_FRAMELEN - fragn_hdrlen) & + paysize = (SIXLOWPAN_FRAMELEN - fragn_hdrlen) & SIXLOWPAN_DISPATCH_FRAG_MASK; if (buflen - outlen < paysize) { diff --git a/net/sixlowpan/sixlowpan_hc06.c b/net/sixlowpan/sixlowpan_hc06.c index e066da19b5a..c6681b2724e 100644 --- a/net/sixlowpan/sixlowpan_hc06.c +++ b/net/sixlowpan/sixlowpan_hc06.c @@ -68,13 +68,6 @@ #ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06 -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define UDPIPv6BUF(ieee) \ - ((FAR struct udp_hdr_s *)&((ieee)->i_dev.d_buf[IPv6_HDRLEN])) - /**************************************************************************** * Private Types ****************************************************************************/ @@ -760,9 +753,12 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, if (ipv6->proto == IP_PROTO_UDP) { - FAR struct udp_hdr_s *udp = UDPIPv6BUF(ieee); + /* The UDP header will follow the IPv6 header */ - ninfo("Uncompressed UDP ports on send side: %x, %x\n", + FAR struct udp_hdr_s *udp = + (FAR struct udp_hdr_s *)((FAR uint8_t *)ipv6 + IPv6_HDRLEN); + + ninfo("Uncompressed UDP ports on send side: srcport=%04x destport=%04x\n", ntohs(udp->srcport), ntohs(udp->destport)); /* Mask out the last 4 bits can be used as a mask */ diff --git a/net/sixlowpan/sixlowpan_utils.c b/net/sixlowpan/sixlowpan_utils.c index a7e80bc09d7..97eb856b929 100644 --- a/net/sixlowpan/sixlowpan_utils.c +++ b/net/sixlowpan/sixlowpan_utils.c @@ -89,7 +89,8 @@ void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr, { DEBUGASSERT(ipaddr[0] == HTONS(0xfe80)); - memcpy(saddr, &ipaddr[7], NET_6LOWPAN_SADDRSIZE); + saddr->u8[0] = ipaddr[7] >> 8; + saddr->u8[1] = ipaddr[7] & 0xff; saddr->u8[0] ^= 0x02; } diff --git a/wireless/ieee802154/Kconfig b/wireless/ieee802154/Kconfig index b5360ab782b..f6a93d709a5 100644 --- a/wireless/ieee802154/Kconfig +++ b/wireless/ieee802154/Kconfig @@ -23,14 +23,23 @@ config IEEE802154_DEFAULT_EADDR choice prompt "IEEE 802.15.4 work queue" - default MAC802154_LPWORK if SCHED_LPWORK - default MAC802154_HPWORK if !SCHED_LPWORK && SCHED_HPWORK + default MAC802154_HPWORK if SCHED_HPWORK + default MAC802154_LPWORK if !SCHED_HPWORK && SCHED_LPWORK depends on SCHED_WORKQUEUE ---help--- Work queue support is required to use the IEEE 802.15.4 MAC layer. - If the low priority work queue is available, then it should be used by + If the high priority work queue is available, then it should be used by the driver. + WARNING!! The IEEE802.15.4 network device must never run on the same + work queue as does the IEEE 802.15.4 MAC. That configuration will + cause deadlocks: The network logic may be blocked on the work queue + waiting on resources that can only be freed by the MAC logic but the + MAC is unable to run because the work queue is blocked. The + recommended configuration is: Network on the LP work queue; MAC on HP + work queue. Blocking on the HP work queue is a very bad thing in + any case. + config MAC802154_HPWORK bool "High priority" depends on SCHED_HPWORK @@ -41,13 +50,7 @@ config MAC802154_LPWORK endchoice # Work queue -config MAC802154_NNOTIF - int "Number of Notifers" - default 6 - ---help--- - This value must be larger than CONFIG_IEEE802154_NTDESC. - -config IEEE802154_NTXDESC +config MAC802154_NTXDESC int "Number or TX descriptors" default 3 ---help--- @@ -56,10 +59,20 @@ config IEEE802154_NTXDESC When used with 6LoWPAN, the descriptor allocator runs on a work and must avoid blocking if possible. Each frame will be provided in an IOB and each TX frame will need a TX descriptor. So the safe - thing to do is set CONFIG_IEEE802154_NTXDESC to CONFIG_IOB_NBUFFERS. + thing to do is set CONFIG_MAC802154_NTXDESC to CONFIG_IOB_NBUFFERS. Then there should be the maximum pre-allocated buffers for each possible TX frame. +config MAC802154_NNOTIF + int "Number or notification structures" + default 3 + ---help--- + Configured number of notification strucures Default: 3 + + When various MAC management events occur, the MAC notifies the registered + receiver with an allocated notification structure indicating the event. The + events are primitives such as Association Indication etc. + config IEEE802154_IND_PREALLOC int "Number of pre-allocated meta-data structures" default 20 @@ -155,9 +168,18 @@ choice depends on SCHED_WORKQUEUE ---help--- Work queue support is required to use the IEEE802.15.4 network - driver. If the low priority work queue is available, then it shoul + driver. If the low priority work queue is available, then it should be used by the loopback driver. + WARNING!! The IEEE802.15.4 network device must never run on the same + work queue as does the IEEE 802.15.4 MAC. That configuration will + cause deadlocks: The network logic may be blocked on the work queue + waiting on resources that can only be freed by the MAC logic but the + MAC is unable to run because the work queue is blocked. The + recommended configuration is: Network on the LP work queue; MAC on HP + work queue. Blocking on the HP work queue is a very bad thing in + any case. + config IEEE802154_NETDEV_HPWORK bool "High priority" depends on SCHED_HPWORK diff --git a/wireless/ieee802154/mac802154.c b/wireless/ieee802154/mac802154.c index 012139204f3..b161c57f1e9 100644 --- a/wireless/ieee802154/mac802154.c +++ b/wireless/ieee802154/mac802154.c @@ -126,12 +126,12 @@ static void mac802154_resetqueues(FAR struct ieee802154_privmac_s *priv) /* Initialize the tx descriptor allocation pool */ sq_init(&priv->txdesc_queue); - for (i = 0; i < CONFIG_IEEE802154_NTXDESC; i++) + for (i = 0; i < CONFIG_MAC802154_NTXDESC; i++) { sq_addlast((FAR sq_entry_t *)&priv->txdesc_pool[i], &priv->txdesc_queue); } - sem_init(&priv->txdesc_sem, 0, CONFIG_IEEE802154_NTXDESC); + sem_init(&priv->txdesc_sem, 0, CONFIG_MAC802154_NTXDESC); /* Initialize the notifcation allocation pool */ @@ -235,7 +235,7 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, } /**************************************************************************** - * Name: mac802154_create_datareq + * Name: mac802154_createdatareq * * Description: * Internal function used by various parts of the MAC layer. This function @@ -247,10 +247,10 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, * ****************************************************************************/ -void mac802154_create_datareq(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_addr_s *coordaddr, - enum ieee802154_addrmode_e srcmode, - FAR struct ieee802154_txdesc_s *txdesc) +void mac802154_createdatareq(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_addr_s *coordaddr, + enum ieee802154_addrmode_e srcmode, + FAR struct ieee802154_txdesc_s *txdesc) { FAR struct iob_s *iob; @@ -947,8 +947,8 @@ static void mac802154_rxframe_worker(FAR void *arg) * operation. * * mac802154_txdesc_alloc(priv, &respdec, false); - * mac802154_create_datareq(priv, &req->coordaddr, - * IEEE802154_ADDRMODE_EXTENDED, respdesc); + * mac802154_createdatareq(priv, &req->coordaddr, + * IEEE802154_ADDRMODE_EXTENDED, respdesc); * sq_addlast((FAR sq_entry_t *)respdesc, &priv->csma_queue); */ } diff --git a/wireless/ieee802154/mac802154_assoc.c b/wireless/ieee802154/mac802154_assoc.c index fd31623d200..494f6d519cb 100644 --- a/wireless/ieee802154/mac802154_assoc.c +++ b/wireless/ieee802154/mac802154_assoc.c @@ -492,8 +492,8 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, mac802154_txdesc_alloc(priv, &respdesc, false); - mac802154_create_datareq(priv, &priv->coordaddr, - IEEE802154_ADDRMODE_EXTENDED, respdesc); + mac802154_createdatareq(priv, &priv->coordaddr, + IEEE802154_ADDRMODE_EXTENDED, respdesc); priv->curr_cmd = IEEE802154_CMD_DATA_REQ; diff --git a/wireless/ieee802154/mac802154_internal.h b/wireless/ieee802154/mac802154_internal.h index d9df64d8516..ad3c23cc439 100644 --- a/wireless/ieee802154/mac802154_internal.h +++ b/wireless/ieee802154/mac802154_internal.h @@ -177,13 +177,13 @@ # define CONFIG_MAC802154_NNOTIF 6 #endif -#if !defined(CONFIG_IEEE802154_NTXDESC) || CONFIG_IEEE802154_NTXDESC <= 0 -# undef CONFIG_IEEE802154_NTXDESC -# define CONFIG_IEEE802154_NTXDESC 3 +#if !defined(CONFIG_MAC802154_NTXDESC) || CONFIG_MAC802154_NTXDESC <= 0 +# undef CONFIG_MAC802154_NTXDESC +# define CONFIG_MAC802154_NTXDESC 3 #endif -#if CONFIG_IEEE802154_NTXDESC > CONFIG_MAC802154_NNOTIF -# error CONFIG_MAC802154_NNOTIF must be greater than CONFIG_IEEE802154_NTXDESC +#if CONFIG_MAC802154_NTXDESC > CONFIG_MAC802154_NNOTIF +# error CONFIG_MAC802154_NNOTIF must be greater than CONFIG_MAC802154_NTXDESC #endif #if !defined(CONFIG_IEEE802154_DEFAULT_EADDR) @@ -258,7 +258,7 @@ struct ieee802154_privmac_s struct mac802154_notif_s notif_pool[CONFIG_MAC802154_NNOTIF]; sem_t notif_sem; - struct ieee802154_txdesc_s txdesc_pool[CONFIG_IEEE802154_NTXDESC]; + struct ieee802154_txdesc_s txdesc_pool[CONFIG_MAC802154_NTXDESC]; sem_t txdesc_sem; sq_queue_t txdesc_queue; sq_queue_t txdone_queue; @@ -481,8 +481,8 @@ static inline int mac802154_timercancel(FAR struct ieee802154_privmac_s *priv) int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_txdesc_s **txdesc, - bool allow_interrupt); + FAR struct ieee802154_txdesc_s **txdesc, + bool allow_interrupt); int mac802154_timerstart(FAR struct ieee802154_privmac_s *priv, uint32_t numsymbols, mac802154_worker_t); @@ -490,9 +490,10 @@ int mac802154_timerstart(FAR struct ieee802154_privmac_s *priv, void mac802154_setupindirect(FAR struct ieee802154_privmac_s *priv, FAR struct ieee802154_txdesc_s *txdesc); -void mac802154_create_datareq(FAR struct ieee802154_privmac_s *priv, - FAR struct ieee802154_addr_s *coordaddr, - enum ieee802154_addrmode_e srcmode, - FAR struct ieee802154_txdesc_s *txdesc); +void mac802154_createdatareq(FAR struct ieee802154_privmac_s *priv, + FAR struct ieee802154_addr_s *coordaddr, + enum ieee802154_addrmode_e srcmode, + FAR struct ieee802154_txdesc_s *txdesc); + #endif /* __WIRELESS_IEEE802154__MAC802154_INTERNAL_H */ diff --git a/wireless/ieee802154/mac802154_poll.c b/wireless/ieee802154/mac802154_poll.c index f82ba91f3d8..12a0f26726f 100644 --- a/wireless/ieee802154/mac802154_poll.c +++ b/wireless/ieee802154/mac802154_poll.c @@ -133,13 +133,13 @@ int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req) if (IEEE802154_SADDRCMP(priv->addr.saddr, &IEEE802154_SADDR_BCAST)) { - mac802154_create_datareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_EXTENDED, - txdesc); + mac802154_createdatareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_EXTENDED, + txdesc); } else { - mac802154_create_datareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_SHORT, - txdesc); + mac802154_createdatareq(priv, &req->coordaddr, IEEE802154_ADDRMODE_SHORT, + txdesc); } /* Save a copy of the destination addressing infromation into the tx descriptor.