Commit e9563355 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Staging: Merge staging-next into Linus's tree

Conflicts:
	drivers/staging/Kconfig
	drivers/staging/batman-adv/bat_sysfs.c
	drivers/staging/batman-adv/device.c
	drivers/staging/batman-adv/hard-interface.c
	drivers/staging/cx25821/cx25821-audups11.c
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parents cdd854bc b12d1995
......@@ -18,6 +18,7 @@
#include <asm/mshyperv.h>
struct ms_hyperv_info ms_hyperv;
EXPORT_SYMBOL_GPL(ms_hyperv);
static bool __init ms_hyperv_platform(void)
{
......
......@@ -97,6 +97,8 @@ source "drivers/staging/octeon/Kconfig"
source "drivers/staging/serqt_usb2/Kconfig"
source "drivers/staging/spectra/Kconfig"
source "drivers/staging/quatech_usb2/Kconfig"
source "drivers/staging/vt6655/Kconfig"
......@@ -115,7 +117,7 @@ source "drivers/staging/sep/Kconfig"
source "drivers/staging/iio/Kconfig"
source "drivers/staging/ramzswap/Kconfig"
source "drivers/staging/zram/Kconfig"
source "drivers/staging/wlags49_h2/Kconfig"
......@@ -127,8 +129,6 @@ source "drivers/staging/samsung-laptop/Kconfig"
source "drivers/staging/sm7xx/Kconfig"
source "drivers/staging/dt3155/Kconfig"
source "drivers/staging/dt3155v4l/Kconfig"
source "drivers/staging/crystalhd/Kconfig"
......@@ -147,5 +147,13 @@ source "drivers/staging/msm/Kconfig"
source "drivers/staging/lirc/Kconfig"
source "drivers/staging/easycap/Kconfig"
source "drivers/staging/solo6x10/Kconfig"
source "drivers/staging/tidspbridge/Kconfig"
source "drivers/staging/quickstart/Kconfig"
endif # !STAGING_EXCLUDE_BUILD
endif # STAGING
......@@ -23,6 +23,7 @@ obj-$(CONFIG_R8187SE) += rtl8187se/
obj-$(CONFIG_RTL8192SU) += rtl8192su/
obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_SPECTRA) += spectra/
obj-$(CONFIG_TRANZPORT) += frontier/
obj-$(CONFIG_DREAM) += dream/
obj-$(CONFIG_POHMELFS) += pohmelfs/
......@@ -39,13 +40,12 @@ obj-$(CONFIG_VME_BUS) += vme/
obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/
obj-$(CONFIG_DX_SEP) += sep/
obj-$(CONFIG_IIO) += iio/
obj-$(CONFIG_RAMZSWAP) += ramzswap/
obj-$(CONFIG_ZRAM) += zram/
obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/
obj-$(CONFIG_BATMAN_ADV) += batman-adv/
obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/
obj-$(CONFIG_FB_SM7XX) += sm7xx/
obj-$(CONFIG_DT3155) += dt3155/
obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
obj-$(CONFIG_CRYSTALHD) += crystalhd/
obj-$(CONFIG_CXT1E1) += cxt1e1/
......@@ -54,3 +54,7 @@ obj-$(CONFIG_ADIS16255) += adis16255/
obj-$(CONFIG_FB_XGI) += xgifb/
obj-$(CONFIG_TOUCHSCREEN_MRSTOUCH) += mrst-touchscreen/
obj-$(CONFIG_MSM_STAGING) += msm/
obj-$(CONFIG_EASYCAP) += easycap/
obj-$(CONFIG_SOLO6X10) += solo6x10/
obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/
......@@ -303,7 +303,7 @@ static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis)
if (status != 0)
goto err;
if (value != 0x0800) {
dev_warn(&spiadis->spi->dev, "Scale factor is none default"
dev_warn(&spiadis->spi->dev, "Scale factor is none default "
"value (%.4x)\n", value);
}
......@@ -338,7 +338,7 @@ static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis)
status = -ENODEV;
goto err;
} else if (value & 0x3) {
dev_warn(&spiadis->spi->dev, "Sensor voltage"
dev_warn(&spiadis->spi->dev, "Sensor voltage "
"out of range.\n");
status = -ENODEV;
goto err;
......
batman-adv 2010.0.0:
* support latest kernels (2.6.21 - 2.6.35)
* further code refactoring and cleaning for coding style
* move from procfs based configuration to sysfs
* reorganized sequence number handling
* limit queue lengths for batman and broadcast packets
* many bugs (endless loop and rogue packets on shutdown, wrong tcpdump output,
missing frees in error situations, sleeps in atomic contexts) squashed
-- Fri, 18 Jun 2010 21:34:26 +0200
batman-adv 0.2.1:
* support latest kernels (2.6.20 - 2.6.33)
......
......@@ -4,7 +4,7 @@
config BATMAN_ADV
tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
depends on PROC_FS && NET
depends on NET
default n
---help---
......
......@@ -18,5 +18,5 @@
# 02110-1301, USA
#
obj-m += batman-adv.o
batman-adv-objs := main.o send.o routing.o soft-interface.o device.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o bat_sysfs.o
obj-$(CONFIG_BATMAN_ADV) += batman-adv.o
batman-adv-objs := main.o bat_debugfs.o bat_sysfs.o send.o routing.o soft-interface.o icmp_socket.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o
[state: 03-05-2010]
[state: 12-06-2010]
BATMAN-ADV
----------
......
Request a review.
Process the comments from the review.
Move into mainline proper.
* Use hweight* for hamming weight calculation
* Save/cache packets direktly as skb instead of using a normal memory region
and copying it in a skb using send_raw_packet and similar functions
* Request a new review
* Process the comments from the review
* Move into mainline proper
Please send all patches to:
Marek Lindner <lindner_marek@yahoo.de>
......
......@@ -106,11 +106,14 @@ static void new_aggregated_packet(unsigned char *packet_buff,
{
struct forw_packet *forw_packet_aggr;
unsigned long flags;
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
/* own packet should always be scheduled */
if (!own_packet) {
if (!atomic_dec_not_zero(&batman_queue_left)) {
bat_dbg(DBG_BATMAN, "batman packet queue full\n");
bat_dbg(DBG_BATMAN, bat_priv,
"batman packet queue full\n");
return;
}
}
......@@ -252,9 +255,9 @@ void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
while (aggregated_packet(buff_pos, packet_len,
batman_packet->num_hna)) {
/* network to host order for our 16bit seqno, and the
/* network to host order for our 32bit seqno, and the
orig_interval. */
batman_packet->seqno = ntohs(batman_packet->seqno);
batman_packet->seqno = ntohl(batman_packet->seqno);
hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
receive_bat_packet(ethhdr, batman_packet,
......
......@@ -19,6 +19,9 @@
*
*/
#ifndef _NET_BATMAN_ADV_AGGREGATION_H_
#define _NET_BATMAN_ADV_AGGREGATION_H_
#include "main.h"
/* is there another aggregated packet here? */
......@@ -36,3 +39,5 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv,
unsigned long send_time);
void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff,
int packet_len, struct batman_if *if_incoming);
#endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */
/*
* Copyright (C) 2010 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
*
*/
#include "main.h"
#include <linux/debugfs.h>
#include "bat_debugfs.h"
#include "translation-table.h"
#include "originator.h"
#include "hard-interface.h"
#include "vis.h"
#include "icmp_socket.h"
static struct dentry *bat_debugfs;
#ifdef CONFIG_BATMAN_ADV_DEBUG
#define LOG_BUFF_MASK (log_buff_len-1)
#define LOG_BUFF(idx) (debug_log->log_buff[(idx) & LOG_BUFF_MASK])
static int log_buff_len = LOG_BUF_LEN;
static void emit_log_char(struct debug_log *debug_log, char c)
{
LOG_BUFF(debug_log->log_end) = c;
debug_log->log_end++;
if (debug_log->log_end - debug_log->log_start > log_buff_len)
debug_log->log_start = debug_log->log_end - log_buff_len;
}
static int fdebug_log(struct debug_log *debug_log, char *fmt, ...)
{
int printed_len;
va_list args;
static char debug_log_buf[256];
char *p;
unsigned long flags;
if (!debug_log)
return 0;
spin_lock_irqsave(&debug_log->lock, flags);
va_start(args, fmt);
printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf),
fmt, args);
va_end(args);
for (p = debug_log_buf; *p != 0; p++)
emit_log_char(debug_log, *p);
spin_unlock_irqrestore(&debug_log->lock, flags);
wake_up(&debug_log->queue_wait);
return 0;
}
int debug_log(struct bat_priv *bat_priv, char *fmt, ...)
{
va_list args;
char tmp_log_buf[256];
va_start(args, fmt);
vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
fdebug_log(bat_priv->debug_log, "[%10u] %s",
(jiffies / HZ), tmp_log_buf);
va_end(args);
return 0;
}
static int log_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
inc_module_count();
return 0;
}
static int log_release(struct inode *inode, struct file *file)
{
dec_module_count();
return 0;
}
static ssize_t log_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
struct bat_priv *bat_priv = file->private_data;
struct debug_log *debug_log = bat_priv->debug_log;
int error, i = 0;
char c;
unsigned long flags;
if ((file->f_flags & O_NONBLOCK) &&
!(debug_log->log_end - debug_log->log_start))
return -EAGAIN;
if ((!buf) || (count < 0))
return -EINVAL;
if (count == 0)
return 0;
if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
error = wait_event_interruptible(debug_log->queue_wait,
(debug_log->log_start - debug_log->log_end));
if (error)
return error;
spin_lock_irqsave(&debug_log->lock, flags);
while ((!error) && (i < count) &&
(debug_log->log_start != debug_log->log_end)) {
c = LOG_BUFF(debug_log->log_start);
debug_log->log_start++;
spin_unlock_irqrestore(&debug_log->lock, flags);
error = __put_user(c, buf);
spin_lock_irqsave(&debug_log->lock, flags);
buf++;
i++;
}
spin_unlock_irqrestore(&debug_log->lock, flags);
if (!error)
return i;
return error;
}
static unsigned int log_poll(struct file *file, poll_table *wait)
{
struct bat_priv *bat_priv = file->private_data;
struct debug_log *debug_log = bat_priv->debug_log;
poll_wait(file, &debug_log->queue_wait, wait);
if (debug_log->log_end - debug_log->log_start)
return POLLIN | POLLRDNORM;
return 0;
}
static const struct file_operations log_fops = {
.open = log_open,
.release = log_release,
.read = log_read,
.poll = log_poll,
};
static int debug_log_setup(struct bat_priv *bat_priv)
{
struct dentry *d;
if (!bat_priv->debug_dir)
goto err;
bat_priv->debug_log = kzalloc(sizeof(struct debug_log), GFP_ATOMIC);
if (!bat_priv->debug_log)
goto err;
spin_lock_init(&bat_priv->debug_log->lock);
init_waitqueue_head(&bat_priv->debug_log->queue_wait);
d = debugfs_create_file("log", S_IFREG | S_IRUSR,
bat_priv->debug_dir, bat_priv, &log_fops);
if (d)
goto err;
return 0;
err:
return 1;
}
static void debug_log_cleanup(struct bat_priv *bat_priv)
{
kfree(bat_priv->debug_log);
bat_priv->debug_log = NULL;
}
#else /* CONFIG_BATMAN_ADV_DEBUG */
static int debug_log_setup(struct bat_priv *bat_priv)
{
bat_priv->debug_log = NULL;
return 0;
}
static void debug_log_cleanup(struct bat_priv *bat_priv)
{
return;
}
#endif
static int originators_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
return single_open(file, orig_seq_print_text, net_dev);
}
static int transtable_global_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
return single_open(file, hna_global_seq_print_text, net_dev);
}
static int transtable_local_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
return single_open(file, hna_local_seq_print_text, net_dev);
}
static int vis_data_open(struct inode *inode, struct file *file)
{
struct net_device *net_dev = (struct net_device *)inode->i_private;
return single_open(file, vis_seq_print_text, net_dev);
}
struct bat_debuginfo {
struct attribute attr;
const struct file_operations fops;
};
#define BAT_DEBUGINFO(_name, _mode, _open) \
struct bat_debuginfo bat_debuginfo_##_name = { \
.attr = { .name = __stringify(_name), \
.mode = _mode, }, \
.fops = { .owner = THIS_MODULE, \
.open = _open, \
.read = seq_read, \
.llseek = seq_lseek, \
.release = single_release, \
} \
};
static BAT_DEBUGINFO(originators, S_IRUGO, originators_open);
static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open);
static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open);
static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open);
static struct bat_debuginfo *mesh_debuginfos[] = {
&bat_debuginfo_originators,
&bat_debuginfo_transtable_global,
&bat_debuginfo_transtable_local,
&bat_debuginfo_vis_data,
NULL,
};
void debugfs_init(void)
{
bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL);
if (bat_debugfs == ERR_PTR(-ENODEV))
bat_debugfs = NULL;
}
void debugfs_destroy(void)
{
if (bat_debugfs) {
debugfs_remove_recursive(bat_debugfs);
bat_debugfs = NULL;
}
}
int debugfs_add_meshif(struct net_device *dev)
{
struct bat_priv *bat_priv = netdev_priv(dev);
struct bat_debuginfo **bat_debug;
struct dentry *file;
if (!bat_debugfs)
goto out;
bat_priv->debug_dir = debugfs_create_dir(dev->name, bat_debugfs);
if (!bat_priv->debug_dir)
goto out;
bat_socket_setup(bat_priv);
debug_log_setup(bat_priv);
for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) {
file = debugfs_create_file(((*bat_debug)->attr).name,
S_IFREG | ((*bat_debug)->attr).mode,
bat_priv->debug_dir,
dev, &(*bat_debug)->fops);
if (!file) {
bat_err(dev, "Can't add debugfs file: %s/%s\n",
dev->name, ((*bat_debug)->attr).name);
goto rem_attr;
}
}
return 0;
rem_attr:
debugfs_remove_recursive(bat_priv->debug_dir);
bat_priv->debug_dir = NULL;
out:
#ifdef CONFIG_DEBUG_FS
return -ENOMEM;
#else
return 0;
#endif /* CONFIG_DEBUG_FS */
}
void debugfs_del_meshif(struct net_device *dev)
{
struct bat_priv *bat_priv = netdev_priv(dev);
debug_log_cleanup(bat_priv);
if (bat_debugfs) {
debugfs_remove_recursive(bat_priv->debug_dir);
bat_priv->debug_dir = NULL;
}
}
/*
* Copyright (C) 2010 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
*
*/
#ifndef _NET_BATMAN_ADV_DEBUGFS_H_
#define _NET_BATMAN_ADV_DEBUGFS_H_
#define DEBUGFS_BAT_SUBDIR "batman_adv"
void debugfs_init(void);
void debugfs_destroy(void);
int debugfs_add_meshif(struct net_device *dev);
void debugfs_del_meshif(struct net_device *dev);
#endif /* _NET_BATMAN_ADV_DEBUGFS_H_ */
This diff is collapsed.
......@@ -20,10 +20,23 @@
*/
#ifndef _NET_BATMAN_ADV_SYSFS_H_
#define _NET_BATMAN_ADV_SYSFS_H_
#define SYSFS_IF_MESH_SUBDIR "mesh"
#define SYSFS_IF_BAT_SUBDIR "batman_adv"
struct bat_attribute {
struct attribute attr;
ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
char *buf);
ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
char *buf, size_t count);
};
int sysfs_add_meshif(struct net_device *dev);
void sysfs_del_meshif(struct net_device *dev);
int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev);
void sysfs_del_hardif(struct kobject **hardif_obj);
#endif /* _NET_BATMAN_ADV_SYSFS_H_ */
......@@ -24,10 +24,10 @@
/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno,
uint16_t curr_seqno)
uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
uint32_t curr_seqno)
{
int16_t diff, word_offset, word_num;
int32_t diff, word_offset, word_num;
diff = last_seqno - curr_seqno;
if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) {
......@@ -63,7 +63,7 @@ void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n)
}
/* shift the packet array by n places. */
void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n)
static void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n)
{
int32_t word_offset, word_num;
int32_t i;
......@@ -125,9 +125,12 @@ static void bit_reset_window(TYPE_OF_WORD *seq_bits)
* 1 if the window was moved (either new or very old)
* 0 if the window was not moved/shifted.
*/
char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
int8_t set_mark)
{
/* FIXME: each orig_node->batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
/* sequence number is slightly older. We already got a sequence number
* higher than this one, so we just mark it. */
......@@ -152,7 +155,7 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE)
|| (seq_num_diff < EXPECTED_SEQNO_RANGE)) {
bat_dbg(DBG_BATMAN,
bat_dbg(DBG_BATMAN, bat_priv,
"We missed a lot of packets (%i) !\n",
seq_num_diff - 1);
bit_reset_window(seq_bits);
......@@ -169,7 +172,7 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
|| (seq_num_diff >= EXPECTED_SEQNO_RANGE)) {
bat_dbg(DBG_BATMAN,
bat_dbg(DBG_BATMAN, bat_priv,
"Other host probably restarted!\n");
bit_reset_window(seq_bits);
......
......@@ -19,6 +19,8 @@
*
*/
#ifndef _NET_BATMAN_ADV_BITARRAY_H_
#define _NET_BATMAN_ADV_BITARRAY_H_
/* you should choose something big, if you don't want to waste cpu */
#define TYPE_OF_WORD unsigned long
......@@ -26,20 +28,19 @@
/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno,
uint16_t curr_seqno);
uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
uint32_t curr_seqno);
/* turn corresponding bit on, so we can remember that we got the packet */
void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n);
/* shift the packet array by n places. */
void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n);
/* receive and process one packet, returns 1 if received seq_num is considered
* new, 0 if old */
char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
int8_t set_mark);
/* count the hamming weight, how many good packets did we receive? */
int bit_packet_count(TYPE_OF_WORD *seq_bits);
#endif /* _NET_BATMAN_ADV_BITARRAY_H_ */
......@@ -30,6 +30,7 @@
#include "hash.h"
#include <linux/if_arp.h>
#include <linux/netfilter_bridge.h>
#define MIN(x, y) ((x) < (y) ? (x) : (y))
......@@ -108,7 +109,7 @@ static void set_primary_if(struct bat_priv *bat_priv,
set_main_if_addr(batman_if->net_dev->dev_addr);
batman_packet = (struct batman_packet *)(batman_if->packet_buff);
batman_packet->flags = 0;
batman_packet->flags = PRIMARIES_FIRST_HOP;
batman_packet->ttl = TTL;
/***
......@@ -149,12 +150,10 @@ static void check_known_mac_addr(uint8_t *addr)
if (!compare_orig(batman_if->net_dev->dev_addr, addr))
continue;
printk(KERN_WARNING "batman-adv:"
"The newly added mac address (%pM) already exists on: %s\n",
addr, batman_if->dev);
printk(KERN_WARNING "batman-adv:"
"It is strongly recommended to keep mac addresses unique"
"to avoid problems!\n");
pr_warning("The newly added mac address (%pM) already exists "
"on: %s\n", addr, batman_if->dev);
pr_warning("It is strongly recommended to keep mac addresses "
"unique to avoid problems!\n");
}
rcu_read_unlock();
}
......@@ -188,7 +187,8 @@ void update_min_mtu(void)
soft_device->mtu = min_mtu;
}
static void hardif_activate_interface(struct bat_priv *bat_priv,
static void hardif_activate_interface(struct net_device *net_dev,
struct bat_priv *bat_priv,
struct batman_if *batman_if)
{
if (batman_if->if_status != IF_INACTIVE)
......@@ -206,8 +206,7 @@ static void hardif_activate_interface(struct bat_priv *bat_priv,
if (!bat_priv->primary_if)
set_primary_if(bat_priv, batman_if);
printk(KERN_INFO "batman-adv:Interface activated: %s\n",
batman_if->dev);
bat_info(net_dev, "Interface activated: %s\n", batman_if->dev);
if (atomic_read(&module_state) == MODULE_INACTIVE)
activate_module();
......@@ -216,7 +215,8 @@ static void hardif_activate_interface(struct bat_priv *bat_priv,
return;
}
static void hardif_deactivate_interface(struct batman_if *batman_if)
static void hardif_deactivate_interface(struct net_device *net_dev,
struct batman_if *batman_if)
{
if ((batman_if->if_status != IF_ACTIVE) &&
(batman_if->if_status != IF_TO_BE_ACTIVATED))
......@@ -226,8 +226,7 @@ static void hardif_deactivate_interface(struct batman_if *batman_if)
batman_if->if_status = IF_INACTIVE;
printk(KERN_INFO "batman-adv:Interface deactivated: %s\n",
batman_if->dev);
bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev);
update_min_mtu();
}
......@@ -245,9 +244,8 @@ int hardif_enable_interface(struct batman_if *batman_if)
batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC);
if (!batman_if->packet_buff) {
printk(KERN_ERR "batman-adv:"
"Can't add interface packet (%s): out of memory\n",
batman_if->dev);
bat_err(soft_device, "Can't add interface packet (%s): "
"out of memory\n", batman_if->dev);
goto err;
}
......@@ -265,15 +263,14 @@ int hardif_enable_interface(struct batman_if *batman_if)
orig_hash_add_if(batman_if, bat_priv->num_ifaces);
atomic_set(&batman_if->seqno, 1);
printk(KERN_INFO "batman-adv:Adding interface: %s\n", batman_if->dev);
bat_info(soft_device, "Adding interface: %s\n", batman_if->dev);
if (hardif_is_iface_up(batman_if))
hardif_activate_interface(bat_priv, batman_if);
hardif_activate_interface(soft_device, bat_priv, batman_if);
else
printk(KERN_ERR "batman-adv:"
"Not using interface %s "
"(retrying later): interface not active\n",
batman_if->dev);
bat_err(soft_device, "Not using interface %s "
"(retrying later): interface not active\n",
batman_if->dev);
/* begin scheduling originator messages on that interface */
schedule_own_packet(batman_if);
......@@ -291,12 +288,12 @@ void hardif_disable_interface(struct batman_if *batman_if)
struct bat_priv *bat_priv = netdev_priv(soft_device);
if (batman_if->if_status == IF_ACTIVE)
hardif_deactivate_interface(batman_if);
hardif_deactivate_interface(soft_device, batman_if);
if (batman_if->if_status != IF_INACTIVE)
return;
printk(KERN_INFO "batman-adv:Removing interface: %s\n", batman_if->dev);
bat_info(soft_device, "Removing interface: %s\n", batman_if->dev);
bat_priv->num_ifaces--;
orig_hash_del_if(batman_if, bat_priv->num_ifaces);
......@@ -323,8 +320,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
if (!batman_if) {
printk(KERN_ERR "batman-adv:"
"Can't add interface (%s): out of memory\n",
pr_err("Can't add interface (%s): out of memory\n",
net_dev->name);
goto out;
}
......@@ -407,11 +403,11 @@ static int hard_if_event(struct notifier_block *this,
case NETDEV_REGISTER:
break;
case NETDEV_UP:
hardif_activate_interface(bat_priv, batman_if);
hardif_activate_interface(soft_device, bat_priv, batman_if);
break;
case NETDEV_GOING_DOWN:
case NETDEV_DOWN:
hardif_deactivate_interface(batman_if);
hardif_deactivate_interface(soft_device, batman_if);
break;
case NETDEV_UNREGISTER:
hardif_remove_interface(batman_if);
......@@ -432,11 +428,18 @@ static int hard_if_event(struct notifier_block *this,
return NOTIFY_DONE;
}
static int batman_skb_recv_finish(struct sk_buff *skb)
{
return NF_ACCEPT;
}
/* receive a packet with the batman ethertype coming on a hard
* interface */
int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype, struct net_device *orig_dev)
{
/* FIXME: each orig_node->batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct batman_packet *batman_packet;
struct batman_if *batman_if;
struct net_device_stats *stats;
......@@ -452,6 +455,13 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
if (atomic_read(&module_state) != MODULE_ACTIVE)
goto err_free;
/* if netfilter/ebtables wants to block incoming batman
* packets then give them a chance to do so here */
ret = NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, dev, NULL,
batman_skb_recv_finish);
if (ret != 1)
goto err_out;
/* packet should hold at least type and version */
if (unlikely(skb_headlen(skb) < 2))
goto err_free;
......@@ -478,7 +488,7 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
batman_packet = (struct batman_packet *)skb->data;
if (batman_packet->version != COMPAT_VERSION) {
bat_dbg(DBG_BATMAN,
bat_dbg(DBG_BATMAN, bat_priv,
"Drop packet: incompatible batman version (%i)\n",
batman_packet->version);
goto err_free;
......@@ -500,7 +510,7 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
/* unicast packet */
case BAT_UNICAST:
ret = recv_unicast_packet(skb);
ret = recv_unicast_packet(skb, batman_if);
break;
/* broadcast packet */
......@@ -531,7 +541,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
return NET_RX_DROP;
}
struct notifier_block hard_if_notifier = {
.notifier_call = hard_if_event,
};
......@@ -19,6 +19,9 @@
*
*/
#ifndef _NET_BATMAN_ADV_HARD_INTERFACE_H_
#define _NET_BATMAN_ADV_HARD_INTERFACE_H_
#define IF_NOT_IN_USE 0
#define IF_TO_BE_REMOVED 1
#define IF_INACTIVE 2
......@@ -38,3 +41,5 @@ int batman_skb_recv(struct sk_buff *skb,
struct net_device *orig_dev);
int hardif_min_mtu(void);
void update_min_mtu(void);
#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
......@@ -23,7 +23,7 @@
#include "hash.h"
/* clears the hash */
void hash_init(struct hashtable_t *hash)
static void hash_init(struct hashtable_t *hash)
{
int i;
......
......@@ -19,8 +19,9 @@
*
*/
#ifndef _BATMAN_HASH_H
#define _BATMAN_HASH_H
#ifndef _NET_BATMAN_ADV_HASH_H_
#define _NET_BATMAN_ADV_HASH_H_
#define HASHIT(name) struct hash_it_t name = { \
.index = -1, .bucket = NULL, \
.prev_bucket = NULL, \
......@@ -56,9 +57,6 @@ struct hashtable_t {
* argument and the size the second */
};
/* clears the hash */
void hash_init(struct hashtable_t *hash);
/* allocates and clears the hash */
struct hashtable_t *hash_new(int size, hashdata_compare_cb compare,
hashdata_choose_cb choose);
......@@ -99,6 +97,4 @@ struct hashtable_t *hash_resize(struct hashtable_t *hash, int size);
struct hash_it_t *hash_iterate(struct hashtable_t *hash,
struct hash_it_t *iter_in);
/* print the hash table for debugging */
void hash_debug(struct hashtable_t *hash);
#endif
#endif /* _NET_BATMAN_ADV_HASH_H_ */
......@@ -19,18 +19,16 @@
*
*/
#ifndef _NET_BATMAN_ADV_ICMP_SOCKET_H_
#define _NET_BATMAN_ADV_ICMP_SOCKET_H_
#include "types.h"
void bat_device_init(void);
int bat_device_setup(void);
void bat_device_destroy(void);
int bat_device_open(struct inode *inode, struct file *file);
int bat_device_release(struct inode *inode, struct file *file);
ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos);
ssize_t bat_device_write(struct file *file, const char __user *buff,
size_t len, loff_t *off);
unsigned int bat_device_poll(struct file *file, poll_table *wait);
void bat_device_add_packet(struct device_client *device_client,
struct icmp_packet *icmp_packet);
void bat_device_receive_packet(struct icmp_packet *icmp_packet);
#define ICMP_SOCKET "socket"
void bat_socket_init(void);
int bat_socket_setup(struct bat_priv *bat_priv);
void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet,
size_t icmp_len);
#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */
......@@ -21,11 +21,12 @@
#include "main.h"
#include "bat_sysfs.h"
#include "bat_debugfs.h"
#include "routing.h"
#include "send.h"
#include "originator.h"
#include "soft-interface.h"
#include "device.h"
#include "icmp_socket.h"
#include "translation-table.h"
#include "hard-interface.h"
#include "types.h"
......@@ -41,7 +42,6 @@ DEFINE_SPINLOCK(orig_hash_lock);
DEFINE_SPINLOCK(forw_bat_list_lock);
DEFINE_SPINLOCK(forw_bcast_list_lock);
atomic_t vis_interval;
atomic_t bcast_queue_left;
atomic_t batman_queue_left;
......@@ -49,7 +49,7 @@ int16_t num_hna;
struct net_device *soft_device;
unsigned char broadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
atomic_t module_state;
static struct packet_type batman_adv_packet_type __read_mostly = {
......@@ -59,18 +59,7 @@ static struct packet_type batman_adv_packet_type __read_mostly = {
struct workqueue_struct *bat_event_workqueue;
#ifdef CONFIG_BATMAN_ADV_DEBUG
int debug;
module_param(debug, int, 0644);
int bat_debug_type(int type)
{
return debug & type;
}
#endif
int init_module(void)
static int __init batman_init(void)
{
int retval;
......@@ -80,8 +69,6 @@ int init_module(void)
atomic_set(&module_state, MODULE_INACTIVE);
atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
* for debugging now. */
atomic_set(&bcast_queue_left, BCAST_QUEUE_LEN);
atomic_set(&batman_queue_left, BATMAN_QUEUE_LEN);
......@@ -92,23 +79,22 @@ int init_module(void)
if (!bat_event_workqueue)
return -ENOMEM;
bat_device_init();
bat_socket_init();
debugfs_init();
/* initialize layer 2 interface */
soft_device = alloc_netdev(sizeof(struct bat_priv) , "bat%d",
interface_setup);
if (!soft_device) {
printk(KERN_ERR "batman-adv:"
"Unable to allocate the batman interface\n");
pr_err("Unable to allocate the batman interface\n");
goto end;
}
retval = register_netdev(soft_device);
if (retval < 0) {
printk(KERN_ERR "batman-adv:"
"Unable to register the batman interface: %i\n", retval);
pr_err("Unable to register the batman interface: %i\n", retval);
goto free_soft_device;
}
......@@ -117,15 +103,22 @@ int init_module(void)
if (retval < 0)
goto unreg_soft_device;
retval = debugfs_add_meshif(soft_device);
if (retval < 0)
goto unreg_sysfs;
register_netdevice_notifier(&hard_if_notifier);
dev_add_pack(&batman_adv_packet_type);
printk(KERN_INFO "batman-adv:"
"B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded\n",
SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) "
"loaded\n", SOURCE_VERSION, REVISION_VERSION_STR,
COMPAT_VERSION);
return 0;
unreg_sysfs:
sysfs_del_meshif(soft_device);
unreg_soft_device:
unregister_netdev(soft_device);
soft_device = NULL;
......@@ -138,14 +131,16 @@ int init_module(void)
return -ENOMEM;
}
void cleanup_module(void)
static void __exit batman_exit(void)
{
deactivate_module();
debugfs_destroy();
unregister_netdevice_notifier(&hard_if_notifier);
hardif_remove_interfaces();
if (soft_device) {
debugfs_del_meshif(soft_device);
sysfs_del_meshif(soft_device);
unregister_netdev(soft_device);
soft_device = NULL;
......@@ -157,7 +152,7 @@ void cleanup_module(void)
bat_event_workqueue = NULL;
}
/* activates the module, creates bat device, starts timer ... */
/* activates the module, starts timer ... */
void activate_module(void)
{
if (originator_init() < 1)
......@@ -171,9 +166,6 @@ void activate_module(void)
hna_local_add(soft_device->dev_addr);
if (bat_device_setup() < 1)
goto end;
if (vis_init() < 1)
goto err;
......@@ -182,8 +174,7 @@ void activate_module(void)
goto end;
err:
printk(KERN_ERR "batman-adv:"
"Unable to allocate memory for mesh information structures: "
pr_err("Unable to allocate memory for mesh information structures: "
"out of mem ?\n");
deactivate_module();
end:
......@@ -208,7 +199,6 @@ void deactivate_module(void)
hna_global_free();
synchronize_net();
bat_device_destroy();
synchronize_rcu();
atomic_set(&module_state, MODULE_INACTIVE);
......@@ -226,8 +216,7 @@ void dec_module_count(void)
int addr_to_string(char *buff, uint8_t *addr)
{
return sprintf(buff, MAC_FMT,
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
return sprintf(buff, "%pM", addr);
}
/* returns 1 if they are the same originator */
......@@ -284,6 +273,9 @@ int is_mcast(uint8_t *addr)
return *addr & 0x01;
}
module_init(batman_init);
module_exit(batman_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
......
......@@ -19,6 +19,9 @@
*
*/
#ifndef _NET_BATMAN_ADV_MAIN_H_
#define _NET_BATMAN_ADV_MAIN_H_
/* Kernel Programming */
#define LINUX
......@@ -27,7 +30,7 @@
#define DRIVER_DESC "B.A.T.M.A.N. advanced"
#define DRIVER_DEVICE "batman-adv"
#define SOURCE_VERSION "0.2.2-beta"
#define SOURCE_VERSION "maint"
/* B.A.T.M.A.N. parameters */
......@@ -36,10 +39,10 @@
#define JITTER 20
#define TTL 50 /* Time To Live of broadcast messages */
#define PURGE_TIMEOUT 200000 /* purge originators after time in ms if no
#define PURGE_TIMEOUT 200 /* purge originators after time in seconds if no
* valid packet comes in -> TODO: check
* influence on TQ_LOCAL_WINDOW_SIZE */
#define LOCAL_HNA_TIMEOUT 3600000
#define LOCAL_HNA_TIMEOUT 3600 /* in seconds */
#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator
* messages in squence numbers (should be a
......@@ -57,44 +60,42 @@
#define LOG_BUF_LEN 8192 /* has to be a power of 2 */
#define ETH_STR_LEN 20
#define VIS_INTERVAL 5000 /* 5 seconds */
/* how much worse secondary interfaces may be to
* to be considered as bonding candidates */
#define BONDING_TQ_THRESHOLD 50
#define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or
* change the size of
* forw_packet->direct_link_flags */
#define MAX_AGGREGATION_MS 100
#define RESET_PROTECTION_MS 30000
#define EXPECTED_SEQNO_RANGE 4096
#define EXPECTED_SEQNO_RANGE 65536
/* don't reset again within 30 seconds */
#define MODULE_INACTIVE 0
#define MODULE_ACTIVE 1
#define MODULE_DEACTIVATING 2
#define BCAST_QUEUE_LEN 256
#define BCAST_QUEUE_LEN 256
#define BATMAN_QUEUE_LEN 256
/*
* Debug Messages
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* Append 'batman-adv: ' before
* kernel messages */
#define DBG_BATMAN 1 /* all messages related to routing / flooding /
* broadcasting / etc */
#define DBG_ROUTES 2 /* route or hna added / changed / deleted */
#define DBG_ALL 3
#ifdef CONFIG_BATMAN_ADV_DEBUG
extern int debug;
#define LOG_BUF_LEN 8192 /* has to be a power of 2 */
extern int bat_debug_type(int type);
#define bat_dbg(type, fmt, arg...) do { \
if (bat_debug_type(type)) \
printk(KERN_DEBUG "batman-adv:" fmt, ## arg); \
} \
while (0)
#else /* !CONFIG_BATMAN_ADV_DEBUG */
#define bat_dbg(type, fmt, arg...) do { \
} \
while (0)
#endif
/*
* Vis
......@@ -117,6 +118,7 @@ extern int bat_debug_type(int type);
#include <linux/slab.h>
#include <net/sock.h> /* struct sock */
#include <linux/jiffies.h>
#include <linux/seq_file.h>
#include "types.h"
#ifndef REVISION_VERSION
......@@ -134,14 +136,13 @@ extern spinlock_t orig_hash_lock;
extern spinlock_t forw_bat_list_lock;
extern spinlock_t forw_bcast_list_lock;
extern atomic_t vis_interval;
extern atomic_t bcast_queue_left;
extern atomic_t batman_queue_left;
extern int16_t num_hna;
extern struct net_device *soft_device;
extern unsigned char broadcastAddr[];
extern unsigned char broadcast_addr[];
extern atomic_t module_state;
extern struct workqueue_struct *bat_event_workqueue;
......@@ -155,3 +156,44 @@ int choose_orig(void *data, int32_t size);
int is_my_mac(uint8_t *addr);
int is_bcast(uint8_t *addr);
int is_mcast(uint8_t *addr);
#ifdef CONFIG_BATMAN_ADV_DEBUG
extern int debug_log(struct bat_priv *bat_priv, char *fmt, ...);
#define bat_dbg(type, bat_priv, fmt, arg...) \
do { \
if (atomic_read(&bat_priv->log_level) & type) \
debug_log(bat_priv, fmt, ## arg); \
} \
while (0)
#else /* !CONFIG_BATMAN_ADV_DEBUG */
static inline void bat_dbg(char type __attribute__((unused)),
struct bat_priv *bat_priv __attribute__((unused)),
char *fmt __attribute__((unused)), ...)
{
}
#endif
#define bat_warning(net_dev, fmt, arg...) \
do { \
struct net_device *_netdev = (net_dev); \
struct bat_priv *_batpriv = netdev_priv(_netdev); \
bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \
pr_warning("%s: " fmt, _netdev->name, ## arg); \
} while (0)
#define bat_info(net_dev, fmt, arg...) \
do { \
struct net_device *_netdev = (net_dev); \
struct bat_priv *_batpriv = netdev_priv(_netdev); \
bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \
pr_info("%s: " fmt, _netdev->name, ## arg); \
} while (0)
#define bat_err(net_dev, fmt, arg...) \
do { \
struct net_device *_netdev = (net_dev); \
struct bat_priv *_batpriv = netdev_priv(_netdev); \
bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \
pr_err("%s: " fmt, _netdev->name, ## arg); \
} while (0)
#endif /* _NET_BATMAN_ADV_MAIN_H_ */
......@@ -56,28 +56,16 @@ int originator_init(void)
return 0;
}
void originator_free(void)
{
unsigned long flags;
if (!orig_hash)
return;
cancel_delayed_work_sync(&purge_orig_wq);
spin_lock_irqsave(&orig_hash_lock, flags);
hash_delete(orig_hash, free_orig_node);
orig_hash = NULL;
spin_unlock_irqrestore(&orig_hash_lock, flags);
}
struct neigh_node *
create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
uint8_t *neigh, struct batman_if *if_incoming)
{
/* FIXME: each orig_node->batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct neigh_node *neigh_node;
bat_dbg(DBG_BATMAN, "Creating new last-hop neighbor of originator\n");
bat_dbg(DBG_BATMAN, bat_priv,
"Creating new last-hop neighbor of originator\n");
neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC);
if (!neigh_node)
......@@ -93,7 +81,7 @@ create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
return neigh_node;
}
void free_orig_node(void *data)
static void free_orig_node(void *data)
{
struct list_head *list_pos, *list_pos_tmp;
struct neigh_node *neigh_node;
......@@ -114,6 +102,21 @@ void free_orig_node(void *data)
kfree(orig_node);
}
void originator_free(void)
{
unsigned long flags;
if (!orig_hash)
return;
cancel_delayed_work_sync(&purge_orig_wq);
spin_lock_irqsave(&orig_hash_lock, flags);
hash_delete(orig_hash, free_orig_node);
orig_hash = NULL;
spin_unlock_irqrestore(&orig_hash_lock, flags);
}
/* this function finds or creates an originator entry for the given
* address if it does not exits */
struct orig_node *get_orig_node(uint8_t *addr)
......@@ -129,7 +132,8 @@ struct orig_node *get_orig_node(uint8_t *addr)
if (orig_node != NULL)
return orig_node;
bat_dbg(DBG_BATMAN, "Creating new originator: %pM\n", addr);
bat_dbg(DBG_BATMAN, bat_priv,
"Creating new originator: %pM\n", addr);
orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC);
if (!orig_node)
......@@ -163,8 +167,8 @@ struct orig_node *get_orig_node(uint8_t *addr)
swaphash = hash_resize(orig_hash, orig_hash->size * 2);
if (swaphash == NULL)
printk(KERN_ERR
"batman-adv:Couldn't resize orig hash table\n");
bat_err(soft_device,
"Couldn't resize orig hash table\n");
else
orig_hash = swaphash;
}
......@@ -182,6 +186,8 @@ struct orig_node *get_orig_node(uint8_t *addr)
static bool purge_orig_neighbors(struct orig_node *orig_node,
struct neigh_node **best_neigh_node)
{
/* FIXME: each orig_node->batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct list_head *list_pos, *list_pos_tmp;
struct neigh_node *neigh_node;
bool neigh_purged = false;
......@@ -193,20 +199,19 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
neigh_node = list_entry(list_pos, struct neigh_node, list);
if ((time_after(jiffies,
(neigh_node->last_valid +
((PURGE_TIMEOUT * HZ) / 1000)))) ||
neigh_node->last_valid + PURGE_TIMEOUT * HZ)) ||
(neigh_node->if_incoming->if_status ==
IF_TO_BE_REMOVED)) {
if (neigh_node->if_incoming->if_status ==
IF_TO_BE_REMOVED)
bat_dbg(DBG_BATMAN,
bat_dbg(DBG_BATMAN, bat_priv,
"neighbor purge: originator %pM, "
"neighbor: %pM, iface: %s\n",
orig_node->orig, neigh_node->addr,
neigh_node->if_incoming->dev);
else
bat_dbg(DBG_BATMAN,
bat_dbg(DBG_BATMAN, bat_priv,
"neighbor timeout: originator %pM, "
"neighbor: %pM, last_valid: %lu\n",
orig_node->orig, neigh_node->addr,
......@@ -226,21 +231,26 @@ static bool purge_orig_neighbors(struct orig_node *orig_node,
static bool purge_orig_node(struct orig_node *orig_node)
{
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct neigh_node *best_neigh_node;
if (time_after(jiffies,
(orig_node->last_valid +
((2 * PURGE_TIMEOUT * HZ) / 1000)))) {
orig_node->last_valid + 2 * PURGE_TIMEOUT * HZ)) {
bat_dbg(DBG_BATMAN,
bat_dbg(DBG_BATMAN, bat_priv,
"Originator timeout: originator %pM, last_valid %lu\n",
orig_node->orig, (orig_node->last_valid / HZ));
return true;
} else {
if (purge_orig_neighbors(orig_node, &best_neigh_node))
if (purge_orig_neighbors(orig_node, &best_neigh_node)) {
update_routes(orig_node, best_neigh_node,
orig_node->hna_buff,
orig_node->hna_buff_len);
/* update bonding candidates, we could have lost
* some candidates. */
update_bonding_candidates(bat_priv, orig_node);
}
}
return false;
......@@ -271,49 +281,41 @@ void purge_orig(struct work_struct *work)
start_purge_timer();
}
ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
size_t count, loff_t off)
int orig_seq_print_text(struct seq_file *seq, void *offset)
{
HASHIT(hashit);
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
struct orig_node *orig_node;
struct neigh_node *neigh_node;
size_t hdr_len, tmp_len;
int batman_count = 0, bytes_written = 0;
int batman_count = 0;
int last_seen_secs;
int last_seen_msecs;
unsigned long flags;
char orig_str[ETH_STR_LEN], router_str[ETH_STR_LEN];
if (!bat_priv->primary_if) {
if (off == 0)
return sprintf(buff,
"BATMAN mesh %s disabled - "
if ((!bat_priv->primary_if) ||
(bat_priv->primary_if->if_status != IF_ACTIVE)) {
if (!bat_priv->primary_if)
return seq_printf(seq, "BATMAN mesh %s disabled - "
"please specify interfaces to enable it\n",
net_dev->name);
return 0;
return seq_printf(seq, "BATMAN mesh %s "
"disabled - primary interface not active\n",
net_dev->name);
}
if (bat_priv->primary_if->if_status != IF_ACTIVE && off == 0)
return sprintf(buff,
"BATMAN mesh %s "
"disabled - primary interface not active\n",
net_dev->name);
else if (bat_priv->primary_if->if_status != IF_ACTIVE)
return 0;
rcu_read_lock();
hdr_len = sprintf(buff,
" %-14s (%s/%i) %17s [%10s]: %20s "
"... [B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n",
"Originator", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF",
"Potential nexthops", SOURCE_VERSION, REVISION_VERSION_STR,
seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%s (%s)]\n",
SOURCE_VERSION, REVISION_VERSION_STR,
bat_priv->primary_if->dev, bat_priv->primary_if->addr_str,
net_dev->name);
seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n",
"Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
"outgoingIF", "Potential nexthops");
rcu_read_unlock();
if (off < hdr_len)
bytes_written = hdr_len;
spin_lock_irqsave(&orig_hash_lock, flags);
while (hash_iterate(orig_hash, &hashit)) {
......@@ -326,44 +328,34 @@ ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
if (orig_node->router->tq_avg == 0)
continue;
/* estimated line length */
if (count < bytes_written + 200)
break;
addr_to_string(orig_str, orig_node->orig);
addr_to_string(router_str, orig_node->router->addr);
last_seen_secs = jiffies_to_msecs(jiffies -
orig_node->last_valid) / 1000;
last_seen_msecs = jiffies_to_msecs(jiffies -
orig_node->last_valid) % 1000;
tmp_len = sprintf(buff + bytes_written,
"%-17s (%3i) %17s [%10s]:",
orig_str, orig_node->router->tq_avg,
router_str,
orig_node->router->if_incoming->dev);
seq_printf(seq, "%-17s %4i.%03is (%3i) %17s [%10s]:",
orig_str, last_seen_secs, last_seen_msecs,
orig_node->router->tq_avg, router_str,
orig_node->router->if_incoming->dev);
list_for_each_entry(neigh_node, &orig_node->neigh_list, list) {
addr_to_string(orig_str, neigh_node->addr);
tmp_len += sprintf(buff + bytes_written + tmp_len,
" %17s (%3i)", orig_str,
seq_printf(seq, " %17s (%3i)", orig_str,
neigh_node->tq_avg);
}
tmp_len += sprintf(buff + bytes_written + tmp_len, "\n");
seq_printf(seq, "\n");
batman_count++;
hdr_len += tmp_len;
if (off >= hdr_len)
continue;
bytes_written += tmp_len;
}
spin_unlock_irqrestore(&orig_hash_lock, flags);
if ((batman_count == 0) && (off == 0))
bytes_written += sprintf(buff + bytes_written,
"No batman nodes in range ...\n");
if ((batman_count == 0))
seq_printf(seq, "No batman nodes in range ...\n");
return bytes_written;
return 0;
}
static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
......@@ -373,8 +365,7 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS,
GFP_ATOMIC);
if (!data_ptr) {
printk(KERN_ERR
"batman-adv:Can't resize orig: out of memory\n");
pr_err("Can't resize orig: out of memory\n");
return -1;
}
......@@ -385,8 +376,7 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num)
data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
if (!data_ptr) {
printk(KERN_ERR
"batman-adv:Can't resize orig: out of memory\n");
pr_err("Can't resize orig: out of memory\n");
return -1;
}
......@@ -435,8 +425,7 @@ static int orig_node_del_if(struct orig_node *orig_node,
chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS;
data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC);
if (!data_ptr) {
printk(KERN_ERR
"batman-adv:Can't resize orig: out of memory\n");
pr_err("Can't resize orig: out of memory\n");
return -1;
}
......@@ -457,8 +446,7 @@ static int orig_node_del_if(struct orig_node *orig_node,
data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
if (!data_ptr) {
printk(KERN_ERR
"batman-adv:Can't resize orig: out of memory\n");
pr_err("Can't resize orig: out of memory\n");
return -1;
}
......
......@@ -19,16 +19,18 @@
*
*/
#ifndef _NET_BATMAN_ADV_ORIGINATOR_H_
#define _NET_BATMAN_ADV_ORIGINATOR_H_
int originator_init(void);
void free_orig_node(void *data);
void originator_free(void);
void purge_orig(struct work_struct *work);
struct orig_node *orig_find(char *mac);
struct orig_node *get_orig_node(uint8_t *addr);
struct neigh_node *
create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node,
uint8_t *neigh, struct batman_if *if_incoming);
ssize_t orig_fill_buffer_text(struct net_device *net_dev, char *buff,
size_t count, loff_t off);
int orig_seq_print_text(struct seq_file *seq, void *offset);
int orig_hash_add_if(struct batman_if *batman_if, int max_if_num);
int orig_hash_del_if(struct batman_if *batman_if, int max_if_num);
#endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */
......@@ -19,6 +19,9 @@
*
*/
#ifndef _NET_BATMAN_ADV_PACKET_H_
#define _NET_BATMAN_ADV_PACKET_H_
#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */
#define BAT_PACKET 0x01
......@@ -28,9 +31,10 @@
#define BAT_VIS 0x05
/* this file is included by batctl which needs these defines */
#define COMPAT_VERSION 8
#define COMPAT_VERSION 11
#define DIRECTLINK 0x40
#define VIS_SERVER 0x20
#define PRIMARIES_FIRST_HOP 0x10
/* ICMP message types */
#define ECHO_REPLY 0
......@@ -48,7 +52,7 @@ struct batman_packet {
uint8_t version; /* batman version field */
uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
uint8_t tq;
uint16_t seqno;
uint32_t seqno;
uint8_t orig[6];
uint8_t prev_sender[6];
uint8_t ttl;
......@@ -68,6 +72,23 @@ struct icmp_packet {
uint8_t uid;
} __attribute__((packed));
#define BAT_RR_LEN 16
/* icmp_packet_rr must start with all fields from imcp_packet
as this is assumed by code that handles ICMP packets */
struct icmp_packet_rr {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t msg_type; /* see ICMP message types above */
uint8_t ttl;
uint8_t dst[6];
uint8_t orig[6];
uint16_t seqno;
uint8_t uid;
uint8_t rr_cur;
uint8_t rr[BAT_RR_LEN][ETH_ALEN];
} __attribute__((packed));
struct unicast_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
......@@ -79,18 +100,21 @@ struct bcast_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t orig[6];
uint16_t seqno;
uint8_t ttl;
uint32_t seqno;
} __attribute__((packed));
struct vis_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t vis_type; /* which type of vis-participant sent this? */
uint8_t seqno; /* sequence number */
uint8_t entries; /* number of entries behind this struct */
uint32_t seqno; /* sequence number */
uint8_t ttl; /* TTL */
uint8_t vis_orig[6]; /* originator that informs about its
* neighbors */
uint8_t target_orig[6]; /* who should receive this packet */
uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */
} __attribute__((packed));
#endif /* _NET_BATMAN_ADV_PACKET_H_ */
......@@ -19,5 +19,10 @@
*
*/
#ifndef _NET_BATMAN_ADV_RING_BUFFER_H_
#define _NET_BATMAN_ADV_RING_BUFFER_H_
void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value);
uint8_t ring_buffer_avg(uint8_t lq_recv[]);
#endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */
This diff is collapsed.
......@@ -19,9 +19,10 @@
*
*/
#include "types.h"
#ifndef _NET_BATMAN_ADV_ROUTING_H_
#define _NET_BATMAN_ADV_ROUTING_H_
extern wait_queue_head_t thread_wait;
#include "types.h"
void slide_own_bcast_window(struct batman_if *batman_if);
void receive_bat_packet(struct ethhdr *ethhdr,
......@@ -32,8 +33,14 @@ void update_routes(struct orig_node *orig_node,
struct neigh_node *neigh_node,
unsigned char *hna_buff, int hna_buff_len);
int recv_icmp_packet(struct sk_buff *skb);
int recv_unicast_packet(struct sk_buff *skb);
int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if);
int recv_bcast_packet(struct sk_buff *skb);
int recv_vis_packet(struct sk_buff *skb);
int recv_bat_packet(struct sk_buff *skb,
struct batman_if *batman_if);
struct neigh_node *find_router(struct orig_node *orig_node,
struct batman_if *recv_if);
void update_bonding_candidates(struct bat_priv *bat_priv,
struct orig_node *orig_node);
#endif /* _NET_BATMAN_ADV_ROUTING_H_ */
......@@ -29,6 +29,10 @@
#include "vis.h"
#include "aggregation.h"
#include <linux/netfilter_bridge.h>
static void send_outstanding_bcast_packet(struct work_struct *work);
/* apply hop penalty for a normal link */
static uint8_t hop_penalty(const uint8_t tq)
{
......@@ -38,15 +42,15 @@ static uint8_t hop_penalty(const uint8_t tq)
/* when do we schedule our own packet to be sent */
static unsigned long own_send_time(struct bat_priv *bat_priv)
{
return jiffies +
(((atomic_read(&bat_priv->orig_interval) - JITTER +
(random32() % 2*JITTER)) * HZ) / 1000);
return jiffies + msecs_to_jiffies(
atomic_read(&bat_priv->orig_interval) -
JITTER + (random32() % 2*JITTER));
}
/* when do we schedule a forwarded packet to be sent */
static unsigned long forward_send_time(struct bat_priv *bat_priv)
{
return jiffies + (((random32() % (JITTER/2)) * HZ) / 1000);
return jiffies + msecs_to_jiffies(random32() % (JITTER/2));
}
/* send out an already prepared packet to the given address via the
......@@ -64,10 +68,8 @@ int send_skb_packet(struct sk_buff *skb,
goto send_skb_err;
if (!(batman_if->net_dev->flags & IFF_UP)) {
printk(KERN_WARNING
"batman-adv:Interface %s "
"is not up - can't send packet via that interface!\n",
batman_if->dev);
pr_warning("Interface %s is not up - can't send packet via "
"that interface!\n", batman_if->dev);
goto send_skb_err;
}
......@@ -90,9 +92,12 @@ int send_skb_packet(struct sk_buff *skb,
/* dev_queue_xmit() returns a negative result on error. However on
* congestion and traffic shaping, it drops and returns NET_XMIT_DROP
* (which is > 0). This will not be treated as an error. */
* (which is > 0). This will not be treated as an error.
* Also, if netfilter/ebtables wants to block outgoing batman
* packets then giving them a chance to do so here */
return dev_queue_xmit(skb);
return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
dev_queue_xmit);
send_skb_err:
kfree_skb(skb);
return NET_XMIT_DROP;
......@@ -119,6 +124,8 @@ void send_raw_packet(unsigned char *pack_buff, int pack_buff_len,
static void send_packet_to_if(struct forw_packet *forw_packet,
struct batman_if *batman_if)
{
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
char *fwd_str;
uint8_t packet_num;
int16_t buff_pos;
......@@ -148,11 +155,11 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ?
"Sending own" :
"Forwarding"));
bat_dbg(DBG_BATMAN,
bat_dbg(DBG_BATMAN, bat_priv,
"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
" IDF %s) on interface %s [%s]\n",
fwd_str, (packet_num > 0 ? "aggregated " : ""),
batman_packet->orig, ntohs(batman_packet->seqno),
batman_packet->orig, ntohl(batman_packet->seqno),
batman_packet->tq, batman_packet->ttl,
(batman_packet->flags & DIRECTLINK ?
"on" : "off"),
......@@ -167,20 +174,22 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
send_raw_packet(forw_packet->packet_buff,
forw_packet->packet_len,
batman_if, broadcastAddr);
batman_if, broadcast_addr);
}
/* send a batman packet */
static void send_packet(struct forw_packet *forw_packet)
{
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct batman_if *batman_if;
struct batman_packet *batman_packet =
(struct batman_packet *)(forw_packet->packet_buff);
unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
if (!forw_packet->if_incoming) {
printk(KERN_ERR "batman-adv: Error - can't forward packet: "
"incoming iface not specified\n");
pr_err("Error - can't forward packet: incoming iface not "
"specified\n");
return;
}
......@@ -193,18 +202,18 @@ static void send_packet(struct forw_packet *forw_packet)
(forw_packet->own && (forw_packet->if_incoming->if_num > 0))) {
/* FIXME: what about aggregated packets ? */
bat_dbg(DBG_BATMAN,
bat_dbg(DBG_BATMAN, bat_priv,
"%s packet (originator %pM, seqno %d, TTL %d) "
"on interface %s [%s]\n",
(forw_packet->own ? "Sending own" : "Forwarding"),
batman_packet->orig, ntohs(batman_packet->seqno),
batman_packet->orig, ntohl(batman_packet->seqno),
batman_packet->ttl, forw_packet->if_incoming->dev,
forw_packet->if_incoming->addr_str);
send_raw_packet(forw_packet->packet_buff,
forw_packet->packet_len,
forw_packet->if_incoming,
broadcastAddr);
broadcast_addr);
return;
}
......@@ -276,14 +285,14 @@ void schedule_own_packet(struct batman_if *batman_if)
batman_packet = (struct batman_packet *)batman_if->packet_buff;
/* change sequence number to network order */
batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno));
batman_packet->seqno =
htonl((uint32_t)atomic_read(&batman_if->seqno));
if (vis_server == VIS_TYPE_SERVER_SYNC)
batman_packet->flags = VIS_SERVER;
batman_packet->flags |= VIS_SERVER;
else
batman_packet->flags &= ~VIS_SERVER;
/* could be read by receive_bat_packet() */
atomic_inc(&batman_if->seqno);
slide_own_bcast_window(batman_if);
......@@ -306,7 +315,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
unsigned long send_time;
if (batman_packet->ttl <= 1) {
bat_dbg(DBG_BATMAN, "ttl exceeded\n");
bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
return;
}
......@@ -335,13 +344,16 @@ void schedule_forward_packet(struct orig_node *orig_node,
/* apply hop penalty */
batman_packet->tq = hop_penalty(batman_packet->tq);
bat_dbg(DBG_BATMAN, "Forwarding packet: tq_orig: %i, tq_avg: %i, "
bat_dbg(DBG_BATMAN, bat_priv,
"Forwarding packet: tq_orig: %i, tq_avg: %i, "
"tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n",
in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
batman_packet->ttl);
batman_packet->seqno = htons(batman_packet->seqno);
batman_packet->seqno = htonl(batman_packet->seqno);
/* switch of primaries first hop flag when forwarding */
batman_packet->flags &= ~PRIMARIES_FIRST_HOP;
if (directlink)
batman_packet->flags |= DIRECTLINK;
else
......@@ -392,9 +404,12 @@ static void _add_bcast_packet_to_list(struct forw_packet *forw_packet,
int add_bcast_packet_to_list(struct sk_buff *skb)
{
struct forw_packet *forw_packet;
struct bcast_packet *bcast_packet;
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
if (!atomic_dec_not_zero(&bcast_queue_left)) {
bat_dbg(DBG_BATMAN, "bcast packet queue full\n");
bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n");
goto out;
}
......@@ -407,6 +422,10 @@ int add_bcast_packet_to_list(struct sk_buff *skb)
if (!skb)
goto packet_free;
/* as we have a copy now, it is safe to decrease the TTL */
bcast_packet = (struct bcast_packet *)skb->data;
bcast_packet->ttl--;
skb_reset_mac_header(skb);
forw_packet->skb = skb;
......@@ -426,7 +445,7 @@ int add_bcast_packet_to_list(struct sk_buff *skb)
return NETDEV_TX_BUSY;
}
void send_outstanding_bcast_packet(struct work_struct *work)
static void send_outstanding_bcast_packet(struct work_struct *work)
{
struct batman_if *batman_if;
struct delayed_work *delayed_work =
......@@ -450,7 +469,7 @@ void send_outstanding_bcast_packet(struct work_struct *work)
skb1 = skb_copy(forw_packet->skb, GFP_ATOMIC);
if (skb1)
send_skb_packet(skb1,
batman_if, broadcastAddr);
batman_if, broadcast_addr);
}
rcu_read_unlock();
......@@ -502,15 +521,19 @@ void send_outstanding_bat_packet(struct work_struct *work)
void purge_outstanding_packets(struct batman_if *batman_if)
{
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct forw_packet *forw_packet;
struct hlist_node *tmp_node, *safe_tmp_node;
unsigned long flags;
if (batman_if)
bat_dbg(DBG_BATMAN, "purge_outstanding_packets(): %s\n",
bat_dbg(DBG_BATMAN, bat_priv,
"purge_outstanding_packets(): %s\n",
batman_if->dev);
else
bat_dbg(DBG_BATMAN, "purge_outstanding_packets()\n");
bat_dbg(DBG_BATMAN, bat_priv,
"purge_outstanding_packets()\n");
/* free bcast list */
spin_lock_irqsave(&forw_bcast_list_lock, flags);
......
......@@ -19,9 +19,11 @@
*
*/
#ifndef _NET_BATMAN_ADV_SEND_H_
#define _NET_BATMAN_ADV_SEND_H_
#include "types.h"
void send_own_packet_work(struct work_struct *work);
int send_skb_packet(struct sk_buff *skb,
struct batman_if *batman_if,
uint8_t *dst_addr);
......@@ -34,6 +36,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
uint8_t directlink, int hna_buff_len,
struct batman_if *if_outgoing);
int add_bcast_packet_to_list(struct sk_buff *skb);
void send_outstanding_bcast_packet(struct work_struct *work);
void send_outstanding_bat_packet(struct work_struct *work);
void purge_outstanding_packets(struct batman_if *batman_if);
#endif /* _NET_BATMAN_ADV_SEND_H_ */
......@@ -22,6 +22,7 @@
#include "main.h"
#include "soft-interface.h"
#include "hard-interface.h"
#include "routing.h"
#include "send.h"
#include "translation-table.h"
#include "types.h"
......@@ -30,13 +31,12 @@
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
static uint32_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
* broadcast storms */
static int32_t skb_packets;
static int32_t skb_bad_packets;
unsigned char mainIfAddr[ETH_ALEN];
static unsigned char mainIfAddr_default[ETH_ALEN];
unsigned char main_if_addr[ETH_ALEN];
static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
static void bat_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info);
......@@ -58,12 +58,7 @@ static const struct ethtool_ops bat_ethtool_ops = {
void set_main_if_addr(uint8_t *addr)
{
memcpy(mainIfAddr, addr, ETH_ALEN);
}
int main_if_was_up(void)
{
return (memcmp(mainIfAddr, mainIfAddr_default, ETH_ALEN) != 0 ? 1 : 0);
memcpy(main_if_addr, addr, ETH_ALEN);
}
int my_skb_push(struct sk_buff *skb, unsigned int len)
......@@ -83,69 +78,25 @@ int my_skb_push(struct sk_buff *skb, unsigned int len)
return 0;
}
#ifdef HAVE_NET_DEVICE_OPS
static const struct net_device_ops bat_netdev_ops = {
.ndo_open = interface_open,
.ndo_stop = interface_release,
.ndo_get_stats = interface_stats,
.ndo_set_mac_address = interface_set_mac_addr,
.ndo_change_mtu = interface_change_mtu,
.ndo_start_xmit = interface_tx,
.ndo_validate_addr = eth_validate_addr
};
#endif
void interface_setup(struct net_device *dev)
{
struct bat_priv *priv = netdev_priv(dev);
char dev_addr[ETH_ALEN];
ether_setup(dev);
#ifdef HAVE_NET_DEVICE_OPS
dev->netdev_ops = &bat_netdev_ops;
#else
dev->open = interface_open;
dev->stop = interface_release;
dev->get_stats = interface_stats;
dev->set_mac_address = interface_set_mac_addr;
dev->change_mtu = interface_change_mtu;
dev->hard_start_xmit = interface_tx;
#endif
dev->destructor = free_netdev;
dev->mtu = hardif_min_mtu();
dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
* skbuff for our header */
/* generate random address */
random_ether_addr(dev_addr);
memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
memset(priv, 0, sizeof(struct bat_priv));
}
int interface_open(struct net_device *dev)
static int interface_open(struct net_device *dev)
{
netif_start_queue(dev);
return 0;
}
int interface_release(struct net_device *dev)
static int interface_release(struct net_device *dev)
{
netif_stop_queue(dev);
return 0;
}
struct net_device_stats *interface_stats(struct net_device *dev)
static struct net_device_stats *interface_stats(struct net_device *dev)
{
struct bat_priv *priv = netdev_priv(dev);
return &priv->stats;
}
int interface_set_mac_addr(struct net_device *dev, void *p)
static int interface_set_mac_addr(struct net_device *dev, void *p)
{
struct sockaddr *addr = p;
......@@ -163,7 +114,7 @@ int interface_set_mac_addr(struct net_device *dev, void *p)
return 0;
}
int interface_change_mtu(struct net_device *dev, int new_mtu)
static int interface_change_mtu(struct net_device *dev, int new_mtu)
{
/* check ranges */
if ((new_mtu < 68) || (new_mtu > hardif_min_mtu()))
......@@ -179,6 +130,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
struct unicast_packet *unicast_packet;
struct bcast_packet *bcast_packet;
struct orig_node *orig_node;
struct neigh_node *router;
struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
struct bat_priv *priv = netdev_priv(dev);
struct batman_if *batman_if;
......@@ -205,16 +157,17 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
bcast_packet = (struct bcast_packet *)skb->data;
bcast_packet->version = COMPAT_VERSION;
bcast_packet->ttl = TTL;
/* batman packet type: broadcast */
bcast_packet->packet_type = BAT_BCAST;
/* hw address of first interface is the orig mac because only
* this mac is known throughout the mesh */
memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN);
memcpy(bcast_packet->orig, main_if_addr, ETH_ALEN);
/* set broadcast sequence number */
bcast_packet->seqno = htons(bcast_seqno);
bcast_packet->seqno = htonl(bcast_seqno);
/* broadcast packet. on success, increase seqno. */
if (add_bcast_packet_to_list(skb) == NETDEV_TX_OK)
......@@ -235,38 +188,36 @@ int interface_tx(struct sk_buff *skb, struct net_device *dev)
if (!orig_node)
orig_node = transtable_search(ethhdr->h_dest);
if ((orig_node) &&
(orig_node->router)) {
struct neigh_node *router = orig_node->router;
router = find_router(orig_node, NULL);
if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0)
goto unlock;
if (!router)
goto unlock;
unicast_packet = (struct unicast_packet *)skb->data;
/* don't lock while sending the packets ... we therefore
* copy the required data before sending */
unicast_packet->version = COMPAT_VERSION;
/* batman packet type: unicast */
unicast_packet->packet_type = BAT_UNICAST;
/* set unicast ttl */
unicast_packet->ttl = TTL;
/* copy the destination for faster routing */
memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
batman_if = router->if_incoming;
memcpy(dstaddr, router->addr, ETH_ALEN);
/* net_dev won't be available when not active */
if (router->if_incoming->if_status != IF_ACTIVE)
goto unlock;
spin_unlock_irqrestore(&orig_hash_lock, flags);
/* don't lock while sending the packets ... we therefore
* copy the required data before sending */
if (batman_if->if_status != IF_ACTIVE)
goto dropped;
batman_if = router->if_incoming;
memcpy(dstaddr, router->addr, ETH_ALEN);
spin_unlock_irqrestore(&orig_hash_lock, flags);
if (my_skb_push(skb, sizeof(struct unicast_packet)) < 0)
goto dropped;
send_skb_packet(skb, batman_if, dstaddr);
} else {
goto unlock;
}
unicast_packet = (struct unicast_packet *)skb->data;
unicast_packet->version = COMPAT_VERSION;
/* batman packet type: unicast */
unicast_packet->packet_type = BAT_UNICAST;
/* set unicast ttl */
unicast_packet->ttl = TTL;
/* copy the destination for faster routing */
memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
send_skb_packet(skb, batman_if, dstaddr);
}
priv->stats.tx_packets++;
......@@ -315,6 +266,50 @@ void interface_rx(struct sk_buff *skb, int hdr_size)
netif_rx(skb);
}
#ifdef HAVE_NET_DEVICE_OPS
static const struct net_device_ops bat_netdev_ops = {
.ndo_open = interface_open,
.ndo_stop = interface_release,
.ndo_get_stats = interface_stats,
.ndo_set_mac_address = interface_set_mac_addr,
.ndo_change_mtu = interface_change_mtu,
.ndo_start_xmit = interface_tx,
.ndo_validate_addr = eth_validate_addr
};
#endif
void interface_setup(struct net_device *dev)
{
struct bat_priv *priv = netdev_priv(dev);
char dev_addr[ETH_ALEN];
ether_setup(dev);
#ifdef HAVE_NET_DEVICE_OPS
dev->netdev_ops = &bat_netdev_ops;
#else
dev->open = interface_open;
dev->stop = interface_release;
dev->get_stats = interface_stats;
dev->set_mac_address = interface_set_mac_addr;
dev->change_mtu = interface_change_mtu;
dev->hard_start_xmit = interface_tx;
#endif
dev->destructor = free_netdev;
dev->mtu = hardif_min_mtu();
dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the
* skbuff for our header */
/* generate random address */
random_ether_addr(dev_addr);
memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
memset(priv, 0, sizeof(struct bat_priv));
}
/* ethtool */
static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
......
......@@ -19,16 +19,15 @@
*
*/
#ifndef _NET_BATMAN_ADV_SOFT_INTERFACE_H_
#define _NET_BATMAN_ADV_SOFT_INTERFACE_H_
void set_main_if_addr(uint8_t *addr);
int main_if_was_up(void);
void interface_setup(struct net_device *dev);
int interface_open(struct net_device *dev);
int interface_release(struct net_device *dev);
struct net_device_stats *interface_stats(struct net_device *dev);
int interface_set_mac_addr(struct net_device *dev, void *addr);
int interface_change_mtu(struct net_device *dev, int new_mtu);
int interface_tx(struct sk_buff *skb, struct net_device *dev);
void interface_rx(struct sk_buff *skb, int hdr_size);
int my_skb_push(struct sk_buff *skb, unsigned int len);
extern unsigned char mainIfAddr[];
extern unsigned char main_if_addr[];
#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */
What: /sys/class/net/<iface>/batman-adv/mesh_iface
Date: May 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
The /sys/class/net/<iface>/batman-adv/mesh_iface file
displays the batman mesh interface this <iface>
currently is associated with.
What: /sys/class/net/<iface>/batman-adv/iface_status
Date: May 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
Indicates the status of <iface> as it is seen by batman.
What: /sys/class/net/<mesh_iface>/mesh/aggregated_ogms
Date: May 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
Indicates whether the batman protocol messages of the
mesh <mesh_iface> shall be aggregated or not.
What: /sys/class/net/<mesh_iface>/mesh/bonding
Date: June 2010
Contact: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Description:
Indicates whether the data traffic going through the
mesh will be sent using multiple interfaces at the
same time (if available).
What: /sys/class/net/<mesh_iface>/mesh/orig_interval
Date: May 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
Defines the interval in milliseconds in which batman
sends its protocol messages.
What: /sys/class/net/<mesh_iface>/mesh/vis_mode
Date: May 2010
Contact: Marek Lindner <lindner_marek@yahoo.de>
Description:
Each batman node only maintains information about its
own local neighborhood, therefore generating graphs
showing the topology of the entire mesh is not easily
feasible without having a central instance to collect
the local topologies from all nodes. This file allows
to activate the collecting (server) mode.
......@@ -32,7 +32,10 @@ atomic_t hna_local_changed;
DEFINE_SPINLOCK(hna_local_hash_lock);
static DEFINE_SPINLOCK(hna_global_hash_lock);
static void hna_local_purge(struct work_struct *work);
static DECLARE_DELAYED_WORK(hna_local_purge_wq, hna_local_purge);
static void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
char *message);
static void hna_local_start_timer(void)
{
......@@ -57,6 +60,8 @@ int hna_local_init(void)
void hna_local_add(uint8_t *addr)
{
/* FIXME: each orig_node->batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct hna_local_entry *hna_local_entry;
struct hna_global_entry *hna_global_entry;
struct hashtable_t *swaphash;
......@@ -77,15 +82,15 @@ void hna_local_add(uint8_t *addr)
MAC-flooding. */
if ((num_hna + 1 > (ETH_DATA_LEN - BAT_PACKET_LEN) / ETH_ALEN) ||
(num_hna + 1 > 255)) {
bat_dbg(DBG_ROUTES,
bat_dbg(DBG_ROUTES, bat_priv,
"Can't add new local hna entry (%pM): "
"number of local hna entries exceeds packet size\n",
addr);
return;
}
bat_dbg(DBG_ROUTES, "Creating new local hna entry: %pM\n",
addr);
bat_dbg(DBG_ROUTES, bat_priv,
"Creating new local hna entry: %pM\n", addr);
hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC);
if (!hna_local_entry)
......@@ -111,8 +116,7 @@ void hna_local_add(uint8_t *addr)
hna_local_hash->size * 2);
if (swaphash == NULL)
printk(KERN_ERR "batman-adv:"
"Couldn't resize local hna hash table\n");
pr_err("Couldn't resize local hna hash table\n");
else
hna_local_hash = swaphash;
}
......@@ -160,59 +164,54 @@ int hna_local_fill_buffer(unsigned char *buff, int buff_len)
return i;
}
int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
size_t count, loff_t off)
int hna_local_seq_print_text(struct seq_file *seq, void *offset)
{
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
struct hna_local_entry *hna_local_entry;
HASHIT(hashit);
int bytes_written = 0;
HASHIT(hashit_count);
unsigned long flags;
size_t hdr_len;
size_t buf_size, pos;
char *buff;
if (!bat_priv->primary_if) {
if (off == 0)
return sprintf(buff,
"BATMAN mesh %s disabled - "
"please specify interfaces to enable it\n",
net_dev->name);
return 0;
return seq_printf(seq, "BATMAN mesh %s disabled - "
"please specify interfaces to enable it\n",
net_dev->name);
}
hdr_len = sprintf(buff,
"Locally retrieved addresses (from %s) "
"announced via HNA:\n",
net_dev->name);
if (off < hdr_len)
bytes_written = hdr_len;
seq_printf(seq, "Locally retrieved addresses (from %s) "
"announced via HNA:\n",
net_dev->name);
spin_lock_irqsave(&hna_local_hash_lock, flags);
while (hash_iterate(hna_local_hash, &hashit)) {
hdr_len += 21;
if (count < bytes_written + 22)
break;
buf_size = 1;
/* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */
while (hash_iterate(hna_local_hash, &hashit_count))
buf_size += 21;
if (off >= hdr_len)
continue;
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
spin_unlock_irqrestore(&hna_local_hash_lock, flags);
return -ENOMEM;
}
buff[0] = '\0';
pos = 0;
while (hash_iterate(hna_local_hash, &hashit)) {
hna_local_entry = hashit.bucket->data;
bytes_written += snprintf(buff + bytes_written, 22,
" * " MAC_FMT "\n",
hna_local_entry->addr[0],
hna_local_entry->addr[1],
hna_local_entry->addr[2],
hna_local_entry->addr[3],
hna_local_entry->addr[4],
hna_local_entry->addr[5]);
pos += snprintf(buff + pos, 22, " * %pM\n",
hna_local_entry->addr);
}
spin_unlock_irqrestore(&hna_local_hash_lock, flags);
return bytes_written;
seq_printf(seq, "%s", buff);
kfree(buff);
return 0;
}
static void _hna_local_del(void *data)
......@@ -225,7 +224,9 @@ static void _hna_local_del(void *data)
static void hna_local_del(struct hna_local_entry *hna_local_entry,
char *message)
{
bat_dbg(DBG_ROUTES, "Deleting local hna entry (%pM): %s\n",
/* FIXME: each orig_node->batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n",
hna_local_entry->addr, message);
hash_remove(hna_local_hash, hna_local_entry->addr);
......@@ -247,7 +248,7 @@ void hna_local_remove(uint8_t *addr, char *message)
spin_unlock_irqrestore(&hna_local_hash_lock, flags);
}
void hna_local_purge(struct work_struct *work)
static void hna_local_purge(struct work_struct *work)
{
struct hna_local_entry *hna_local_entry;
HASHIT(hashit);
......@@ -259,8 +260,7 @@ void hna_local_purge(struct work_struct *work)
while (hash_iterate(hna_local_hash, &hashit)) {
hna_local_entry = hashit.bucket->data;
timeout = hna_local_entry->last_seen +
((LOCAL_HNA_TIMEOUT / 1000) * HZ);
timeout = hna_local_entry->last_seen + LOCAL_HNA_TIMEOUT * HZ;
if ((!hna_local_entry->never_purge) &&
time_after(jiffies, timeout))
hna_local_del(hna_local_entry, "address timed out");
......@@ -296,6 +296,8 @@ int hna_global_init(void)
void hna_global_add_orig(struct orig_node *orig_node,
unsigned char *hna_buff, int hna_buff_len)
{
/* FIXME: each orig_node->batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
struct hna_global_entry *hna_global_entry;
struct hna_local_entry *hna_local_entry;
struct hashtable_t *swaphash;
......@@ -322,7 +324,7 @@ void hna_global_add_orig(struct orig_node *orig_node,
memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN);
bat_dbg(DBG_ROUTES,
bat_dbg(DBG_ROUTES, bat_priv,
"Creating new global hna entry: "
"%pM (via %pM)\n",
hna_global_entry->addr, orig_node->orig);
......@@ -369,8 +371,7 @@ void hna_global_add_orig(struct orig_node *orig_node,
hna_global_hash->size * 2);
if (swaphash == NULL)
printk(KERN_ERR "batman-adv:"
"Couldn't resize global hna hash table\n");
pr_err("Couldn't resize global hna hash table\n");
else
hna_global_hash = swaphash;
}
......@@ -378,71 +379,63 @@ void hna_global_add_orig(struct orig_node *orig_node,
spin_unlock_irqrestore(&hna_global_hash_lock, flags);
}
int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
size_t count, loff_t off)
int hna_global_seq_print_text(struct seq_file *seq, void *offset)
{
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
struct hna_global_entry *hna_global_entry;
HASHIT(hashit);
int bytes_written = 0;
HASHIT(hashit_count);
unsigned long flags;
size_t hdr_len;
size_t buf_size, pos;
char *buff;
if (!bat_priv->primary_if) {
if (off == 0)
return sprintf(buff,
"BATMAN mesh %s disabled - "
"please specify interfaces to enable it\n",
net_dev->name);
return 0;
return seq_printf(seq, "BATMAN mesh %s disabled - "
"please specify interfaces to enable it\n",
net_dev->name);
}
hdr_len = sprintf(buff,
"Globally announced HNAs received via the mesh %s "
"(translation table):\n",
net_dev->name);
if (off < hdr_len)
bytes_written = hdr_len;
seq_printf(seq, "Globally announced HNAs received via the mesh %s\n",
net_dev->name);
spin_lock_irqsave(&hna_global_hash_lock, flags);
while (hash_iterate(hna_global_hash, &hashit)) {
hdr_len += 43;
if (count < bytes_written + 44)
break;
buf_size = 1;
/* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/
while (hash_iterate(hna_global_hash, &hashit_count))
buf_size += 43;
if (off >= hdr_len)
continue;
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
spin_unlock_irqrestore(&hna_global_hash_lock, flags);
return -ENOMEM;
}
buff[0] = '\0';
pos = 0;
while (hash_iterate(hna_global_hash, &hashit)) {
hna_global_entry = hashit.bucket->data;
bytes_written += snprintf(buff + bytes_written, 44,
" * " MAC_FMT " via " MAC_FMT "\n",
hna_global_entry->addr[0],
hna_global_entry->addr[1],
hna_global_entry->addr[2],
hna_global_entry->addr[3],
hna_global_entry->addr[4],
hna_global_entry->addr[5],
hna_global_entry->orig_node->orig[0],
hna_global_entry->orig_node->orig[1],
hna_global_entry->orig_node->orig[2],
hna_global_entry->orig_node->orig[3],
hna_global_entry->orig_node->orig[4],
hna_global_entry->orig_node->orig[5]);
pos += snprintf(buff + pos, 44,
" * %pM via %pM\n", hna_global_entry->addr,
hna_global_entry->orig_node->orig);
}
spin_unlock_irqrestore(&hna_global_hash_lock, flags);
return bytes_written;
seq_printf(seq, "%s", buff);
kfree(buff);
return 0;
}
void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
char *message)
static void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
char *message)
{
bat_dbg(DBG_ROUTES, "Deleting global hna entry %pM (via %pM): %s\n",
/* FIXME: each orig_node->batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
bat_dbg(DBG_ROUTES, bat_priv,
"Deleting global hna entry %pM (via %pM): %s\n",
hna_global_entry->addr, hna_global_entry->orig_node->orig,
message);
......
......@@ -19,23 +19,21 @@
*
*/
#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
#include "types.h"
int hna_local_init(void);
void hna_local_add(uint8_t *addr);
void hna_local_remove(uint8_t *addr, char *message);
int hna_local_fill_buffer(unsigned char *buff, int buff_len);
int hna_local_fill_buffer_text(struct net_device *net_dev, char *buff,
size_t count, loff_t off);
void hna_local_purge(struct work_struct *work);
int hna_local_seq_print_text(struct seq_file *seq, void *offset);
void hna_local_free(void);
int hna_global_init(void);
void hna_global_add_orig(struct orig_node *orig_node, unsigned char *hna_buff,
int hna_buff_len);
int hna_global_fill_buffer_text(struct net_device *net_dev, char *buff,
size_t count, loff_t off);
void _hna_global_del_orig(struct hna_global_entry *hna_global_entry,
char *orig_str);
int hna_global_seq_print_text(struct seq_file *seq, void *offset);
void hna_global_del_orig(struct orig_node *orig_node, char *message);
void hna_global_free(void);
struct orig_node *transtable_search(uint8_t *addr);
......@@ -43,3 +41,5 @@ struct orig_node *transtable_search(uint8_t *addr);
extern spinlock_t hna_local_hash_lock;
extern struct hashtable_t *hna_local_hash;
extern atomic_t hna_local_changed;
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
......@@ -21,10 +21,8 @@
#ifndef TYPES_H
#define TYPES_H
#ifndef _NET_BATMAN_ADV_TYPES_H_
#define _NET_BATMAN_ADV_TYPES_H_
#include "packet.h"
#include "bitarray.h"
......@@ -52,6 +50,7 @@ struct batman_if {
/**
* orig_node - structure for orig_list maintaining nodes of mesh
* @primary_addr: hosts primary interface address
* @last_valid: when last packet from this node was received
* @bcast_seqno_reset: time when the broadcast seqno window was reset
* @batman_seqno_reset: time when the batman seqno window was reset
......@@ -59,9 +58,13 @@ struct batman_if {
* @last_real_seqno: last and best known squence number
* @last_ttl: ttl of last received packet
* @last_bcast_seqno: last broadcast sequence number received by this host
*
* @candidates: how many candidates are available
* @selected: next bonding candidate
*/
struct orig_node {
uint8_t orig[ETH_ALEN];
uint8_t primary_addr[ETH_ALEN];
struct neigh_node *router;
TYPE_OF_WORD *bcast_own;
uint8_t *bcast_own_sum;
......@@ -72,12 +75,16 @@ struct orig_node {
unsigned long batman_seqno_reset;
uint8_t flags;
unsigned char *hna_buff;
int16_t hna_buff_len;
uint16_t last_real_seqno;
int16_t hna_buff_len;
uint32_t last_real_seqno;
uint8_t last_ttl;
TYPE_OF_WORD bcast_bits[NUM_WORDS];
uint16_t last_bcast_seqno;
uint32_t last_bcast_seqno;
struct list_head neigh_list;
struct {
uint8_t candidates;
struct neigh_node *selected;
} bond;
};
/**
......@@ -92,6 +99,7 @@ struct neigh_node {
uint8_t tq_index;
uint8_t tq_avg;
uint8_t last_ttl;
struct neigh_node *next_bond_candidate;
unsigned long last_valid;
TYPE_OF_WORD real_bits[NUM_WORDS];
struct orig_node *orig_node;
......@@ -101,14 +109,18 @@ struct neigh_node {
struct bat_priv {
struct net_device_stats stats;
atomic_t aggregation_enabled;
atomic_t bonding_enabled;
atomic_t vis_mode;
atomic_t orig_interval;
atomic_t log_level;
char num_ifaces;
struct debug_log *debug_log;
struct batman_if *primary_if;
struct kobject *mesh_obj;
struct dentry *debug_dir;
};
struct device_client {
struct socket_client {
struct list_head queue_list;
unsigned int queue_len;
unsigned char index;
......@@ -116,9 +128,10 @@ struct device_client {
wait_queue_head_t queue_wait;
};
struct device_packet {
struct socket_packet {
struct list_head list;
struct icmp_packet icmp_packet;
size_t icmp_len;
struct icmp_packet_rr icmp_packet;
};
struct hna_local_entry {
......@@ -159,4 +172,12 @@ struct if_list_entry {
struct hlist_node list;
};
#endif
struct debug_log {
char log_buff[LOG_BUF_LEN];
unsigned long log_start;
unsigned long log_end;
spinlock_t lock;
wait_queue_head_t queue_wait;
};
#endif /* _NET_BATMAN_ADV_TYPES_H_ */
......@@ -43,8 +43,8 @@
_dummy > smallest_signed_int(_dummy); })
#define seq_after(x, y) seq_before(y, x)
struct hashtable_t *vis_hash;
DEFINE_SPINLOCK(vis_hash_lock);
static struct hashtable_t *vis_hash;
static DEFINE_SPINLOCK(vis_hash_lock);
static DEFINE_SPINLOCK(recv_list_lock);
static struct vis_info *my_vis_info;
static struct list_head send_list; /* always locked with vis_hash_lock */
......@@ -115,7 +115,7 @@ static void vis_data_insert_interface(const uint8_t *interface,
}
/* its a new address, add it to the list */
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (!entry)
return;
memcpy(entry->addr, interface, ETH_ALEN);
......@@ -142,12 +142,29 @@ static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list)
return len;
}
static size_t vis_data_count_prim_sec(struct hlist_head *if_list)
{
struct if_list_entry *entry;
struct hlist_node *pos;
size_t count = 0;
hlist_for_each_entry(entry, pos, if_list, list) {
if (entry->primary)
count += 9;
else
count += 23;
}
return count;
}
/* read an entry */
static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
uint8_t *src, bool primary)
{
char to[40];
char to[18];
/* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
addr_to_string(to, entry->dest);
if (primary && entry->quality == 0)
return sprintf(buff, "HNA %s, ", to);
......@@ -157,38 +174,74 @@ static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry,
return 0;
}
ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
size_t count, loff_t off)
int vis_seq_print_text(struct seq_file *seq, void *offset)
{
HASHIT(hashit);
HASHIT(hashit_count);
struct vis_info *info;
struct vis_info_entry *entries;
struct net_device *net_dev = (struct net_device *)seq->private;
struct bat_priv *bat_priv = netdev_priv(net_dev);
HLIST_HEAD(vis_if_list);
struct if_list_entry *entry;
struct hlist_node *pos, *n;
size_t hdr_len, tmp_len;
int i, bytes_written = 0;
int i;
char tmp_addr_str[ETH_STR_LEN];
unsigned long flags;
int vis_server = atomic_read(&bat_priv->vis_mode);
size_t buff_pos, buf_size;
char *buff;
if ((!bat_priv->primary_if) ||
(vis_server == VIS_TYPE_CLIENT_UPDATE))
return 0;
hdr_len = 0;
buf_size = 1;
/* Estimate length */
spin_lock_irqsave(&vis_hash_lock, flags);
while (hash_iterate(vis_hash, &hashit_count)) {
info = hashit_count.bucket->data;
entries = (struct vis_info_entry *)
((char *)info + sizeof(struct vis_info));
for (i = 0; i < info->packet.entries; i++) {
if (entries[i].quality == 0)
continue;
vis_data_insert_interface(entries[i].src, &vis_if_list,
compare_orig(entries[i].src,
info->packet.vis_orig));
}
hlist_for_each_entry(entry, pos, &vis_if_list, list) {
buf_size += 18 + 26 * info->packet.entries;
/* add primary/secondary records */
if (compare_orig(entry->addr, info->packet.vis_orig))
buf_size +=
vis_data_count_prim_sec(&vis_if_list);
buf_size += 1;
}
hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
hlist_del(&entry->list);
kfree(entry);
}
}
buff = kmalloc(buf_size, GFP_ATOMIC);
if (!buff) {
spin_unlock_irqrestore(&vis_hash_lock, flags);
return -ENOMEM;
}
buff[0] = '\0';
buff_pos = 0;
while (hash_iterate(vis_hash, &hashit)) {
info = hashit.bucket->data;
entries = (struct vis_info_entry *)
((char *)info + sizeof(struct vis_info));
/* estimated line length */
if (count < bytes_written + 200)
break;
for (i = 0; i < info->packet.entries; i++) {
if (entries[i].quality == 0)
continue;
......@@ -199,30 +252,22 @@ ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
hlist_for_each_entry(entry, pos, &vis_if_list, list) {
addr_to_string(tmp_addr_str, entry->addr);
tmp_len = sprintf(buff + bytes_written,
"%s,", tmp_addr_str);
buff_pos += sprintf(buff + buff_pos, "%s,",
tmp_addr_str);
for (i = 0; i < info->packet.entries; i++)
tmp_len += vis_data_read_entry(
buff + bytes_written + tmp_len,
&entries[i], entry->addr,
entry->primary);
buff_pos += vis_data_read_entry(buff + buff_pos,
&entries[i],
entry->addr,
entry->primary);
/* add primary/secondary records */
if (compare_orig(entry->addr, info->packet.vis_orig))
tmp_len += vis_data_read_prim_sec(
buff + bytes_written + tmp_len,
&vis_if_list);
tmp_len += sprintf(buff + bytes_written + tmp_len,
"\n");
hdr_len += tmp_len;
buff_pos +=
vis_data_read_prim_sec(buff + buff_pos,
&vis_if_list);
if (off >= hdr_len)
continue;
bytes_written += tmp_len;
buff_pos += sprintf(buff + buff_pos, "\n");
}
hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) {
......@@ -230,9 +275,13 @@ ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
kfree(entry);
}
}
spin_unlock_irqrestore(&vis_hash_lock, flags);
return bytes_written;
seq_printf(seq, "%s", buff);
kfree(buff);
return 0;
}
/* add the info packet to the send list, if it was not
......@@ -308,7 +357,8 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
old_info = hash_find(vis_hash, &search_elem);
if (old_info != NULL) {
if (!seq_after(vis_packet->seqno, old_info->packet.seqno)) {
if (!seq_after(ntohl(vis_packet->seqno),
ntohl(old_info->packet.seqno))) {
if (old_info->packet.seqno == vis_packet->seqno) {
recv_list_add(&old_info->recv_list,
vis_packet->sender_orig);
......@@ -340,7 +390,7 @@ static struct vis_info *add_packet(struct vis_packet *vis_packet,
/* Make it a broadcast packet, if required */
if (make_broadcast)
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
/* repair if entries is longer than packet. */
if (info->packet.entries * sizeof(struct vis_info_entry) > vis_info_len)
......@@ -474,9 +524,9 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
info->packet.vis_type = atomic_read(&bat_priv->vis_mode);
spin_lock_irqsave(&orig_hash_lock, flags);
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
info->packet.ttl = TTL;
info->packet.seqno++;
info->packet.seqno = htonl(ntohl(info->packet.seqno) + 1);
info->packet.entries = 0;
if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) {
......@@ -547,7 +597,7 @@ static void purge_vis_packets(void)
if (info == my_vis_info) /* never purge own data. */
continue;
if (time_after(jiffies,
info->first_seen + (VIS_TIMEOUT*HZ)/1000)) {
info->first_seen + VIS_TIMEOUT * HZ)) {
hash_remove_bucket(vis_hash, &hashit);
send_list_del(info);
kref_put(&info->refcount, free_info);
......@@ -591,7 +641,7 @@ static void broadcast_vis_packet(struct vis_info *info, int packet_length)
}
spin_unlock_irqrestore(&orig_hash_lock, flags);
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
memcpy(info->packet.target_orig, broadcast_addr, ETH_ALEN);
}
static void unicast_vis_packet(struct vis_info *info, int packet_length)
......@@ -628,11 +678,11 @@ static void send_vis_packet(struct vis_info *info)
int packet_length;
if (info->packet.ttl < 2) {
printk(KERN_WARNING "batman-adv: Error - can't send vis packet: ttl exceeded\n");
pr_warning("Error - can't send vis packet: ttl exceeded\n");
return;
}
memcpy(info->packet.sender_orig, mainIfAddr, ETH_ALEN);
memcpy(info->packet.sender_orig, main_if_addr, ETH_ALEN);
info->packet.ttl--;
packet_length = sizeof(struct vis_packet) +
......@@ -690,18 +740,18 @@ int vis_init(void)
vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
if (!vis_hash) {
printk(KERN_ERR "batman-adv:Can't initialize vis_hash\n");
pr_err("Can't initialize vis_hash\n");
goto err;
}
my_vis_info = kmalloc(1000, GFP_ATOMIC);
if (!my_vis_info) {
printk(KERN_ERR "batman-adv:Can't initialize vis packet\n");
pr_err("Can't initialize vis packet\n");
goto err;
}
/* prefill the vis info */
my_vis_info->first_seen = jiffies - atomic_read(&vis_interval);
my_vis_info->first_seen = jiffies - msecs_to_jiffies(VIS_INTERVAL);
INIT_LIST_HEAD(&my_vis_info->recv_list);
INIT_LIST_HEAD(&my_vis_info->send_list);
kref_init(&my_vis_info->refcount);
......@@ -713,12 +763,11 @@ int vis_init(void)
INIT_LIST_HEAD(&send_list);
memcpy(my_vis_info->packet.vis_orig, mainIfAddr, ETH_ALEN);
memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);
memcpy(my_vis_info->packet.vis_orig, main_if_addr, ETH_ALEN);
memcpy(my_vis_info->packet.sender_orig, main_if_addr, ETH_ALEN);
if (hash_add(vis_hash, my_vis_info) < 0) {
printk(KERN_ERR
"batman-adv:Can't add own vis packet into hash\n");
pr_err("Can't add own vis packet into hash\n");
/* not in hash, need to remove it manually. */
kref_put(&my_vis_info->refcount, free_info);
goto err;
......@@ -764,5 +813,5 @@ void vis_quit(void)
static void start_vis_timer(void)
{
queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
(atomic_read(&vis_interval) * HZ) / 1000);
(VIS_INTERVAL * HZ) / 1000);
}
......@@ -19,7 +19,10 @@
*
*/
#define VIS_TIMEOUT 200000
#ifndef _NET_BATMAN_ADV_VIS_H_
#define _NET_BATMAN_ADV_VIS_H_
#define VIS_TIMEOUT 200 /* timeout of vis packets in seconds */
struct vis_info {
unsigned long first_seen;
......@@ -44,11 +47,7 @@ struct recvlist_node {
uint8_t mac[ETH_ALEN];
};
extern struct hashtable_t *vis_hash;
extern spinlock_t vis_hash_lock;
ssize_t vis_fill_buffer_text(struct net_device *net_dev, char *buff,
size_t count, loff_t off);
int vis_seq_print_text(struct seq_file *seq, void *offset);
void receive_server_sync_packet(struct bat_priv *bat_priv,
struct vis_packet *vis_packet,
int vis_info_len);
......@@ -57,3 +56,5 @@ void receive_client_update_packet(struct bat_priv *bat_priv,
int vis_info_len);
int vis_init(void);
void vis_quit(void);
#endif /* _NET_BATMAN_ADV_VIS_H_ */
......@@ -2,7 +2,6 @@ TODO:
- checkpatch.pl cleanups
- Lindent
- remove all wrappers
- remove typedefs
- audit userspace interface
- reserve major number
- cleanup the individual comedi drivers as well
......
......@@ -1845,8 +1845,15 @@ static int comedi_open(struct inode *inode, struct file *file)
}
}
if (dev->attached && dev->use_count == 0 && dev->open)
dev->open(dev);
if (dev->attached && dev->use_count == 0 && dev->open) {
int rc = dev->open(dev);
if (rc < 0) {
module_put(dev->driver->module);
module_put(THIS_MODULE);
mutex_unlock(&dev->mutex);
return rc;
}
}
dev->use_count++;
......
......@@ -53,62 +53,6 @@
COMEDI_MINORVERSION, COMEDI_MICROVERSION)
#define COMEDI_RELEASE VERSION
#define COMEDI_INITCLEANUP_NOMODULE(x) \
static int __init x ## _init_module(void) \
{return comedi_driver_register(&(x)); } \
static void __exit x ## _cleanup_module(void) \
{comedi_driver_unregister(&(x)); } \
module_init(x ## _init_module); \
module_exit(x ## _cleanup_module);
#define COMEDI_MODULE_MACROS \
MODULE_AUTHOR("Comedi http://www.comedi.org"); \
MODULE_DESCRIPTION("Comedi low-level driver"); \
MODULE_LICENSE("GPL");
#define COMEDI_INITCLEANUP(x) \
COMEDI_MODULE_MACROS \
COMEDI_INITCLEANUP_NOMODULE(x)
#define COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table) \
static int __devinit comedi_driver ## _pci_probe(struct pci_dev *dev, \
const struct pci_device_id *ent) \
{ \
return comedi_pci_auto_config(dev, comedi_driver.driver_name); \
} \
static void __devexit comedi_driver ## _pci_remove(\
struct pci_dev *dev) \
{ \
comedi_pci_auto_unconfig(dev); \
} \
static struct pci_driver comedi_driver ## _pci_driver = \
{ \
.id_table = pci_id_table, \
.probe = &comedi_driver ## _pci_probe, \
.remove = __devexit_p(&comedi_driver ## _pci_remove) \
}; \
static int __init comedi_driver ## _init_module(void) \
{ \
int retval; \
retval = comedi_driver_register(&comedi_driver); \
if (retval < 0) \
return retval; \
comedi_driver ## _pci_driver.name = \
(char *)comedi_driver.driver_name; \
return pci_register_driver(&comedi_driver ## _pci_driver); \
} \
static void __exit comedi_driver ## _cleanup_module(void) \
{ \
pci_unregister_driver(&comedi_driver ## _pci_driver); \
comedi_driver_unregister(&comedi_driver); \
} \
module_init(comedi_driver ## _init_module); \
module_exit(comedi_driver ## _cleanup_module);
#define COMEDI_PCI_INITCLEANUP(comedi_driver, pci_id_table) \
COMEDI_MODULE_MACROS \
COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table)
#define PCI_VENDOR_ID_ADLINK 0x144a
#define PCI_VENDOR_ID_ICP 0x104c
#define PCI_VENDOR_ID_CONTEC 0x1221
......@@ -285,7 +229,7 @@ struct comedi_device {
struct fasync_struct *async_queue;
void (*open) (struct comedi_device *dev);
int (*open) (struct comedi_device *dev);
void (*close) (struct comedi_device *dev);
};
......
......@@ -117,7 +117,18 @@ static struct comedi_driver driver_8255 = {
.detach = dev_8255_detach,
};
COMEDI_INITCLEANUP(driver_8255);
static int __init driver_8255_init_module(void)
{
return comedi_driver_register(&driver_8255);
}
static void __exit driver_8255_cleanup_module(void)
{
comedi_driver_unregister(&driver_8255);
}
module_init(driver_8255_init_module);
module_exit(driver_8255_cleanup_module);
static void do_config(struct comedi_device *dev, struct comedi_subdevice *s);
......@@ -457,3 +468,7 @@ static int dev_8255_detach(struct comedi_device *dev)
return 0;
}
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
......@@ -49,7 +49,18 @@ static struct comedi_driver driver_acl7225b = {
.offset = sizeof(struct boardtype),
};
COMEDI_INITCLEANUP(driver_acl7225b);
static int __init driver_acl7225b_init_module(void)
{
return comedi_driver_register(&driver_acl7225b);
}
static void __exit driver_acl7225b_cleanup_module(void)
{
comedi_driver_unregister(&driver_acl7225b);
}
module_init(driver_acl7225b_init_module);
module_exit(driver_acl7225b_cleanup_module);
static int acl7225b_do_insn(struct comedi_device *dev,
struct comedi_subdevice *s,
......@@ -150,3 +161,7 @@ static int acl7225b_detach(struct comedi_device *dev)
return 0;
}
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
......@@ -247,16 +247,14 @@ int i_pci_card_data(struct pcilst_struct *amcc,
/* build list of amcc cards in this system */
void v_pci_card_list_init(unsigned short pci_vendor, char display)
{
struct pci_dev *pcidev;
struct pci_dev *pcidev = NULL;
struct pcilst_struct *amcc, *last;
int i;
int i_Count = 0;
amcc_devices = NULL;
last = NULL;
for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
pcidev != NULL;
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
for_each_pci_dev(pcidev) {
for (i_Count = 0; i_Count < 2; i_Count++) {
pci_vendor = i_ADDIDATADeviceID[i_Count];
if (pcidev->vendor == pci_vendor) {
......
......@@ -2541,7 +2541,43 @@ static struct comedi_driver driver_addi = {
.offset = sizeof(struct addi_board),
};
COMEDI_PCI_INITCLEANUP(driver_addi, addi_apci_tbl);
static int __devinit driver_addi_pci_probe(struct pci_dev *dev,
const struct pci_device_id *ent)
{
return comedi_pci_auto_config(dev, driver_addi.driver_name);
}
static void __devexit driver_addi_pci_remove(struct pci_dev *dev)
{
comedi_pci_auto_unconfig(dev);
}
static struct pci_driver driver_addi_pci_driver = {
.id_table = addi_apci_tbl,
.probe = &driver_addi_pci_probe,
.remove = __devexit_p(&driver_addi_pci_remove)
};
static int __init driver_addi_init_module(void)
{
int retval;
retval = comedi_driver_register(&driver_addi);
if (retval < 0)
return retval;
driver_addi_pci_driver.name = (char *)driver_addi.driver_name;
return pci_register_driver(&driver_addi_pci_driver);
}
static void __exit driver_addi_cleanup_module(void)
{
pci_unregister_driver(&driver_addi_pci_driver);
comedi_driver_unregister(&driver_addi);
}
module_init(driver_addi_init_module);
module_exit(driver_addi_cleanup_module);
/*
+----------------------------------------------------------------------------+
......
......@@ -101,10 +101,10 @@ struct str_TimerMainHeader {
};
typedef struct {
struct str_AnalogOutputHeader {
unsigned short w_Nchannel;
unsigned char b_Resolution;
} str_AnalogOutputHeader;
};
struct str_AnalogInputHeader {
unsigned short w_Nchannel;
......@@ -136,7 +136,7 @@ int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
char *pc_PCIChipInformation, unsigned short w_Address,
str_AnalogOutputHeader *s_Header);
struct str_AnalogOutputHeader *s_Header);
int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress,
char *pc_PCIChipInformation, unsigned short w_Address,
......@@ -635,7 +635,7 @@ void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromComman
| Input Parameters : unsigned int dw_Address : PCI eeprom base address |
| unsigned short w_offset : Offset of the adress to read |
| unsigned short w_offset : Offset of the address to read |
| unsigned short * pw_Value : PCI eeprom 16 bit read value. |
......@@ -811,7 +811,7 @@ int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress,
struct str_DigitalInputHeader s_DigitalInputHeader;
struct str_DigitalOutputHeader s_DigitalOutputHeader;
/* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */
str_AnalogOutputHeader s_AnalogOutputHeader;
struct str_AnalogOutputHeader s_AnalogOutputHeader;
struct str_AnalogInputHeader s_AnalogInputHeader;
/* Read size */
......@@ -1081,7 +1081,7 @@ int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress,
int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress,
char *pc_PCIChipInformation, unsigned short w_Address,
str_AnalogOutputHeader *s_Header)
struct str_AnalogOutputHeader *s_Header)
{
unsigned short w_Temp;
/* No of channels for 1st hard component */
......
......@@ -1090,13 +1090,13 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
* and put into into an array array used may be for differnet pages
*/
/* DMA Start Adress Low */
/* DMA Start Address Low */
outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
outw((devpriv->ul_DmaBufferHw[0] & 0xFFFF),
devpriv->i_IobaseAddon + 2);
/*************************/
/* DMA Start Adress High */
/* DMA Start Address High */
/*************************/
outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
outw((devpriv->ul_DmaBufferHw[0] / 65536),
......@@ -1733,11 +1733,11 @@ void v_APCI3120_InterruptDma(int irq, void *d)
var = devpriv->ul_DmaBufferHw[next_dma_buf];
high_word = var / 65536;
/* DMA Start Adress Low */
/* DMA Start Address Low */
outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
outw(low_word, devpriv->i_IobaseAddon + 2);
/* DMA Start Adress High */
/* DMA Start Address High */
outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
outw(high_word, devpriv->i_IobaseAddon + 2);
......
......@@ -5,3 +5,7 @@
#define ADDIDATA_DRIVER_NAME "addi_apci_035"
#include "addi-data/addi_common.c"
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
......@@ -3,3 +3,7 @@
#define ADDIDATA_DRIVER_NAME "addi_apci_1032"
#include "addi-data/addi_common.c"
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
......@@ -3,3 +3,7 @@
#define ADDIDATA_DRIVER_NAME "addi_apci_1500"
#include "addi-data/addi_common.c"
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
......@@ -3,3 +3,7 @@
#define ADDIDATA_DRIVER_NAME "addi_apci_1516"
#include "addi-data/addi_common.c"
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
......@@ -3,3 +3,7 @@
#define ADDIDATA_DRIVER_NAME "addi_apci_1564"
#include "addi-data/addi_common.c"
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
......@@ -3,3 +3,7 @@
#define ADDIDATA_DRIVER_NAME "addi_apci_16xx"
#include "addi-data/addi_common.c"
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
......@@ -3,3 +3,7 @@
#define ADDIDATA_DRIVER_NAME "addi_apci_2016"
#include "addi-data/addi_common.c"
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment