fix race condition

This commit is contained in:
Fabian Montero 2024-10-18 22:59:14 -06:00
parent d238c8b1cd
commit a73edd885d
Signed by: fabian
GPG key ID: 1FFAC35E1798174F
2 changed files with 45 additions and 49 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
copy.sh

View file

@ -37,9 +37,10 @@
* *
*/ */
#define DEBUG
#define SX127X_LEGACY_KERNEL #define SX127X_LEGACY_KERNEL
#define DEBUG
#include <linux/module.h> #include <linux/module.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/device.h> #include <linux/device.h>
@ -50,28 +51,9 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <net/mac802154.h> #include <net/mac802154.h>
#ifndef F_XOSC static unsigned tx_poll_div = 10;
#define F_XOSC 32000000 module_param(tx_poll_div, uint, 0000);
#endif MODULE_PARM_DESC(tx_poll_div, "Number of RX poll cycles to perform before attempting a single TX op");
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");
/* SX127X Registers addresses */ /* SX127X Registers addresses */
#define SX127X_REG_FIFO 0x00 #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_EXPLICIT 0x00
#define SX127X_MODEM_CONFIG1_HEADER_MODE_IMPLICIT 0x01 #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 */ /* SX127X's RX/TX FIFO base address */
#define SX127X_FIFO_RX_BASE_ADDRESS 0x00 #define SX127X_FIFO_RX_BASE_ADDRESS 0x00
#define SX127X_FIFO_TX_BASE_ADDRESS 0x80 #define SX127X_FIFO_TX_BASE_ADDRESS 0x80
@ -186,6 +164,7 @@ struct sx127x {
bool busy; bool busy;
struct sk_buff *tx_skb; struct sk_buff *tx_skb;
size_t delayed_tx_length; size_t delayed_tx_length;
unsigned tx_wait;
struct timer_list poll_timer; struct timer_list poll_timer;
struct work_struct poll_work; 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) 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; int ret;
ret = sx127x_reg_read(hw, SX127X_REG_VERSION, &version); 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) if (ret < 0)
return ret; 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_MASK;
modem_config1 |= SX127X_MODEM_CONFIG1_HEADER_MODE_EXPLICIT; 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); ret = sx127x_reg_write(hw, SX127X_REG_MODEM_CONFIG1, modem_config1);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = sx127x_reg_write(hw, SX127X_REG_MODEM_CONFIG2, modem_config2); ret = sx127x_reg_write(hw, SX127X_REG_MODEM_CONFIG3, 0x4);
if (ret < 0)
return ret;
ret = sx127x_reg_write(hw, SX127X_REG_MODEM_CONFIG3, SX127X_MODEM_CONFIG3_AGCAUTOON);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -493,7 +463,7 @@ static void sx127x_poll_work(struct work_struct *work)
goto exit_busy; goto exit_busy;
ack_flags = 0; ack_flags = 0;
if (read_flags & SX127X_FLAG_TXDONE) if (read_flags & SX127X_FLAG_TXDONE)
ack_flags |= SX127X_FLAG_TXDONE; ack_flags |= SX127X_FLAG_TXDONE;
else else
@ -526,9 +496,6 @@ static void sx127x_poll_work(struct work_struct *work)
if (!rx_skb) if (!rx_skb)
goto exit_busy; goto exit_busy;
if (rx_length > IEEE802154_MTU)
rx_length = IEEE802154_MTU;
rx_data = skb_put(rx_skb, rx_length); rx_data = skb_put(rx_skb, rx_length);
while (rx_length--) while (rx_length--)
if (sx127x_reg_read(hw, SX127X_REG_FIFO, rx_data++) < 0) 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; goto exit_busy;
if ((mode & SX127X_MODE_MASK) != SX127X_TX_MODE) { 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); sx127x_mode(hw, SX127X_TX_MODE);
hw->delayed_tx_length = 0; hw->delayed_tx_length = 0;
} else if ((mode & SX127X_MODE_MASK) != SX127X_RXCONTINUOUS_MODE) } else if ((mode & SX127X_MODE_MASK) != SX127X_RXCONTINUOUS_MODE)
@ -562,14 +532,14 @@ exit_busy:
if (rx_skb) if (rx_skb)
kfree_skb(rx_skb); kfree_skb(rx_skb);
if (tx_skb)
ieee802154_xmit_complete(hw->ieee, tx_skb, false);
spin_lock_irqsave(&hw->lock, spin_irq); spin_lock_irqsave(&hw->lock, spin_irq);
hw->busy = false; hw->busy = false;
if (tx_skb) if (tx_skb)
hw->tx_skb = NULL; hw->tx_skb = NULL;
spin_unlock_irqrestore(&hw->lock, spin_irq); 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) 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; ret = -EBUSY;
spin_unlock_irqrestore(&hw->lock, spin_irq); spin_unlock_irqrestore(&hw->lock, spin_irq);
schedule_work(&hw->tx_work); if (!ret)
schedule_work(&hw->tx_work);
return ret; return ret;
} }
@ -629,7 +601,6 @@ static int sx127x_802154_start(struct ieee802154_hw *ieee)
} }
mod_timer(&hw->poll_timer, jiffies + POLL_JIFFIES); mod_timer(&hw->poll_timer, jiffies + POLL_JIFFIES);
dev_dbg(regmap_get_device(hw->regmap), "%s\n", __func__);
return 0; return 0;
} }
@ -641,7 +612,6 @@ static void sx127x_802154_stop(struct ieee802154_hw *ieee)
cancel_work_sync(&hw->poll_work); cancel_work_sync(&hw->poll_work);
(void) sx127x_mode(hw, SX127X_SLEEP_MODE); (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) 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->spi = spi;
hw->ieee = ieee; hw->ieee = ieee;
hw->busy = false; hw->busy = false;
hw->tx_wait = 0;
hw->delayed_tx_length = 0; hw->delayed_tx_length = 0;
spin_lock_init(&hw->lock); 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); dev_err(&spi->dev, "ieee802154_register_hw() failed: %d\n", ret);
return 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: fail_init:
ieee802154_free_hw(ieee); ieee802154_free_hw(ieee);