diff --git a/csma.c b/csma.c index ea5e316..f703cf9 100644 --- a/csma.c +++ b/csma.c @@ -8,6 +8,7 @@ #include "csma.h" #include "cc2520.h" #include "radio.h" +#include "debug.h" struct cc2520_interface *csma_top; struct cc2520_interface *csma_bottom; @@ -128,12 +129,12 @@ static enum hrtimer_restart cc2520_csma_timer_cb(struct hrtimer *timer) // interrupt context, there's a few places // where we spin lock and assume we can be // preempted. If we're running in atomic mode - // that promise is broken. We use a work queue. + // that promise is broken. We use a work queue. - // The workqueue adds about 30uS of latency. + // The workqueue adds about 30uS of latency. INIT_WORK(&work, cc2520_csma_wq); queue_work(wq, &work); - return HRTIMER_NORESTART; + return HRTIMER_NORESTART; } else { spin_lock_irqsave(&state_sl, flags); @@ -141,7 +142,7 @@ static enum hrtimer_restart cc2520_csma_timer_cb(struct hrtimer *timer) csma_state = CC2520_CSMA_CONG; spin_unlock_irqrestore(&state_sl, flags); - new_backoff = + new_backoff = cc2520_csma_get_backoff(backoff_min, backoff_max_cong); INFO((KERN_INFO "[cc2520] - channel still busy, waiting %d uS\n", new_backoff)); @@ -228,4 +229,4 @@ void cc2520_csma_set_init_backoff(int backoff) void cc2520_csma_set_cong_backoff(int backoff) { backoff_max_cong = backoff; -} \ No newline at end of file +} diff --git a/debug.h b/debug.h new file mode 100644 index 0000000..3743a20 --- /dev/null +++ b/debug.h @@ -0,0 +1,23 @@ +#ifndef DEBUG_H +#define DEBUG_H + +// Define different levels of debug printing + +// print nothing +#define DEBUG_PRINT_OFF 0 +// print only when something goes wrong +#define DEBUG_PRINT_ERR 1 +// print occasional messages about interesting things +#define DEBUG_PRINT_INFO 2 +// print a good amount of debuging output +#define DEBUG_PRINT_DBG 3 + +// Defines the level of debug output +extern uint8_t debug_print; + +// Define the printk macros. +#define ERR(x) do {if (debug_print >= DEBUG_PRINT_ERR) { printk x; }} while (0) +#define INFO(x) do {if (debug_print >= DEBUG_PRINT_INFO) { printk x; }} while (0) +#define DBG(x) do {if (debug_print >= DEBUG_PRINT_DBG) { printk x; }} while (0) + +#endif diff --git a/interface.c b/interface.c index 75058fb..7dcf712 100644 --- a/interface.c +++ b/interface.c @@ -17,6 +17,7 @@ #include "sack.h" #include "csma.h" #include "lpl.h" +#include "debug.h" struct cc2520_interface *interface_bottom; @@ -45,8 +46,6 @@ static struct semaphore rx_done_sem; // Results, stored by the callbacks static int tx_result; -static bool print_messages = false; - DECLARE_WAIT_QUEUE_HEAD(cc2520_interface_read_queue); static void cc2520_interface_tx_done(u8 status); @@ -135,7 +134,7 @@ static ssize_t interface_write( } tx_pkt_len = pkt_len; - if (print_messages) { + if (debug_print >= DEBUG_PRINT_DBG) { interface_print_to_log(tx_buf_c, pkt_len, true); } @@ -163,7 +162,7 @@ static ssize_t interface_read(struct file *filp, char __user *buf, size_t count, if (copy_to_user(buf, rx_buf_c, rx_pkt_len)) return -EFAULT; - if (print_messages) { + if (debug_print >= DEBUG_PRINT_DBG) { interface_print_to_log(rx_buf_c, rx_pkt_len, false); } @@ -176,15 +175,15 @@ static long interface_ioctl(struct file *file, { switch (ioctl_num) { case CC2520_IO_RADIO_INIT: - printk(KERN_INFO "[cc2520] - radio starting\n"); + INFO((KERN_INFO "[cc2520] - radio starting\n")); cc2520_radio_start(); break; case CC2520_IO_RADIO_ON: - printk(KERN_INFO "[cc2520] - radio turning on\n"); + INFO((KERN_INFO "[cc2520] - radio turning on\n")); cc2520_radio_on(); break; case CC2520_IO_RADIO_OFF: - printk(KERN_INFO "[cc2520] - radio turning off\n"); + INFO((KERN_INFO "[cc2520] - radio turning off\n")); cc2520_radio_off(); break; case CC2520_IO_RADIO_SET_CHANNEL: @@ -236,10 +235,11 @@ static void interface_ioctl_set_print(struct cc2520_set_print_messages_data *dat return; } - INFO((KERN_INFO "[cc2520] - setting debug message print: %d", ldata.enabled)); + INFO((KERN_INFO "[cc2520] - setting debug message print: %i", ldata.debug_level)); - print_messages = ldata.enabled; + debug_print = ldata.debug_level; } + static void interface_ioctl_set_channel(struct cc2520_set_channel_data *data) { int result; @@ -248,11 +248,11 @@ static void interface_ioctl_set_channel(struct cc2520_set_channel_data *data) result = copy_from_user(&ldata, data, sizeof(struct cc2520_set_channel_data)); if (result) { - printk(KERN_ALERT "[cc2520] - an error occurred setting the channel\n"); + ERR((KERN_ALERT "[cc2520] - an error occurred setting the channel\n")); return; } - printk(KERN_INFO "[cc2520] - Setting channel to %d\n", ldata.channel); + INFO((KERN_INFO "[cc2520] - Setting channel to %d\n", ldata.channel)); cc2520_radio_set_channel(ldata.channel); } @@ -263,12 +263,12 @@ static void interface_ioctl_set_address(struct cc2520_set_address_data *data) result = copy_from_user(&ldata, data, sizeof(struct cc2520_set_address_data)); if (result) { - printk(KERN_ALERT "[cc2520] - an error occurred setting the address\n"); + ERR((KERN_ALERT "[cc2520] - an error occurred setting the address\n")); return; } - printk(KERN_INFO "[cc2520] - setting addr: %d ext_addr: %lld pan_id: %d\n", - ldata.short_addr, ldata.extended_addr, ldata.pan_id); + INFO((KERN_INFO "[cc2520] - setting addr: %d ext_addr: %lld pan_id: %d\n", + ldata.short_addr, ldata.extended_addr, ldata.pan_id)); cc2520_radio_set_address(ldata.short_addr, ldata.extended_addr, ldata.pan_id); } @@ -279,11 +279,11 @@ static void interface_ioctl_set_txpower(struct cc2520_set_txpower_data *data) result = copy_from_user(&ldata, data, sizeof(struct cc2520_set_txpower_data)); if (result) { - printk(KERN_ALERT "[cc2520] - an error occurred setting the txpower\n"); + ERR((KERN_ALERT "[cc2520] - an error occurred setting the txpower\n")); return; } - printk(KERN_INFO "[cc2520] - setting txpower: %d\n", ldata.txpower); + INFO((KERN_INFO "[cc2520] - setting txpower: %d\n", ldata.txpower)); cc2520_radio_set_txpower(ldata.txpower); } @@ -371,7 +371,7 @@ int cc2520_interface_init() // Allocate a major number for this device result = alloc_chrdev_region(&char_d_mm, 0, 1, cc2520_name); if (result < 0) { - printk(KERN_INFO "[cc2520] - Could not allocate a major number\n"); + ERR((KERN_INFO "[cc2520] - Could not allocate a major number\n")); goto error; } major = MAJOR(char_d_mm); @@ -381,21 +381,21 @@ int cc2520_interface_init() char_d_cdev.owner = THIS_MODULE; result = cdev_add(&char_d_cdev, char_d_mm, 1); if (result < 0) { - printk(KERN_INFO "[cc2520] - Unable to register char dev\n"); + ERR((KERN_INFO "[cc2520] - Unable to register char dev\n")); goto error; } - printk(KERN_INFO "[cc2520] - Char interface registered on %d\n", major); + INFO((KERN_INFO "[cc2520] - Char interface registered on %d\n", major)); cl = class_create(THIS_MODULE, "cc2520"); if (cl == NULL) { - printk(KERN_INFO "[cc2520] - Could not create device class\n"); + ERR((KERN_INFO "[cc2520] - Could not create device class\n")); goto error; } // Create the device in /dev/radio de = device_create(cl, NULL, char_d_mm, NULL, "radio"); if (de == NULL) { - printk(KERN_INFO "[cc2520] - Could not create device\n"); + ERR((KERN_INFO "[cc2520] - Could not create device\n")); goto error; } @@ -422,12 +422,12 @@ void cc2520_interface_free() result = down_interruptible(&tx_sem); if (result) { - printk("[cc2520] - critical error occurred on free."); + ERR(("[cc2520] - critical error occurred on free.")); } result = down_interruptible(&rx_sem); if (result) { - printk("[cc2520] - critical error occurred on free."); + ERR(("[cc2520] - critical error occurred on free.")); } cdev_del(&char_d_cdev); @@ -436,7 +436,7 @@ void cc2520_interface_free() class_destroy(cl); - printk(KERN_INFO "[cc2520] - Removed character device\n"); + INFO((KERN_INFO "[cc2520] - Removed character device\n")); if (rx_buf_c) { kfree(rx_buf_c); @@ -447,4 +447,4 @@ void cc2520_interface_free() kfree(tx_buf_c); tx_buf_c = 0; } -} \ No newline at end of file +} diff --git a/interface.h b/interface.h index 1c52574..2e115db 100644 --- a/interface.h +++ b/interface.h @@ -1,5 +1,5 @@ #ifndef INTERFACE_H -#define iNTERFACE_H +#define INTERFACE_H // Interface int cc2520_interface_init(void); @@ -7,4 +7,4 @@ void cc2520_interface_free(void); extern struct cc2520_interface *interface_bottom; -#endif \ No newline at end of file +#endif diff --git a/ioctl.h b/ioctl.h index e2042b5..d75c4f3 100644 --- a/ioctl.h +++ b/ioctl.h @@ -39,7 +39,7 @@ struct cc2520_set_csma_data { }; struct cc2520_set_print_messages_data { - bool enabled; + u8 debug_level; }; // Possible TX Powers: @@ -66,4 +66,4 @@ struct cc2520_set_txpower_data { #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) -#define CC2520_IO_RADIO_SET_PRINT _IOW(BASE, 9, struct cc2520_set_print_messages_data) \ No newline at end of file +#define CC2520_IO_RADIO_SET_PRINT _IOW(BASE, 9, struct cc2520_set_print_messages_data) diff --git a/lpl.c b/lpl.c index 334e5ff..c25d364 100644 --- a/lpl.c +++ b/lpl.c @@ -6,6 +6,7 @@ #include "lpl.h" #include "packet.h" #include "cc2520.h" +#include "debug.h" struct cc2520_interface *lpl_top; struct cc2520_interface *lpl_bottom; @@ -125,7 +126,7 @@ static void cc2520_lpl_tx_done(u8 status) } else { spin_unlock_irqrestore(&state_sl, flags); - //printk(KERN_INFO "[cc2520] - lpl retransmit.\n"); + DBG((KERN_INFO "[cc2520] - lpl retransmit.\n")); lpl_bottom->tx(cur_tx_buf, cur_tx_len); } } @@ -138,7 +139,7 @@ static void cc2520_lpl_tx_done(u8 status) else { spin_unlock_irqrestore(&state_sl, flags); lpl_bottom->tx(cur_tx_buf, cur_tx_len); - } + } } } else { @@ -190,4 +191,4 @@ void cc2520_lpl_set_listen_length(int length) void cc2520_lpl_set_wakeup_interval(int interval) { lpl_interval = interval; -} \ No newline at end of file +} diff --git a/module.c b/module.c index b0e9223..69f8f03 100644 --- a/module.c +++ b/module.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -17,9 +17,13 @@ #include "sack.h" #include "csma.h" #include "unique.h" +#include "debug.h" -#define DRIVER_AUTHOR "Andrew Robinson " -#define DRIVER_DESC "A driver for the CC2520 radio. Be afraid." +#define DRIVER_AUTHOR "Andrew Robinson " +#define DRIVER_DESC "A driver for the CC2520 radio. Be afraid." +#define DRIVER_VERSION "0.5" + +uint8_t debug_print; struct cc2520_state state; const char cc2520_name[] = "cc2520"; @@ -48,11 +52,13 @@ int init_module() { int err = 0; + debug_print = DEBUG_PRINT_INFO; + setup_bindings(); memset(&state, 0, sizeof(struct cc2520_state)); - - INFO((KERN_INFO "loading CC2520 Kernel Module v0.01...\n")); + + INFO((KERN_INFO "loading CC2520 Kernel Module v%s...\n", DRIVER_VERSION)); err = cc2520_plat_gpio_init(); if (err) { @@ -69,7 +75,7 @@ int init_module() err = cc2520_interface_init(); if (err) { ERR((KERN_ALERT "[cc2520] - char driver error. aborting.\n")); - goto error5; + goto error5; } err = cc2520_radio_init(); @@ -135,4 +141,4 @@ void cleanup_module() MODULE_LICENSE("GPL"); MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); \ No newline at end of file +MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/packet.c b/packet.c index e32f337..405eca9 100644 --- a/packet.c +++ b/packet.c @@ -2,6 +2,7 @@ #include #include "packet.h" #include "cc2520.h" +#include "debug.h" bool cc2520_packet_requires_ack_reply(u8 *buf) { @@ -89,8 +90,8 @@ u64 cc2520_packet_get_src(u8 *buf) src_addr_offset += 10; } // WARNING: this is a weird edge case from the - // 802.15.4 spec. - // NOTE: Assuming we're on LE arch. + // 802.15.4 spec. + // NOTE: Assuming we're on LE arch. else if (pan_compression) { src_addr_offset += 2; } @@ -108,7 +109,7 @@ u64 cc2520_packet_get_src(u8 *buf) memcpy(&ret, buf + src_addr_offset, 8); } - INFO((KERN_INFO "[cc2520] - src_mode: %d dest_mode: %d pan_comp: %d src_addr_offset: %d\n", + DBG((KERN_INFO "[cc2520] - src_mode: %d dest_mode: %d pan_comp: %d src_addr_offset: %d\n", src_addr_mode, dest_addr_mode, pan_compression, src_addr_offset)); return ret; diff --git a/platform.c b/platform.c index 309d8a1..a9d45b8 100644 --- a/platform.c +++ b/platform.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -13,6 +13,7 @@ #include "cc2520.h" #include "radio.h" #include "platform.h" +#include "debug.h" ////////////////////////// // SPI Stuff @@ -28,23 +29,23 @@ static int cc2520_spi_add_to_bus(void) spi_master = spi_busnum_to_master(SPI_BUS); if (!spi_master) { - printk(KERN_ALERT "[cc2520] - spi_busnum_to_master(%d) returned NULL\n", - SPI_BUS); - printk(KERN_ALERT "[cc2520] - Missing modprobe spi-bcm2708?\n"); + ERR((KERN_ALERT "[cc2520] - spi_busnum_to_master(%d) returned NULL\n", + SPI_BUS)); + ERR((KERN_ALERT "[cc2520] - Missing modprobe spi-bcm2708?\n")); return -1; } spi_device = spi_alloc_device(spi_master); if (!spi_device) { put_device(&spi_master->dev); - printk(KERN_ALERT "[cc2520] - spi_alloc_device() failed\n"); + ERR((KERN_ALERT "[cc2520] - spi_alloc_device() failed\n")); return -1; } spi_device->chip_select = SPI_BUS_CS0; /* Check whether this SPI bus.cs is already claimed */ - snprintf(buff, sizeof(buff), "%s.%u", + snprintf(buff, sizeof(buff), "%s.%u", dev_name(&spi_device->master->dev), spi_device->chip_select); @@ -52,13 +53,15 @@ static int cc2520_spi_add_to_bus(void) if (pdev) { if (pdev->driver != NULL) { - printk(KERN_INFO - "[cc2520] - Driver [%s] already registered for %s. Nuking from orbit.\n", - pdev->driver->name, buff); + ERR((KERN_INFO + "[cc2520] - Driver [%s] already registered for %s. \ +Nuking from orbit.\n", + pdev->driver->name, buff)); } else { - printk(KERN_INFO - "[cc2520] - Previous driver registered with no loaded module. Nuking from orbit.\n"); + ERR((KERN_INFO + "[cc2520] - Previous driver registered with no loaded module. \ +Nuking from orbit.\n")); } device_unregister(pdev); @@ -73,12 +76,12 @@ static int cc2520_spi_add_to_bus(void) spi_device->controller_data = NULL; strlcpy(spi_device->modalias, cc2520_name, SPI_NAME_SIZE); - status = spi_add_device(spi_device); - if (status < 0) { + status = spi_add_device(spi_device); + if (status < 0) { spi_dev_put(spi_device); - printk(KERN_ALERT "[cc2520] - spi_add_device() failed: %d\n", - status); - } + ERR((KERN_ALERT "[cc2520] - spi_add_device() failed: %d\n", + status)); + } put_device(&spi_master->dev); return status; @@ -86,14 +89,14 @@ static int cc2520_spi_add_to_bus(void) static int cc2520_spi_probe(struct spi_device *spi_device) { - printk(KERN_INFO "[cc2520] - Inserting SPI protocol driver.\n"); + ERR((KERN_INFO "[cc2520] - Inserting SPI protocol driver.\n")); state.spi_device = spi_device; return 0; } static int cc2520_spi_remove(struct spi_device *spi_device) { - printk(KERN_INFO "[cc2520] - Removing SPI protocol driver."); + ERR((KERN_INFO "[cc2520] - Removing SPI protocol driver.")); state.spi_device = NULL; return 0; } @@ -118,7 +121,7 @@ int cc2520_plat_spi_init() result = spi_register_driver(&cc2520_spi_driver); if (result < 0) goto error; - + return 0; error: @@ -138,7 +141,7 @@ void cc2520_plat_spi_free() // Interrupt Handles ///////////////////////// -static irqreturn_t cc2520_sfd_handler(int irq, void *dev_id) +static irqreturn_t cc2520_sfd_handler(int irq, void *dev_id) { int gpio_val; struct timespec ts; @@ -157,11 +160,11 @@ static irqreturn_t cc2520_sfd_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t cc2520_fifop_handler(int irq, void *dev_id) +static irqreturn_t cc2520_fifop_handler(int irq, void *dev_id) { if (gpio_get_value(CC2520_FIFOP) == 1) { DBG((KERN_INFO "[cc2520] - fifop interrupt occurred\n")); - cc2520_radio_fifop_occurred(); + cc2520_radio_fifop_occurred(); } return IRQ_HANDLED; } @@ -216,10 +219,10 @@ int cc2520_plat_gpio_init() } err = request_irq( - irq, - cc2520_fifop_handler, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - "fifopHandler", + irq, + cc2520_fifop_handler, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "fifopHandler", NULL ); if (err) @@ -234,10 +237,10 @@ int cc2520_plat_gpio_init() } err = request_irq( - irq, - cc2520_sfd_handler, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, - "sfdHandler", + irq, + cc2520_sfd_handler, + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "sfdHandler", NULL ); if (err) @@ -247,7 +250,7 @@ int cc2520_plat_gpio_init() return err; fail: - printk(KERN_ALERT "[cc2520] - failed to init GPIOs\n"); + ERR((KERN_ALERT "[cc2520] - failed to init GPIOs\n")); cc2520_plat_gpio_free(); return err; } @@ -266,4 +269,4 @@ void cc2520_plat_gpio_free() free_irq(state.gpios.fifop_irq, NULL); free_irq(state.gpios.sfd_irq, NULL); -} \ No newline at end of file +} diff --git a/radio.c b/radio.c index d5dba6f..87f39ee 100644 --- a/radio.c +++ b/radio.c @@ -17,6 +17,8 @@ #include "cc2520.h" #include "radio.h" #include "radio_config.h" +#include "interface.h" +#include "debug.h" static u16 short_addr; static u64 extended_addr; @@ -790,4 +792,4 @@ static cc2520_status_t cc2520_radio_strobe(u8 cmd) ret.value = rx_buf[0]; return ret; -} \ No newline at end of file +} diff --git a/sack.c b/sack.c index acd037d..683e70b 100644 --- a/sack.c +++ b/sack.c @@ -6,8 +6,8 @@ #include "sack.h" #include "cc2520.h" #include "packet.h" - #include "radio.h" +#include "debug.h" struct cc2520_interface *sack_top; struct cc2520_interface *sack_bottom; @@ -76,7 +76,7 @@ int cc2520_sack_init() hrtimer_init(&timeout_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); timeout_timer.function = &cc2520_sack_timer_cb; - + spin_lock_init(&sack_sl); sack_state = CC2520_SACK_IDLE; @@ -126,7 +126,7 @@ static void cc2520_sack_start_timer() static int cc2520_sack_tx(u8 * buf, u8 len) { spin_lock_irqsave(&sack_sl, flags); - + if (sack_state != CC2520_SACK_IDLE) { INFO((KERN_INFO "[cc2520] - Ut oh! Tx spinlocking.\n")); } @@ -182,13 +182,13 @@ static void cc2520_sack_rx_done(u8 *buf, u8 len) // 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. + // think it's needed anymore. cc2520_radio_release_rx(); spin_lock_irqsave(&sack_sl, flags); if (cc2520_packet_is_ack(cur_rx_buf)) { - if (sack_state == CC2520_SACK_TX_WAIT && + if (sack_state == CC2520_SACK_TX_WAIT && cc2520_packet_is_ack_to(cur_rx_buf, cur_tx_buf)) { sack_state = CC2520_SACK_IDLE; spin_unlock_irqrestore(&sack_sl, flags); diff --git a/unique.c b/unique.c index 5889955..58b764b 100644 --- a/unique.c +++ b/unique.c @@ -7,6 +7,7 @@ #include "unique.h" #include "packet.h" #include "cc2520.h" +#include "debug.h" struct node_list{ struct list_head list; @@ -66,7 +67,7 @@ static void cc2520_unique_rx_done(u8 *buf, u8 len) dsn = cc2520_packet_get_header(buf)->dsn; src = cc2520_packet_get_src(buf); - + found = false; drop = false; @@ -98,4 +99,4 @@ static void cc2520_unique_rx_done(u8 *buf, u8 len) if (!drop) unique_top->rx_done(buf, len); -} \ No newline at end of file +}