From c2a0d468ab9c32addfeaca5955c3e484b24f5ec9 Mon Sep 17 00:00:00 2001 From: Andrew Robinson Date: Tue, 15 Jan 2013 10:44:15 -0500 Subject: [PATCH] added the missing ioctl interfaces for csma and lpl --- cc2520.h | 2 ++ csma.c | 34 +++++++++++++++++++++++++++++--- csma.h | 6 ++++-- interface.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++----- ioctl.h | 17 +++++++++++++++- lpl.c | 2 +- radio.c | 1 - sack.c | 10 ++++++++++ 8 files changed, 116 insertions(+), 13 deletions(-) diff --git a/cc2520.h b/cc2520.h index 122342a..9ac02dd 100644 --- a/cc2520.h +++ b/cc2520.h @@ -75,11 +75,13 @@ #define CC2520_DEF_MIN_BACKOFF 320 #define CC2520_DEF_INIT_BACKOFF 4960 #define CC2520_DEF_CONG_BACKOFF 2240 +#define CC2520_DEF_CSMA_ENABLED true // We go for around a 1% duty cycle of the radio // for LPL stuff. #define CC2520_DEF_LPL_WAKEUP_INTERVAL 512000 #define CC2520_DEF_LPL_LISTEN_WINDOW 5120 +#define CC2520_DEF_LPL_ENABLED true // Error codes #define CC2520_TX_SUCCESS 0 diff --git a/csma.c b/csma.c index b0d59b3..b877a63 100644 --- a/csma.c +++ b/csma.c @@ -15,6 +15,7 @@ struct cc2520_interface *csma_bottom; static int backoff_min; static int backoff_max_init; static int backoff_max_cong; +static bool csma_enabled; static struct hrtimer backoff_timer; @@ -53,6 +54,7 @@ int cc2520_csma_init() backoff_min = CC2520_DEF_MIN_BACKOFF; backoff_max_init = CC2520_DEF_INIT_BACKOFF; backoff_max_cong = CC2520_DEF_CONG_BACKOFF; + csma_enabled = CC2520_DEF_CSMA_ENABLED; spin_lock_init(&state_sl); csma_state = CC2520_CSMA_IDLE; @@ -166,6 +168,10 @@ static int cc2520_csma_tx(u8 * buf, u8 len) { int backoff; + if (!csma_enabled) { + return csma_bottom->tx(buf, len); + } + spin_lock_irqsave(&state_sl, flags); if (csma_state == CC2520_CSMA_IDLE) { csma_state = CC2520_CSMA_TX; @@ -190,9 +196,11 @@ static int cc2520_csma_tx(u8 * buf, u8 len) static void cc2520_csma_tx_done(u8 status) { - spin_lock_irqsave(&state_sl, flags); - csma_state = CC2520_CSMA_IDLE; - spin_unlock_irqrestore(&state_sl, flags); + if (csma_enabled) { + spin_lock_irqsave(&state_sl, flags); + csma_state = CC2520_CSMA_IDLE; + spin_unlock_irqrestore(&state_sl, flags); + } csma_top->tx_done(status); } @@ -200,4 +208,24 @@ static void cc2520_csma_tx_done(u8 status) static void cc2520_csma_rx_done(u8 *buf, u8 len) { csma_top->rx_done(buf, len); +} + +void cc2520_csma_set_enabled(bool enabled) +{ + csma_enabled = enabled; +} + +void cc2520_csma_set_min_backoff(int backoff) +{ + backoff_min = backoff; +} + +void cc2520_csma_set_init_backoff(int backoff) +{ + backoff_max_init = backoff; +} + +void cc2520_csma_set_cong_backoff(int backoff) +{ + backoff_max_cong = backoff; } \ No newline at end of file diff --git a/csma.h b/csma.h index 883ba54..84a6ad3 100644 --- a/csma.h +++ b/csma.h @@ -9,7 +9,9 @@ extern struct cc2520_interface *csma_bottom; int cc2520_csma_init(void); void cc2520_csma_free(void); -void cc2520_csma_set_inital_backoff(int timeout); -void cc2520_csma_set_congestion_backoff(int timeout); +void cc2520_csma_set_enabled(bool enabled); +void cc2520_csma_set_min_backoff(int timeout); +void cc2520_csma_set_init_backoff(int timeout); +void cc2520_csma_set_cong_backoff(int timeout); #endif \ No newline at end of file diff --git a/interface.c b/interface.c index afcfa9f..43afc01 100644 --- a/interface.c +++ b/interface.c @@ -13,6 +13,8 @@ #include "interface.h" #include "radio.h" #include "sack.h" +#include "csma.h" +#include "lpl.h" struct cc2520_interface *interface_bottom; @@ -45,6 +47,8 @@ static void interface_ioctl_set_channel(struct cc2520_set_channel_data *data); static void interface_ioctl_set_address(struct cc2520_set_address_data *data); static void interface_ioctl_set_txpower(struct cc2520_set_txpower_data *data); static void interface_ioctl_set_ack(struct cc2520_set_ack_data *data); +static void interface_ioctl_set_lpl(struct cc2520_set_lpl_data *data); +static void interface_ioctl_set_csma(struct cc2520_set_csma_data *data); static long interface_ioctl(struct file *file, unsigned int ioctl_num, @@ -146,17 +150,23 @@ static long interface_ioctl(struct file *file, cc2520_radio_off(); break; case CC2520_IO_RADIO_SET_CHANNEL: - interface_ioctl_set_channel((struct cc2520_set_channel_data *) ioctl_param); + interface_ioctl_set_channel((struct cc2520_set_channel_data*) ioctl_param); break; case CC2520_IO_RADIO_SET_ADDRESS: - interface_ioctl_set_address((struct cc2520_set_address_data *) ioctl_param); + interface_ioctl_set_address((struct cc2520_set_address_data*) ioctl_param); break; case CC2520_IO_RADIO_SET_TXPOWER: - interface_ioctl_set_txpower((struct cc2520_set_txpower_data *) ioctl_param); + interface_ioctl_set_txpower((struct cc2520_set_txpower_data*) ioctl_param); break; case CC2520_IO_RADIO_SET_ACK: interface_ioctl_set_ack((struct cc2520_set_ack_data*) ioctl_param); break; + case CC2520_IO_RADIO_SET_LPL: + interface_ioctl_set_lpl((struct cc2520_set_lpl_data*) ioctl_param); + break; + case CC2520_IO_RADIO_SET_CSMA: + interface_ioctl_set_csma((struct cc2520_set_csma_data*) ioctl_param); + break; } return 0; @@ -228,14 +238,51 @@ static void interface_ioctl_set_ack(struct cc2520_set_ack_data *data) result = copy_from_user(&ldata, data, sizeof(struct cc2520_set_ack_data)); if (result) { - printk(KERN_INFO "[cc2520] - an error occurred setting soft ack\n"); + ERR((KERN_INFO "[cc2520] - an error occurred setting soft ack\n")); return; } - printk(KERN_INFO "[cc2520] - setting softack timeout\n"); + INFO((KERN_INFO "[cc2520] - setting softack timeout: %d\n", ldata.timeout)); cc2520_sack_set_timeout(ldata.timeout); } +static void interface_ioctl_set_lpl(struct cc2520_set_lpl_data *data) +{ + int result; + struct cc2520_set_lpl_data ldata; + result = copy_from_user(&ldata, data, sizeof(struct cc2520_set_lpl_data)); + + if (result) { + ERR((KERN_INFO "[cc2520] - an error occurred setting lpl\n")); + return; + } + + INFO((KERN_INFO "[cc2520] - setting lpl enabled: %d, window: %d, interval: %d\n", + ldata.enabled, ldata.window, ldata.interval)); + cc2520_lpl_set_enabled(ldata.enabled); + cc2520_lpl_set_listen_length(ldata.window); + cc2520_lpl_set_wakeup_interval(ldata.interval); +} + +static void interface_ioctl_set_csma(struct cc2520_set_csma_data *data) +{ + int result; + struct cc2520_set_csma_data ldata; + result = copy_from_user(&ldata, data, sizeof(struct cc2520_set_csma_data)); + + if (result) { + ERR((KERN_INFO "[cc2520] - an error occurred setting csma\n")); + return; + } + + INFO((KERN_INFO "[cc2520] - setting csma enabled: %d, min_backoff: %d, init_backoff: %d, cong_backoff_ %d\n", + ldata.enabled, ldata.min_backoff, ldata.init_backoff, ldata.cong_backoff)); + cc2520_csma_set_enabled(ldata.enabled); + cc2520_csma_set_min_backoff(ldata.min_backoff); + cc2520_csma_set_init_backoff(ldata.init_backoff); + cc2520_csma_set_cong_backoff(ldata.cong_backoff); +} + ///////////////// // init/free /////////////////// diff --git a/ioctl.h b/ioctl.h index 4c37474..73caed6 100644 --- a/ioctl.h +++ b/ioctl.h @@ -24,6 +24,19 @@ struct cc2520_set_ack_data { u32 timeout; }; +struct cc2520_set_lpl_data { + u32 window; + u32 interval; + bool enabled; +}; + +struct cc2520_set_csma_data { + u32 min_backoff; + u32 init_backoff; + u32 cong_backoff; + bool enabled; +}; + // Possible TX Powers: #define CC2520_TXPOWER_5DBM 0xF7 #define CC2520_TXPOWER_3DBM 0xF2 @@ -45,4 +58,6 @@ struct cc2520_set_txpower_data { #define CC2520_IO_RADIO_SET_CHANNEL _IOW(BASE, 3, struct cc2520_set_channel_data) #define CC2520_IO_RADIO_SET_ADDRESS _IOW(BASE, 4, struct cc2520_set_address_data) #define CC2520_IO_RADIO_SET_TXPOWER _IOW(BASE, 5, struct cc2520_set_txpower_data) -#define CC2520_IO_RADIO_SET_ACK _IOW(BASE, 6, struct cc2520_set_ack_data) \ No newline at end of file +#define CC2520_IO_RADIO_SET_ACK _IOW(BASE, 6, struct cc2520_set_ack_data) +#define CC2520_IO_RADIO_SET_LPL _IOW(BASE, 7, struct cc2520_set_lpl_data) +#define CC2520_IO_RADIO_SET_CSMA _IOW(BASE, 8, struct cc2520_set_csma_data) \ No newline at end of file diff --git a/lpl.c b/lpl.c index 4529916..334e5ff 100644 --- a/lpl.c +++ b/lpl.c @@ -45,7 +45,7 @@ int cc2520_lpl_init() lpl_window = CC2520_DEF_LPL_LISTEN_WINDOW; lpl_interval = CC2520_DEF_LPL_WAKEUP_INTERVAL; - lpl_enabled = true; + lpl_enabled = CC2520_DEF_LPL_ENABLED; cur_tx_buf = kmalloc(PKT_BUFF_SIZE, GFP_KERNEL); if (!cur_tx_buf) { diff --git a/radio.c b/radio.c index a5105d6..62a8bac 100644 --- a/radio.c +++ b/radio.c @@ -272,7 +272,6 @@ void cc2520_radio_free() void cc2520_radio_start() { - //INIT_WORK(&work, cc2520_radio_download_packet); cc2520_radio_lock(CC2520_RADIO_STATE_CONFIG); tsfer.cs_change = 1; diff --git a/sack.c b/sack.c index 71b18b2..12dfc14 100644 --- a/sack.c +++ b/sack.c @@ -173,6 +173,16 @@ static void cc2520_sack_rx_done(u8 *buf, u8 len) // an ACK, trasmit it. memcpy(cur_rx_buf, buf, len); cur_rx_buf_len = len; + + // NOTE: this is a big hack right now, + // and I'm not sure if it's even needed. + // We introduce a strong coupling between + // the sack layer and the radio layer here + // by providing a mechanism to explicitly + // release the buffer. When I was troubleshooting + // a terrible concurrency bug I added this + // as a possible solution, but I don't + // think it's needed anymore. cc2520_radio_release_rx(); spin_lock_irqsave(&sack_sl, flags);