Information such as spreading factor, coding rate and power are on a per
transmission basis so it makes sence to include this in a header much
like CAN frames do.

Signed-off-by: Ben Whitten <ben.whit...@lairdtech.com>
---
 drivers/net/lora/dev.c    |  2 -
 drivers/net/lora/sx1301.c | 79 +++++++++++++++++++++++++++++++++------
 include/uapi/linux/lora.h | 46 +++++++++++++++++++++++
 3 files changed, 114 insertions(+), 13 deletions(-)

diff --git a/drivers/net/lora/dev.c b/drivers/net/lora/dev.c
index 0d4823de8c06..62dbe21668b0 100644
--- a/drivers/net/lora/dev.c
+++ b/drivers/net/lora/dev.c
@@ -11,8 +11,6 @@
 #include <linux/lora/skb.h>
 #include <net/rtnetlink.h>
 
-#define LORA_MTU 256 /* XXX */
-
 struct sk_buff *alloc_lora_skb(struct net_device *dev, u8 **data)
 {
        struct sk_buff *skb;
diff --git a/drivers/net/lora/sx1301.c b/drivers/net/lora/sx1301.c
index 9bcbb967f307..fed6d6201bf3 100644
--- a/drivers/net/lora/sx1301.c
+++ b/drivers/net/lora/sx1301.c
@@ -584,7 +584,7 @@ static int sx1301_load_tx_gain_lut(struct sx1301_priv *priv)
        return ret;
 };
 
-static int sx1301_tx(struct sx1301_priv *priv, void *data, int len)
+static int sx1301_tx(struct sx1301_priv *priv, struct lora_frame *frame)
 {
        int ret, i;
        u8 buff[256 + 16];
@@ -617,11 +617,67 @@ static int sx1301_tx(struct sx1301_priv *priv, void 
*data, int len)
        hdr->tx_power = 15; /* HACK power entry 15 */
 
        hdr->u.lora.crc16_en = 1; /* Enable CRC16 */
-       hdr->u.lora.cr = 1; /* CR 4/5 */
-       hdr->u.lora.sf = 7; /* SF7 */
-       hdr->u.lora.payload_len = len; /* Set the data len to the skb len */
+
+       switch (frame->cr) {
+       case LORA_CR_4_5:
+               hdr->u.lora.cr = 1; /* CR 4/5 */
+               break;
+       case LORA_CR_4_6:
+               hdr->u.lora.cr = 2; /* CR 4/6 */
+               break;
+       case LORA_CR_4_7:
+               hdr->u.lora.cr = 3; /* CR 4/7 */
+               break;
+       case LORA_CR_4_8:
+               hdr->u.lora.cr = 4; /* CR 4/8 */
+               break;
+       default:
+               return -ENXIO;
+       }
+
+       switch (frame->sf) {
+       case LORA_SF_6:
+               hdr->u.lora.sf = 6; /* SF6 */
+               break;
+       case LORA_SF_7:
+               hdr->u.lora.sf = 7; /* SF7 */
+               break;
+       case LORA_SF_8:
+               hdr->u.lora.sf = 8; /* SF8 */
+               break;
+       case LORA_SF_9:
+               hdr->u.lora.sf = 9; /* SF9 */
+               break;
+       case LORA_SF_10:
+               hdr->u.lora.sf = 10; /* SF10 */
+               break;
+       case LORA_SF_11:
+               hdr->u.lora.sf = 11; /* SF11 */
+               break;
+       case LORA_SF_12:
+               hdr->u.lora.sf = 12; /* SF12 */
+               break;
+       default:
+               return -ENXIO;
+       }
+
+       hdr->u.lora.payload_len = frame->len; /* Set the data length */
        hdr->u.lora.implicit_header = 0; /* No implicit header */
-       hdr->u.lora.mod_bw = 0; /* Set 125KHz BW */
+
+       switch (frame->bw) {
+       case LORA_BW_125KHZ:
+               hdr->u.lora.mod_bw = 0; /* 125KHz BW */
+               break;
+       case LORA_BW_250KHZ:
+               hdr->u.lora.mod_bw = 1; /* 250KHz BW */
+               break;
+       case LORA_BW_500KHZ:
+               hdr->u.lora.mod_bw = 2; /* 500KHz BW */
+               break;
+       default:
+               return -ENXIO;
+       }
+
        hdr->u.lora.ppm_offset = 0; /* TODO no ppm offset? */
        hdr->u.lora.invert_pol = 0; /* TODO set no inverted polarity */
 
@@ -632,7 +688,7 @@ static int sx1301_tx(struct sx1301_priv *priv, void *data, 
int len)
 
        /* Copy the TX data into the buffer ready to go */
 
-       memcpy((void *)&buff[16], data, len);
+       memcpy((void *)&buff[16], frame->data, frame->len);
 
        /* Reset any transmissions */
        ret = regmap_write(priv->regmap, SX1301_TX_TRIG, 0);
@@ -644,7 +700,7 @@ static int sx1301_tx(struct sx1301_priv *priv, void *data, 
int len)
        if (ret)
                return ret;
        ret = regmap_noinc_write(priv->regmap, SX1301_TX_DATA_BUF_DATA, buff,
-                                len + 16);
+                                frame->len + 16);
        if (ret)
                return ret;
 
