From a73edd885df4d26923f0909208ac429e9bd692ff Mon Sep 17 00:00:00 2001 From: Fabian Montero Date: Fri, 18 Oct 2024 22:59:14 -0600 Subject: [PATCH] fix race condition --- .gitignore | 1 + lora_sx127.c | 93 +++++++++++++++++++++++++--------------------------- 2 files changed, 45 insertions(+), 49 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f5f242b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +copy.sh diff --git a/lora_sx127.c b/lora_sx127.c index 3177e7e..381a05b 100644 --- a/lora_sx127.c +++ b/lora_sx127.c @@ -37,9 +37,10 @@ * */ -#define DEBUG #define SX127X_LEGACY_KERNEL +#define DEBUG + #include #include #include @@ -50,28 +51,9 @@ #include #include -#ifndef F_XOSC -#define F_XOSC 32000000 -#endif -static u32 xosc_frq = F_XOSC; -module_param(xosc_frq, uint, 0000); -MODULE_PARM_DESC(xosc_frq, "Crystal oscillator frequency of the LoRa chip"); - -#define __POW_2_19 0x80000 - -#ifndef SX127X_SPRF -#define SX127X_SPRF 512 -#endif -static u32 sprf = SX127X_SPRF; -module_param(sprf, uint, 0000); -MODULE_PARM_DESC(sprf, "Spreading factor of Chirp Spread Spectrum modulation"); - -#ifndef SX127X_RX_BYTE_TIMEOUT -#define SX127X_RX_BYTE_TIMEOUT 1023 -#endif -static u32 rx_timeout = SX127X_RX_BYTE_TIMEOUT; -module_param(rx_timeout, uint, 0000); -MODULE_PARM_DESC(rx_timeout, "RX time-out value as number of symbols"); +static unsigned tx_poll_div = 10; +module_param(tx_poll_div, uint, 0000); +MODULE_PARM_DESC(tx_poll_div, "Number of RX poll cycles to perform before attempting a single TX op"); /* SX127X Registers addresses */ #define SX127X_REG_FIFO 0x00 @@ -167,10 +149,6 @@ MODULE_PARM_DESC(rx_timeout, "RX time-out value as number of symbols"); #define SX127X_MODEM_CONFIG1_HEADER_MODE_EXPLICIT 0x00 #define SX127X_MODEM_CONFIG1_HEADER_MODE_IMPLICIT 0x01 -#define SX127X_MODEM_CONFIG2_RXPAYLOADCRCON 0x04 - -#define SX127X_MODEM_CONFIG3_AGCAUTOON 0x04 - /* SX127X's RX/TX FIFO base address */ #define SX127X_FIFO_RX_BASE_ADDRESS 0x00 #define SX127X_FIFO_TX_BASE_ADDRESS 0x80 @@ -186,6 +164,7 @@ struct sx127x { bool busy; struct sk_buff *tx_skb; size_t delayed_tx_length; + unsigned tx_wait; struct timer_list poll_timer; struct work_struct poll_work; @@ -316,7 +295,7 @@ static int sx127x_set_tx_power(struct sx127x *hw, int level) static int sx127x_init(struct sx127x *hw, u8 *major, u8 *minor) { - u8 modem_config1, modem_config2, lna, version; + u8 modem_config1, lna, version; int ret; ret = sx127x_reg_read(hw, SX127X_REG_VERSION, &version); @@ -358,23 +337,14 @@ static int sx127x_init(struct sx127x *hw, u8 *major, u8 *minor) if (ret < 0) return ret; - ret = sx127x_reg_read(hw, SX127X_REG_MODEM_CONFIG2, &modem_config2); - if (ret < 0) - return ret; - modem_config1 &= ~SX127X_MODEM_CONFIG1_HEADER_MODE_MASK; modem_config1 |= SX127X_MODEM_CONFIG1_HEADER_MODE_EXPLICIT; - modem_config2 |= SX127X_MODEM_CONFIG2_RXPAYLOADCRCON; ret = sx127x_reg_write(hw, SX127X_REG_MODEM_CONFIG1, modem_config1); if (ret < 0) return ret; - ret = sx127x_reg_write(hw, SX127X_REG_MODEM_CONFIG2, modem_config2); - if (ret < 0) - return ret; - - ret = sx127x_reg_write(hw, SX127X_REG_MODEM_CONFIG3, SX127X_MODEM_CONFIG3_AGCAUTOON); + ret = sx127x_reg_write(hw, SX127X_REG_MODEM_CONFIG3, 0x4); if (ret < 0) return ret; @@ -493,7 +463,7 @@ static void sx127x_poll_work(struct work_struct *work) goto exit_busy; ack_flags = 0; - + if (read_flags & SX127X_FLAG_TXDONE) ack_flags |= SX127X_FLAG_TXDONE; else @@ -526,9 +496,6 @@ static void sx127x_poll_work(struct work_struct *work) if (!rx_skb) goto exit_busy; - if (rx_length > IEEE802154_MTU) - rx_length = IEEE802154_MTU; - rx_data = skb_put(rx_skb, rx_length); while (rx_length--) if (sx127x_reg_read(hw, SX127X_REG_FIFO, rx_data++) < 0) @@ -545,7 +512,10 @@ static void sx127x_poll_work(struct work_struct *work) goto exit_busy; if ((mode & SX127X_MODE_MASK) != SX127X_TX_MODE) { - if (hw->delayed_tx_length) { + if (++hw->tx_wait >= tx_poll_div) + hw->tx_wait = 0; + + if (hw->delayed_tx_length && hw->tx_wait == 0) { sx127x_mode(hw, SX127X_TX_MODE); hw->delayed_tx_length = 0; } else if ((mode & SX127X_MODE_MASK) != SX127X_RXCONTINUOUS_MODE) @@ -562,14 +532,14 @@ exit_busy: if (rx_skb) kfree_skb(rx_skb); - if (tx_skb) - ieee802154_xmit_complete(hw->ieee, tx_skb, false); - spin_lock_irqsave(&hw->lock, spin_irq); hw->busy = false; if (tx_skb) hw->tx_skb = NULL; spin_unlock_irqrestore(&hw->lock, spin_irq); + + if (tx_skb) + ieee802154_xmit_complete(hw->ieee, tx_skb, false); } static void sx127x_poll_timer(struct timer_list *timer) @@ -592,7 +562,9 @@ static int sx127x_802154_xmit_async(struct ieee802154_hw *ieee, struct sk_buff * ret = -EBUSY; spin_unlock_irqrestore(&hw->lock, spin_irq); - schedule_work(&hw->tx_work); + if (!ret) + schedule_work(&hw->tx_work); + return ret; } @@ -629,7 +601,6 @@ static int sx127x_802154_start(struct ieee802154_hw *ieee) } mod_timer(&hw->poll_timer, jiffies + POLL_JIFFIES); - dev_dbg(regmap_get_device(hw->regmap), "%s\n", __func__); return 0; } @@ -641,7 +612,6 @@ static void sx127x_802154_stop(struct ieee802154_hw *ieee) cancel_work_sync(&hw->poll_work); (void) sx127x_mode(hw, SX127X_SLEEP_MODE); - dev_dbg(regmap_get_device(hw->regmap), "%s\n", __func__); } static int sx127x_802154_set_promiscuous_mode(struct ieee802154_hw *ieee, const bool on) @@ -700,6 +670,7 @@ static int sx127x_spi_probe(struct spi_device *spi) hw->spi = spi; hw->ieee = ieee; hw->busy = false; + hw->tx_wait = 0; hw->delayed_tx_length = 0; spin_lock_init(&hw->lock); @@ -774,6 +745,30 @@ static int sx127x_spi_probe(struct spi_device *spi) dev_err(&spi->dev, "ieee802154_register_hw() failed: %d\n", ret); return ret; + /*u8 buffer[] = { 0x36, 0x39 }; // 69? + ret = sx127x_mode(hw, SX127X_STANDBY_MODE); + if (ret < 0) { + dev_err(&spi->dev, "%s: sx127x_mode() failed: %d\n", __func__, ret); + goto fail_begin; + } + + ret = sx127x_begin_packet(hw); + if (ret < 0) { + dev_err(&spi->dev, "%s: sx127x_begin_packet() failed: %d\n", __func__, ret); + goto fail_begin; + } + + ret = sx127x_write_buffer(hw, buffer, sizeof buffer); + if (ret < 0) { + dev_err(&spi->dev, "%s: sx127x_send() failed: %d\n", __func__, ret); + goto fail_begin; + } + + ret = sx127x_end_packet(hw, 0); + if (ret < 0) { + dev_err(&spi->dev, "%s: sx127x_end_packet() failed: %d\n", __func__, ret); + goto fail_begin; + }*/ fail_init: ieee802154_free_hw(ieee);