@@ -653,8 +709,8 @@ static int sx1301_tx(struct sx1301_priv *priv, void *data, 
int len)
        if (ret)
                return ret;
 
-       dev_dbg(priv->dev, "Transmitting packet of size %d: ", len);
-       for (i = 0; i < len + 16; i++)
+       dev_dbg(priv->dev, "Transmitting packet of size %d: ", frame->len);
+       for (i = 0; i < frame->len + 16; i++)
                dev_dbg(priv->dev, "%X", buff[i]);
 
        return ret;
@@ -683,17 +739,18 @@ static void sx1301_tx_work_handler(struct work_struct *ws)
        struct sx1301_priv *priv = container_of(ws, struct sx1301_priv,
                                                tx_work);
        struct net_device *netdev = dev_get_drvdata(priv->dev);
+       struct lora_frame *frame = (struct lora_frame *)priv->tx_skb->data;
        int ret;
 
        netdev_dbg(netdev, "%s\n", __func__);
 
        if (priv->tx_skb) {
-               ret = sx1301_tx(priv, priv->tx_skb->data, priv->tx_skb->len);
+               ret = sx1301_tx(priv, frame);
                if (ret) {
                        netdev->stats.tx_errors++;
                } else {
                        netdev->stats.tx_packets++;
-                       netdev->stats.tx_bytes += priv->tx_skb->len;
+                       netdev->stats.tx_bytes += frame->len;
                }
 
                if (!(netdev->flags & IFF_ECHO) ||
diff --git a/include/uapi/linux/lora.h b/include/uapi/linux/lora.h
index 4ff00b9c3c20..d675025d2a6e 100644
--- a/include/uapi/linux/lora.h
+++ b/include/uapi/linux/lora.h
@@ -21,4 +21,50 @@ struct sockaddr_lora {
        } lora_addr;
 };
 
+#define LORA_MAX_DLEN  256
+
+enum lora_bw {
+       LORA_BW_125KHZ,
+       LORA_BW_250KHZ,
+       LORA_BW_500KHZ,
+};
+
+enum lora_cr {
+       LORA_CR_4_5,
+       LORA_CR_4_6,
+       LORA_CR_4_7,
+       LORA_CR_4_8,
+};
+
+enum lora_sf {
+       LORA_SF_6,
+       LORA_SF_7,
+       LORA_SF_8,
+       LORA_SF_9,
+       LORA_SF_10,
+       LORA_SF_11,
+       LORA_SF_12,
+};
+
+/**
+ * struct lora_frame - LoRa frame structure
+ * @freq: Frequency of LoRa transmission in Hz
+ * @power: Power of transmission in dBm
+ * @bw:  bandwidth, 125, 250 or 500 KHz
+ * @cr:  coding rate, 4/5 to 4/8
+ * @sf:  spreading factor from SF6 to 12
+ * @data:   LoRa frame payload (up to LORA_MAX_DLEN byte)
+ */
+struct lora_frame {
+       __u32           freq; /* transmission frequency in Hz */
+       __u8            power; /* transmission power in dBm */
+       enum lora_bw    bw; /* bandwidth */
+       enum lora_cr    cr; /* coding rate */
+       enum lora_sf    sf; /* spreading factor */
+       __u8            len;
+       __u8            data[LORA_MAX_DLEN] __attribute__((aligned(8)));
+};
+
+#define LORA_MTU (sizeof(struct lora_frame))
+
 #endif /* _UAPI_LINUX_LORA_H */
-- 
2.17.1

Reply via email to